11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds BlueZ - Bluetooth protocol stack for Linux 32d0a0346SRon Shaffer Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved. 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 61da177e4SLinus Torvalds 71da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 81da177e4SLinus Torvalds it under the terms of the GNU General Public License version 2 as 91da177e4SLinus Torvalds published by the Free Software Foundation; 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 121da177e4SLinus Torvalds OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 131da177e4SLinus Torvalds FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 141da177e4SLinus Torvalds IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 151da177e4SLinus Torvalds CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 161da177e4SLinus Torvalds WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 171da177e4SLinus Torvalds ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 181da177e4SLinus Torvalds OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 211da177e4SLinus Torvalds COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 221da177e4SLinus Torvalds SOFTWARE IS DISCLAIMED. 231da177e4SLinus Torvalds */ 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds #ifndef __HCI_CORE_H 261da177e4SLinus Torvalds #define __HCI_CORE_H 271da177e4SLinus Torvalds 286d5d2ee6SHeiner Kallweit #include <linux/leds.h> 29b2d09103SIngo Molnar #include <linux/rculist.h> 30b2d09103SIngo Molnar 311da177e4SLinus Torvalds #include <net/bluetooth/hci.h> 32f49daa81SMarcel Holtmann #include <net/bluetooth/hci_sock.h> 331da177e4SLinus Torvalds 345e59b791SLuiz Augusto von Dentz /* HCI priority */ 355e59b791SLuiz Augusto von Dentz #define HCI_PRIO_MAX 7 365e59b791SLuiz Augusto von Dentz 371da177e4SLinus Torvalds /* HCI Core structures */ 381da177e4SLinus Torvalds struct inquiry_data { 391da177e4SLinus Torvalds bdaddr_t bdaddr; 401da177e4SLinus Torvalds __u8 pscan_rep_mode; 411da177e4SLinus Torvalds __u8 pscan_period_mode; 421da177e4SLinus Torvalds __u8 pscan_mode; 431da177e4SLinus Torvalds __u8 dev_class[3]; 441ebb9252SMarcel Holtmann __le16 clock_offset; 451da177e4SLinus Torvalds __s8 rssi; 4641a96212SMarcel Holtmann __u8 ssp_mode; 471da177e4SLinus Torvalds }; 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds struct inquiry_entry { 50561aafbcSJohan Hedberg struct list_head all; /* inq_cache.all */ 51561aafbcSJohan Hedberg struct list_head list; /* unknown or resolve */ 52561aafbcSJohan Hedberg enum { 53561aafbcSJohan Hedberg NAME_NOT_KNOWN, 54561aafbcSJohan Hedberg NAME_NEEDED, 55561aafbcSJohan Hedberg NAME_PENDING, 56561aafbcSJohan Hedberg NAME_KNOWN, 57561aafbcSJohan Hedberg } name_state; 581da177e4SLinus Torvalds __u32 timestamp; 591da177e4SLinus Torvalds struct inquiry_data data; 601da177e4SLinus Torvalds }; 611da177e4SLinus Torvalds 6230883512SJohan Hedberg struct discovery_state { 634aab14e5SAndre Guedes int type; 64ff9ef578SJohan Hedberg enum { 65ff9ef578SJohan Hedberg DISCOVERY_STOPPED, 66ff9ef578SJohan Hedberg DISCOVERY_STARTING, 67343f935bSAndre Guedes DISCOVERY_FINDING, 6830dc78e1SJohan Hedberg DISCOVERY_RESOLVING, 69ff9ef578SJohan Hedberg DISCOVERY_STOPPING, 70ff9ef578SJohan Hedberg } state; 71561aafbcSJohan Hedberg struct list_head all; /* All devices found during inquiry */ 72561aafbcSJohan Hedberg struct list_head unknown; /* Name state not known */ 73561aafbcSJohan Hedberg struct list_head resolve; /* Name needs to be resolved */ 741da177e4SLinus Torvalds __u32 timestamp; 75b9a6328fSJohan Hedberg bdaddr_t last_adv_addr; 76b9a6328fSJohan Hedberg u8 last_adv_addr_type; 77ff5cd29fSJohan Hedberg s8 last_adv_rssi; 78c70a7e4cSMarcel Holtmann u32 last_adv_flags; 79b9a6328fSJohan Hedberg u8 last_adv_data[HCI_MAX_AD_LENGTH]; 80b9a6328fSJohan Hedberg u8 last_adv_data_len; 81da25cf6aSMarcel Holtmann bool report_invalid_rssi; 8282f8b651SJakub Pawlowski bool result_filtering; 8378b781caSJohan Hedberg bool limited; 8437eab042SJakub Pawlowski s8 rssi; 8537eab042SJakub Pawlowski u16 uuid_count; 8637eab042SJakub Pawlowski u8 (*uuids)[16]; 872d28cfe7SJakub Pawlowski unsigned long scan_start; 882d28cfe7SJakub Pawlowski unsigned long scan_duration; 891da177e4SLinus Torvalds }; 901da177e4SLinus Torvalds 911da177e4SLinus Torvalds struct hci_conn_hash { 921da177e4SLinus Torvalds struct list_head list; 931da177e4SLinus Torvalds unsigned int acl_num; 94bd1eb66bSAndrei Emeltchenko unsigned int amp_num; 951da177e4SLinus Torvalds unsigned int sco_num; 96fcd89c09SVille Tervo unsigned int le_num; 97f8218dc6SJohan Hedberg unsigned int le_num_slave; 981da177e4SLinus Torvalds }; 991da177e4SLinus Torvalds 100f0358568SJohan Hedberg struct bdaddr_list { 101f0358568SJohan Hedberg struct list_head list; 102f0358568SJohan Hedberg bdaddr_t bdaddr; 103b9ee0a78SMarcel Holtmann u8 bdaddr_type; 104f0358568SJohan Hedberg }; 1052aeb9a1aSJohan Hedberg 106b950aa88SAnkit Navik struct bdaddr_list_with_irk { 107b950aa88SAnkit Navik struct list_head list; 108b950aa88SAnkit Navik bdaddr_t bdaddr; 109b950aa88SAnkit Navik u8 bdaddr_type; 110b950aa88SAnkit Navik u8 peer_irk[16]; 111b950aa88SAnkit Navik u8 local_irk[16]; 112b950aa88SAnkit Navik }; 113b950aa88SAnkit Navik 1142aeb9a1aSJohan Hedberg struct bt_uuid { 1152aeb9a1aSJohan Hedberg struct list_head list; 1162aeb9a1aSJohan Hedberg u8 uuid[16]; 11783be8ecaSJohan Hedberg u8 size; 1181aff6f09SJohan Hedberg u8 svc_hint; 1192aeb9a1aSJohan Hedberg }; 1202aeb9a1aSJohan Hedberg 1217ee4ea36SMarcel Holtmann struct smp_csrk { 1227ee4ea36SMarcel Holtmann bdaddr_t bdaddr; 1237ee4ea36SMarcel Holtmann u8 bdaddr_type; 1244cd3928aSJohan Hedberg u8 type; 1257ee4ea36SMarcel Holtmann u8 val[16]; 1267ee4ea36SMarcel Holtmann }; 1277ee4ea36SMarcel Holtmann 128b899efafSVinicius Costa Gomes struct smp_ltk { 129b899efafSVinicius Costa Gomes struct list_head list; 130970d0f1bSJohan Hedberg struct rcu_head rcu; 131b899efafSVinicius Costa Gomes bdaddr_t bdaddr; 132b899efafSVinicius Costa Gomes u8 bdaddr_type; 133b899efafSVinicius Costa Gomes u8 authenticated; 134b899efafSVinicius Costa Gomes u8 type; 135b899efafSVinicius Costa Gomes u8 enc_size; 136b899efafSVinicius Costa Gomes __le16 ediv; 137fe39c7b2SMarcel Holtmann __le64 rand; 138b899efafSVinicius Costa Gomes u8 val[16]; 13903c515d7SMarcel Holtmann }; 140b899efafSVinicius Costa Gomes 141970c4e46SJohan Hedberg struct smp_irk { 142970c4e46SJohan Hedberg struct list_head list; 143adae20cbSJohan Hedberg struct rcu_head rcu; 144970c4e46SJohan Hedberg bdaddr_t rpa; 145970c4e46SJohan Hedberg bdaddr_t bdaddr; 146970c4e46SJohan Hedberg u8 addr_type; 147970c4e46SJohan Hedberg u8 val[16]; 148970c4e46SJohan Hedberg }; 149970c4e46SJohan Hedberg 15055ed8ca1SJohan Hedberg struct link_key { 15155ed8ca1SJohan Hedberg struct list_head list; 1520378b597SJohan Hedberg struct rcu_head rcu; 15355ed8ca1SJohan Hedberg bdaddr_t bdaddr; 15455ed8ca1SJohan Hedberg u8 type; 1559b3b4460SAndrei Emeltchenko u8 val[HCI_LINK_KEY_SIZE]; 15655ed8ca1SJohan Hedberg u8 pin_len; 15755ed8ca1SJohan Hedberg }; 15855ed8ca1SJohan Hedberg 1592763eda6SSzymon Janc struct oob_data { 1602763eda6SSzymon Janc struct list_head list; 1612763eda6SSzymon Janc bdaddr_t bdaddr; 1626928a924SJohan Hedberg u8 bdaddr_type; 163f7697b16SMarcel Holtmann u8 present; 164519ca9d0SMarcel Holtmann u8 hash192[16]; 16538da1703SJohan Hedberg u8 rand192[16]; 166519ca9d0SMarcel Holtmann u8 hash256[16]; 16738da1703SJohan Hedberg u8 rand256[16]; 1682763eda6SSzymon Janc }; 1692763eda6SSzymon Janc 170203fea01SArman Uguray struct adv_info { 171d2609b34SFlorian Grandel struct list_head list; 172fffd38bcSFlorian Grandel bool pending; 173203fea01SArman Uguray __u8 instance; 174203fea01SArman Uguray __u32 flags; 175912098a6SArman Uguray __u16 timeout; 1765d900e46SFlorian Grandel __u16 remaining_time; 177d2609b34SFlorian Grandel __u16 duration; 178203fea01SArman Uguray __u16 adv_data_len; 179203fea01SArman Uguray __u8 adv_data[HCI_MAX_AD_LENGTH]; 180203fea01SArman Uguray __u16 scan_rsp_len; 181203fea01SArman Uguray __u8 scan_rsp_data[HCI_MAX_AD_LENGTH]; 182de181e88SJaganath Kanakkassery __s8 tx_power; 183a73c046aSJaganath Kanakkassery bdaddr_t random_addr; 184a73c046aSJaganath Kanakkassery bool rpa_expired; 185a73c046aSJaganath Kanakkassery struct delayed_work rpa_expired_cb; 186203fea01SArman Uguray }; 187203fea01SArman Uguray 188db25be66SFlorian Grandel #define HCI_MAX_ADV_INSTANCES 5 189d2609b34SFlorian Grandel #define HCI_DEFAULT_ADV_DURATION 2 190d2609b34SFlorian Grandel 191490c5babSJohan Hedberg #define HCI_MAX_SHORT_NAME_LENGTH 10 192490c5babSJohan Hedberg 193d6bfd59cSJohan Hedberg /* Default LE RPA expiry time, 15 minutes */ 194d6bfd59cSJohan Hedberg #define HCI_DEFAULT_RPA_TIMEOUT (15 * 60) 195d6bfd59cSJohan Hedberg 19631ad1691SAndrzej Kaczmarek /* Default min/max age of connection information (1s/3s) */ 19731ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MIN_AGE 1000 19831ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MAX_AGE 3000 19931ad1691SAndrzej Kaczmarek 200903e4541SAndrei Emeltchenko struct amp_assoc { 201903e4541SAndrei Emeltchenko __u16 len; 202903e4541SAndrei Emeltchenko __u16 offset; 20393c284eeSAndrei Emeltchenko __u16 rem_len; 20493c284eeSAndrei Emeltchenko __u16 len_so_far; 205903e4541SAndrei Emeltchenko __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; 206903e4541SAndrei Emeltchenko }; 207903e4541SAndrei Emeltchenko 208d2c5d77fSJohan Hedberg #define HCI_MAX_PAGES 3 209cad718edSJohan Hedberg 2101da177e4SLinus Torvalds struct hci_dev { 2111da177e4SLinus Torvalds struct list_head list; 21209fd0de5SGustavo F. Padovan struct mutex lock; 2131da177e4SLinus Torvalds 2141da177e4SLinus Torvalds char name[8]; 2151da177e4SLinus Torvalds unsigned long flags; 2161da177e4SLinus Torvalds __u16 id; 217c13854ceSMarcel Holtmann __u8 bus; 218943da25dSMarcel Holtmann __u8 dev_type; 2191da177e4SLinus Torvalds bdaddr_t bdaddr; 220e30d3f5fSMarcel Holtmann bdaddr_t setup_addr; 22124c457e2SMarcel Holtmann bdaddr_t public_addr; 2227a4cd51dSMarcel Holtmann bdaddr_t random_addr; 223d13eafceSMarcel Holtmann bdaddr_t static_addr; 22456ed2cb8SJohan Hedberg __u8 adv_addr_type; 2251f6c6378SJohan Hedberg __u8 dev_name[HCI_MAX_NAME_LENGTH]; 226490c5babSJohan Hedberg __u8 short_name[HCI_MAX_SHORT_NAME_LENGTH]; 22780a1e1dbSJohan Hedberg __u8 eir[HCI_MAX_EIR_LENGTH]; 228c4960ecfSMichał Narajowski __u16 appearance; 229a9de9248SMarcel Holtmann __u8 dev_class[3]; 2301aff6f09SJohan Hedberg __u8 major_class; 2311aff6f09SJohan Hedberg __u8 minor_class; 232d2c5d77fSJohan Hedberg __u8 max_page; 233cad718edSJohan Hedberg __u8 features[HCI_MAX_PAGES][8]; 23460e77321SJohan Hedberg __u8 le_features[8]; 235cf1d081fSJohan Hedberg __u8 le_white_list_size; 236cfdb0c2dSAnkit Navik __u8 le_resolv_list_size; 2376b49bcb4SJaganath Kanakkassery __u8 le_num_of_adv_sets; 2389b008c04SJohan Hedberg __u8 le_states[8]; 239a9de9248SMarcel Holtmann __u8 commands[64]; 2401143e5a6SMarcel Holtmann __u8 hci_ver; 2411143e5a6SMarcel Holtmann __u16 hci_rev; 242d5859e22SJohan Hedberg __u8 lmp_ver; 2431143e5a6SMarcel Holtmann __u16 manufacturer; 2447d69230cSAndrei Emeltchenko __u16 lmp_subver; 2451da177e4SLinus Torvalds __u16 voice_setting; 246b4cb9fb2SMarcel Holtmann __u8 num_iac; 247c2f0f979SMarcel Holtmann __u8 stored_max_keys; 248c2f0f979SMarcel Holtmann __u8 stored_num_keys; 24917fa4b9dSJohan Hedberg __u8 io_capability; 25091c4e9b1SMarcel Holtmann __s8 inq_tx_power; 251f332ec66SJohan Hedberg __u16 page_scan_interval; 252f332ec66SJohan Hedberg __u16 page_scan_window; 253f332ec66SJohan Hedberg __u8 page_scan_type; 2543f959d46SMarcel Holtmann __u8 le_adv_channel_map; 255628531c9SGeorg Lukas __u16 le_adv_min_interval; 256628531c9SGeorg Lukas __u16 le_adv_max_interval; 257533553f8SMarcel Holtmann __u8 le_scan_type; 258bef64738SMarcel Holtmann __u16 le_scan_interval; 259bef64738SMarcel Holtmann __u16 le_scan_window; 2604e70c7e7SMarcel Holtmann __u16 le_conn_min_interval; 2614e70c7e7SMarcel Holtmann __u16 le_conn_max_interval; 26204fb7d90SMarcel Holtmann __u16 le_conn_latency; 26304fb7d90SMarcel Holtmann __u16 le_supv_timeout; 264a8e1bfaaSMarcel Holtmann __u16 le_def_tx_len; 265a8e1bfaaSMarcel Holtmann __u16 le_def_tx_time; 266a8e1bfaaSMarcel Holtmann __u16 le_max_tx_len; 267a8e1bfaaSMarcel Holtmann __u16 le_max_tx_time; 268a8e1bfaaSMarcel Holtmann __u16 le_max_rx_len; 269a8e1bfaaSMarcel Holtmann __u16 le_max_rx_time; 27030d65e08SMatias Karhumaa __u8 le_max_key_size; 27130d65e08SMatias Karhumaa __u8 le_min_key_size; 272b9a7a61eSLukasz Rymanowski __u16 discov_interleaved_timeout; 27331ad1691SAndrzej Kaczmarek __u16 conn_info_min_age; 27431ad1691SAndrzej Kaczmarek __u16 conn_info_max_age; 27506f5b778SMarcel Holtmann __u8 ssp_debug_mode; 276c7741d16SMarcel Holtmann __u8 hw_error_code; 27733f35721SJohan Hedberg __u32 clock; 278f332ec66SJohan Hedberg 2792b9be137SMarcel Holtmann __u16 devid_source; 2802b9be137SMarcel Holtmann __u16 devid_vendor; 2812b9be137SMarcel Holtmann __u16 devid_product; 2822b9be137SMarcel Holtmann __u16 devid_version; 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds __u16 pkt_type; 2855b7f9909SMarcel Holtmann __u16 esco_type; 2861da177e4SLinus Torvalds __u16 link_policy; 2871da177e4SLinus Torvalds __u16 link_mode; 2881da177e4SLinus Torvalds 28904837f64SMarcel Holtmann __u32 idle_timeout; 29004837f64SMarcel Holtmann __u16 sniff_min_interval; 29104837f64SMarcel Holtmann __u16 sniff_max_interval; 29204837f64SMarcel Holtmann 293928abaa7SAndrei Emeltchenko __u8 amp_status; 294928abaa7SAndrei Emeltchenko __u32 amp_total_bw; 295928abaa7SAndrei Emeltchenko __u32 amp_max_bw; 296928abaa7SAndrei Emeltchenko __u32 amp_min_latency; 297928abaa7SAndrei Emeltchenko __u32 amp_max_pdu; 298928abaa7SAndrei Emeltchenko __u8 amp_type; 299928abaa7SAndrei Emeltchenko __u16 amp_pal_cap; 300928abaa7SAndrei Emeltchenko __u16 amp_assoc_size; 301928abaa7SAndrei Emeltchenko __u32 amp_max_flush_to; 302928abaa7SAndrei Emeltchenko __u32 amp_be_flush_to; 303928abaa7SAndrei Emeltchenko 304903e4541SAndrei Emeltchenko struct amp_assoc loc_assoc; 305903e4541SAndrei Emeltchenko 3061e89cffbSAndrei Emeltchenko __u8 flow_ctl_mode; 3071e89cffbSAndrei Emeltchenko 3089f61656aSJohan Hedberg unsigned int auto_accept_delay; 3099f61656aSJohan Hedberg 3101da177e4SLinus Torvalds unsigned long quirks; 3111da177e4SLinus Torvalds 3121da177e4SLinus Torvalds atomic_t cmd_cnt; 3131da177e4SLinus Torvalds unsigned int acl_cnt; 3141da177e4SLinus Torvalds unsigned int sco_cnt; 3156ed58ec5SVille Tervo unsigned int le_cnt; 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds unsigned int acl_mtu; 3181da177e4SLinus Torvalds unsigned int sco_mtu; 3196ed58ec5SVille Tervo unsigned int le_mtu; 3201da177e4SLinus Torvalds unsigned int acl_pkts; 3211da177e4SLinus Torvalds unsigned int sco_pkts; 3226ed58ec5SVille Tervo unsigned int le_pkts; 3231da177e4SLinus Torvalds 324350ee4cfSAndrei Emeltchenko __u16 block_len; 325350ee4cfSAndrei Emeltchenko __u16 block_mtu; 326350ee4cfSAndrei Emeltchenko __u16 num_blocks; 327350ee4cfSAndrei Emeltchenko __u16 block_cnt; 328350ee4cfSAndrei Emeltchenko 3291da177e4SLinus Torvalds unsigned long acl_last_tx; 3301da177e4SLinus Torvalds unsigned long sco_last_tx; 3316ed58ec5SVille Tervo unsigned long le_last_tx; 3321da177e4SLinus Torvalds 3336decb5b4SJaganath Kanakkassery __u8 le_tx_def_phys; 3346decb5b4SJaganath Kanakkassery __u8 le_rx_def_phys; 3356decb5b4SJaganath Kanakkassery 336f48fd9c8SMarcel Holtmann struct workqueue_struct *workqueue; 3376ead1bbcSJohan Hedberg struct workqueue_struct *req_workqueue; 338f48fd9c8SMarcel Holtmann 339ab81cbf9SJohan Hedberg struct work_struct power_on; 3403243553fSJohan Hedberg struct delayed_work power_off; 341c7741d16SMarcel Holtmann struct work_struct error_reset; 342ab81cbf9SJohan Hedberg 34316ab91abSJohan Hedberg __u16 discov_timeout; 34416ab91abSJohan Hedberg struct delayed_work discov_off; 34516ab91abSJohan Hedberg 3467d78525dSJohan Hedberg struct delayed_work service_cache; 3477d78525dSJohan Hedberg 34865cc2b49SMarcel Holtmann struct delayed_work cmd_timer; 349b78752ccSMarcel Holtmann 350b78752ccSMarcel Holtmann struct work_struct rx_work; 351c347b765SGustavo F. Padovan struct work_struct cmd_work; 3523eff45eaSGustavo F. Padovan struct work_struct tx_work; 3531da177e4SLinus Torvalds 354e68f072bSJohan Hedberg struct work_struct discov_update; 3552e93e53bSJohan Hedberg struct work_struct bg_scan_update; 35601b1cb87SJohan Hedberg struct work_struct scan_update; 35753c0ba74SJohan Hedberg struct work_struct connectable_update; 358aed1a885SJohan Hedberg struct work_struct discoverable_update; 3597c1fbed2SJohan Hedberg struct delayed_work le_scan_disable; 3607c1fbed2SJohan Hedberg struct delayed_work le_scan_restart; 3612e93e53bSJohan Hedberg 3621da177e4SLinus Torvalds struct sk_buff_head rx_q; 3631da177e4SLinus Torvalds struct sk_buff_head raw_q; 3641da177e4SLinus Torvalds struct sk_buff_head cmd_q; 3651da177e4SLinus Torvalds 3661da177e4SLinus Torvalds struct sk_buff *sent_cmd; 3671da177e4SLinus Torvalds 368a6a67efdSThomas Gleixner struct mutex req_lock; 3691da177e4SLinus Torvalds wait_queue_head_t req_wait_q; 3701da177e4SLinus Torvalds __u32 req_status; 3711da177e4SLinus Torvalds __u32 req_result; 372f60cb305SJohan Hedberg struct sk_buff *req_skb; 373a5040efaSJohan Hedberg 37470db83c4SJohan Hedberg void *smp_data; 375ef8efe4bSJohan Hedberg void *smp_bredr_data; 3762e58ef3eSJohan Hedberg 37730883512SJohan Hedberg struct discovery_state discovery; 3781da177e4SLinus Torvalds struct hci_conn_hash conn_hash; 3795c136e90SAndre Guedes 3805c136e90SAndre Guedes struct list_head mgmt_pending; 381ea4bd8baSDavid Miller struct list_head blacklist; 3826659358eSJohan Hedberg struct list_head whitelist; 3832aeb9a1aSJohan Hedberg struct list_head uuids; 38455ed8ca1SJohan Hedberg struct list_head link_keys; 385b899efafSVinicius Costa Gomes struct list_head long_term_keys; 386970c4e46SJohan Hedberg struct list_head identity_resolving_keys; 3872763eda6SSzymon Janc struct list_head remote_oob_data; 388d2ab0ac1SMarcel Holtmann struct list_head le_white_list; 389cfdb0c2dSAnkit Navik struct list_head le_resolv_list; 39015819a70SAndre Guedes struct list_head le_conn_params; 39177a77a30SAndre Guedes struct list_head pend_le_conns; 39266f8455aSJohan Hedberg struct list_head pend_le_reports; 3932763eda6SSzymon Janc 3941da177e4SLinus Torvalds struct hci_dev_stats stat; 3951da177e4SLinus Torvalds 3961da177e4SLinus Torvalds atomic_t promisc; 3971da177e4SLinus Torvalds 3985177a838SMarcel Holtmann const char *hw_info; 3995177a838SMarcel Holtmann const char *fw_info; 400ca325f69SMarcel Holtmann struct dentry *debugfs; 401ca325f69SMarcel Holtmann 402a91f2e39SMarcel Holtmann struct device dev; 4031da177e4SLinus Torvalds 404611b30f7SMarcel Holtmann struct rfkill *rfkill; 405611b30f7SMarcel Holtmann 406eacb44dfSMarcel Holtmann DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS); 407d23264a8SAndre Guedes 4088fa19098SJohan Hedberg __s8 adv_tx_power; 4093f0f524bSJohan Hedberg __u8 adv_data[HCI_MAX_AD_LENGTH]; 4103f0f524bSJohan Hedberg __u8 adv_data_len; 411f8e808bdSMarcel Holtmann __u8 scan_rsp_data[HCI_MAX_AD_LENGTH]; 412f8e808bdSMarcel Holtmann __u8 scan_rsp_data_len; 4138fa19098SJohan Hedberg 414d2609b34SFlorian Grandel struct list_head adv_instances; 415d2609b34SFlorian Grandel unsigned int adv_instance_cnt; 416d2609b34SFlorian Grandel __u8 cur_adv_instance; 4175d900e46SFlorian Grandel __u16 adv_instance_timeout; 4185d900e46SFlorian Grandel struct delayed_work adv_instance_expire; 419203fea01SArman Uguray 420863efaf2SJohan Hedberg __u8 irk[16]; 421d6bfd59cSJohan Hedberg __u32 rpa_timeout; 422d6bfd59cSJohan Hedberg struct delayed_work rpa_expired; 4232b5224dcSMarcel Holtmann bdaddr_t rpa; 424863efaf2SJohan Hedberg 42553f863a6SMarcel Holtmann #if IS_ENABLED(CONFIG_BT_LEDS) 4266d5d2ee6SHeiner Kallweit struct led_trigger *power_led; 42753f863a6SMarcel Holtmann #endif 4286d5d2ee6SHeiner Kallweit 4291da177e4SLinus Torvalds int (*open)(struct hci_dev *hdev); 4301da177e4SLinus Torvalds int (*close)(struct hci_dev *hdev); 4311da177e4SLinus Torvalds int (*flush)(struct hci_dev *hdev); 432f41c70c4SMarcel Holtmann int (*setup)(struct hci_dev *hdev); 433a44fecbdSTedd Ho-Jeong An int (*shutdown)(struct hci_dev *hdev); 4347bd8f09fSMarcel Holtmann int (*send)(struct hci_dev *hdev, struct sk_buff *skb); 4351da177e4SLinus Torvalds void (*notify)(struct hci_dev *hdev, unsigned int evt); 436c7741d16SMarcel Holtmann void (*hw_error)(struct hci_dev *hdev, u8 code); 43798a63aafSMarcel Holtmann int (*post_init)(struct hci_dev *hdev); 4384b4113d6SMarcel Holtmann int (*set_diag)(struct hci_dev *hdev, bool enable); 43924c457e2SMarcel Holtmann int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); 4401da177e4SLinus Torvalds }; 4411da177e4SLinus Torvalds 44253502d69SAndrei Emeltchenko #define HCI_PHY_HANDLE(handle) (handle & 0xff) 44353502d69SAndrei Emeltchenko 4441da177e4SLinus Torvalds struct hci_conn { 4451da177e4SLinus Torvalds struct list_head list; 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvalds atomic_t refcnt; 4481da177e4SLinus Torvalds 4491da177e4SLinus Torvalds bdaddr_t dst; 45029b7988aSAndre Guedes __u8 dst_type; 451662e8820SMarcel Holtmann bdaddr_t src; 452e7c4096eSMarcel Holtmann __u8 src_type; 453cb1d68f7SJohan Hedberg bdaddr_t init_addr; 454cb1d68f7SJohan Hedberg __u8 init_addr_type; 455cb1d68f7SJohan Hedberg bdaddr_t resp_addr; 456cb1d68f7SJohan Hedberg __u8 resp_addr_type; 4571da177e4SLinus Torvalds __u16 handle; 4581da177e4SLinus Torvalds __u16 state; 45904837f64SMarcel Holtmann __u8 mode; 4601da177e4SLinus Torvalds __u8 type; 46140bef302SJohan Hedberg __u8 role; 462a0c808b3SJohan Hedberg bool out; 4634c67bc74SMarcel Holtmann __u8 attempt; 4641da177e4SLinus Torvalds __u8 dev_class[3]; 465cad718edSJohan Hedberg __u8 features[HCI_MAX_PAGES][8]; 466a8746417SMarcel Holtmann __u16 pkt_type; 46704837f64SMarcel Holtmann __u16 link_policy; 46813d39315SWaldemar Rymarkiewicz __u8 key_type; 46940be492fSMarcel Holtmann __u8 auth_type; 4708c1b2355SMarcel Holtmann __u8 sec_level; 471765c2a96SJohan Hedberg __u8 pending_sec_level; 472980e1a53SJohan Hedberg __u8 pin_length; 473726b4ffcSVinicius Costa Gomes __u8 enc_key_size; 47417fa4b9dSJohan Hedberg __u8 io_capability; 47592a25256SJohan Hedberg __u32 passkey_notify; 47692a25256SJohan Hedberg __u8 passkey_entered; 477052b30b0SMarcel Holtmann __u16 disc_timeout; 47809ae260bSJohan Hedberg __u16 conn_timeout; 47910c62ddcSFrédéric Dalleau __u16 setting; 4801e406eefSAndre Guedes __u16 le_conn_min_interval; 4811e406eefSAndre Guedes __u16 le_conn_max_interval; 482e04fde60SMarcel Holtmann __u16 le_conn_interval; 483e04fde60SMarcel Holtmann __u16 le_conn_latency; 484e04fde60SMarcel Holtmann __u16 le_supv_timeout; 485fd45ada9SAlfonso Acosta __u8 le_adv_data[HCI_MAX_AD_LENGTH]; 486fd45ada9SAlfonso Acosta __u8 le_adv_data_len; 4875ae76a94SAndrzej Kaczmarek __s8 rssi; 4885a134faeSAndrzej Kaczmarek __s8 tx_power; 489d0455ed9SAndrzej Kaczmarek __s8 max_tx_power; 49051a8efd7SJohan Hedberg unsigned long flags; 4911da177e4SLinus Torvalds 49233f35721SJohan Hedberg __u32 clock; 49333f35721SJohan Hedberg __u16 clock_accuracy; 49433f35721SJohan Hedberg 495dd983808SAndrzej Kaczmarek unsigned long conn_info_timestamp; 496dd983808SAndrzej Kaczmarek 49703b555e1SJohan Hedberg __u8 remote_cap; 49803b555e1SJohan Hedberg __u8 remote_auth; 4993161ae1cSAndrei Emeltchenko __u8 remote_id; 50003b555e1SJohan Hedberg 5011da177e4SLinus Torvalds unsigned int sent; 5021da177e4SLinus Torvalds 5031da177e4SLinus Torvalds struct sk_buff_head data_q; 5042c33c06aSGustavo F. Padovan struct list_head chan_list; 5051da177e4SLinus Torvalds 50619c40e3bSGustavo F. Padovan struct delayed_work disc_work; 5077bc18d9dSJohan Hedberg struct delayed_work auto_accept_work; 508a74a84f6SJohan Hedberg struct delayed_work idle_work; 5099489eca4SJohan Hedberg struct delayed_work le_conn_timeout; 5108ce783dcSJohan Hedberg struct work_struct le_scan_cleanup; 5111da177e4SLinus Torvalds 512b219e3acSMarcel Holtmann struct device dev; 51323b9ceb7SMarcel Holtmann struct dentry *debugfs; 514b219e3acSMarcel Holtmann 5151da177e4SLinus Torvalds struct hci_dev *hdev; 5161da177e4SLinus Torvalds void *l2cap_data; 5171da177e4SLinus Torvalds void *sco_data; 5189740e49dSAndrei Emeltchenko struct amp_mgr *amp_mgr; 5191da177e4SLinus Torvalds 5201da177e4SLinus Torvalds struct hci_conn *link; 521e9a416b5SJohan Hedberg 522e9a416b5SJohan Hedberg void (*connect_cfm_cb) (struct hci_conn *conn, u8 status); 523e9a416b5SJohan Hedberg void (*security_cfm_cb) (struct hci_conn *conn, u8 status); 524e9a416b5SJohan Hedberg void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); 5251da177e4SLinus Torvalds }; 5261da177e4SLinus Torvalds 52773d80debSLuiz Augusto von Dentz struct hci_chan { 52873d80debSLuiz Augusto von Dentz struct list_head list; 52942c4e53eSAndrei Emeltchenko __u16 handle; 53073d80debSLuiz Augusto von Dentz struct hci_conn *conn; 53173d80debSLuiz Augusto von Dentz struct sk_buff_head data_q; 53273d80debSLuiz Augusto von Dentz unsigned int sent; 533168df8e5SMat Martineau __u8 state; 53473d80debSLuiz Augusto von Dentz }; 53573d80debSLuiz Augusto von Dentz 53615819a70SAndre Guedes struct hci_conn_params { 53715819a70SAndre Guedes struct list_head list; 53893450c75SJohan Hedberg struct list_head action; 53915819a70SAndre Guedes 54015819a70SAndre Guedes bdaddr_t addr; 54115819a70SAndre Guedes u8 addr_type; 54215819a70SAndre Guedes 54315819a70SAndre Guedes u16 conn_min_interval; 54415819a70SAndre Guedes u16 conn_max_interval; 545f044eb05SMarcel Holtmann u16 conn_latency; 546f044eb05SMarcel Holtmann u16 supervision_timeout; 5479fcb18efSAndre Guedes 5489fcb18efSAndre Guedes enum { 5499fcb18efSAndre Guedes HCI_AUTO_CONN_DISABLED, 550a3451d27SJohan Hedberg HCI_AUTO_CONN_REPORT, 5514b9e7e75SMarcel Holtmann HCI_AUTO_CONN_DIRECT, 5529fcb18efSAndre Guedes HCI_AUTO_CONN_ALWAYS, 5539fcb18efSAndre Guedes HCI_AUTO_CONN_LINK_LOSS, 554158e9218SJakub Pawlowski HCI_AUTO_CONN_EXPLICIT, 5559fcb18efSAndre Guedes } auto_connect; 556f161dd41SJohan Hedberg 557f161dd41SJohan Hedberg struct hci_conn *conn; 558158e9218SJakub Pawlowski bool explicit_connect; 55915819a70SAndre Guedes }; 56015819a70SAndre Guedes 5611da177e4SLinus Torvalds extern struct list_head hci_dev_list; 5621da177e4SLinus Torvalds extern struct list_head hci_cb_list; 5631da177e4SLinus Torvalds extern rwlock_t hci_dev_list_lock; 564fba7ecf0SJohan Hedberg extern struct mutex hci_cb_list_lock; 5651da177e4SLinus Torvalds 566eacb44dfSMarcel Holtmann #define hci_dev_set_flag(hdev, nr) set_bit((nr), (hdev)->dev_flags) 567eacb44dfSMarcel Holtmann #define hci_dev_clear_flag(hdev, nr) clear_bit((nr), (hdev)->dev_flags) 568eacb44dfSMarcel Holtmann #define hci_dev_change_flag(hdev, nr) change_bit((nr), (hdev)->dev_flags) 569eacb44dfSMarcel Holtmann #define hci_dev_test_flag(hdev, nr) test_bit((nr), (hdev)->dev_flags) 570eacb44dfSMarcel Holtmann #define hci_dev_test_and_set_flag(hdev, nr) test_and_set_bit((nr), (hdev)->dev_flags) 571eacb44dfSMarcel Holtmann #define hci_dev_test_and_clear_flag(hdev, nr) test_and_clear_bit((nr), (hdev)->dev_flags) 572eacb44dfSMarcel Holtmann #define hci_dev_test_and_change_flag(hdev, nr) test_and_change_bit((nr), (hdev)->dev_flags) 573d7a5a11dSMarcel Holtmann 574eacb44dfSMarcel Holtmann #define hci_dev_clear_volatile_flags(hdev) \ 575eacb44dfSMarcel Holtmann do { \ 576eacb44dfSMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_SCAN); \ 577eacb44dfSMarcel Holtmann hci_dev_clear_flag(hdev, HCI_LE_ADV); \ 578eacb44dfSMarcel Holtmann hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); \ 579eacb44dfSMarcel Holtmann } while (0) 580516018a9SMarcel Holtmann 581686ebf28SUlisses Furquim /* ----- HCI interface to upper protocols ----- */ 582e74e58f8SJoe Perches int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); 583e74e58f8SJoe Perches int l2cap_disconn_ind(struct hci_conn *hcon); 5849b4c3336SArron Wang void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); 585686ebf28SUlisses Furquim 586ff50e8afSArron Wang #if IS_ENABLED(CONFIG_BT_BREDR) 587e74e58f8SJoe Perches int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags); 5889b4c3336SArron Wang void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); 589ff50e8afSArron Wang #else 590ff50e8afSArron Wang static inline int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, 591ff50e8afSArron Wang __u8 *flags) 592ff50e8afSArron Wang { 593ff50e8afSArron Wang return 0; 594ff50e8afSArron Wang } 595ff50e8afSArron Wang 596ff50e8afSArron Wang static inline void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) 597ff50e8afSArron Wang { 598ff50e8afSArron Wang } 599ff50e8afSArron Wang #endif 600686ebf28SUlisses Furquim 6011da177e4SLinus Torvalds /* ----- Inquiry cache ----- */ 60270f23020SAndrei Emeltchenko #define INQUIRY_CACHE_AGE_MAX (HZ*30) /* 30 seconds */ 60370f23020SAndrei Emeltchenko #define INQUIRY_ENTRY_AGE_MAX (HZ*60) /* 60 seconds */ 6041da177e4SLinus Torvalds 60530883512SJohan Hedberg static inline void discovery_init(struct hci_dev *hdev) 6061da177e4SLinus Torvalds { 607ff9ef578SJohan Hedberg hdev->discovery.state = DISCOVERY_STOPPED; 60830883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.all); 60930883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.unknown); 61030883512SJohan Hedberg INIT_LIST_HEAD(&hdev->discovery.resolve); 611da25cf6aSMarcel Holtmann hdev->discovery.report_invalid_rssi = true; 61237eab042SJakub Pawlowski hdev->discovery.rssi = HCI_RSSI_INVALID; 6131da177e4SLinus Torvalds } 6141da177e4SLinus Torvalds 6150256325eSMarcel Holtmann static inline void hci_discovery_filter_clear(struct hci_dev *hdev) 6160256325eSMarcel Holtmann { 61782f8b651SJakub Pawlowski hdev->discovery.result_filtering = false; 618da25cf6aSMarcel Holtmann hdev->discovery.report_invalid_rssi = true; 6190256325eSMarcel Holtmann hdev->discovery.rssi = HCI_RSSI_INVALID; 6200256325eSMarcel Holtmann hdev->discovery.uuid_count = 0; 6210256325eSMarcel Holtmann kfree(hdev->discovery.uuids); 6220256325eSMarcel Holtmann hdev->discovery.uuids = NULL; 6232d28cfe7SJakub Pawlowski hdev->discovery.scan_start = 0; 6242d28cfe7SJakub Pawlowski hdev->discovery.scan_duration = 0; 6250256325eSMarcel Holtmann } 6260256325eSMarcel Holtmann 62730dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev); 62830dc78e1SJohan Hedberg 629ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state); 630ff9ef578SJohan Hedberg 6311da177e4SLinus Torvalds static inline int inquiry_cache_empty(struct hci_dev *hdev) 6321da177e4SLinus Torvalds { 63330883512SJohan Hedberg return list_empty(&hdev->discovery.all); 6341da177e4SLinus Torvalds } 6351da177e4SLinus Torvalds 6361da177e4SLinus Torvalds static inline long inquiry_cache_age(struct hci_dev *hdev) 6371da177e4SLinus Torvalds { 63830883512SJohan Hedberg struct discovery_state *c = &hdev->discovery; 6391da177e4SLinus Torvalds return jiffies - c->timestamp; 6401da177e4SLinus Torvalds } 6411da177e4SLinus Torvalds 6421da177e4SLinus Torvalds static inline long inquiry_entry_age(struct inquiry_entry *e) 6431da177e4SLinus Torvalds { 6441da177e4SLinus Torvalds return jiffies - e->timestamp; 6451da177e4SLinus Torvalds } 6461da177e4SLinus Torvalds 6475a9d0a3fSWaldemar Rymarkiewicz struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, 6485a9d0a3fSWaldemar Rymarkiewicz bdaddr_t *bdaddr); 649561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev, 650561aafbcSJohan Hedberg bdaddr_t *bdaddr); 65130dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev, 65230dc78e1SJohan Hedberg bdaddr_t *bdaddr, 65330dc78e1SJohan Hedberg int state); 654a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, 655a3d4e20aSJohan Hedberg struct inquiry_entry *ie); 656af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, 657af58925cSMarcel Holtmann bool name_known); 6581f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev); 6591da177e4SLinus Torvalds 6601da177e4SLinus Torvalds /* ----- HCI Connections ----- */ 6611da177e4SLinus Torvalds enum { 6621da177e4SLinus Torvalds HCI_CONN_AUTH_PEND, 66319f8def0SWaldemar Rymarkiewicz HCI_CONN_REAUTH_PEND, 6641da177e4SLinus Torvalds HCI_CONN_ENCRYPT_PEND, 66504837f64SMarcel Holtmann HCI_CONN_RSWITCH_PEND, 66604837f64SMarcel Holtmann HCI_CONN_MODE_CHANGE_PEND, 667e73439d8SMarcel Holtmann HCI_CONN_SCO_SETUP_PEND, 668b644ba33SJohan Hedberg HCI_CONN_MGMT_CONNECTED, 66958a681efSJohan Hedberg HCI_CONN_SSP_ENABLED, 670eb9a8f3fSMarcel Holtmann HCI_CONN_SC_ENABLED, 671abf76badSMarcel Holtmann HCI_CONN_AES_CCM, 67258a681efSJohan Hedberg HCI_CONN_POWER_SAVE, 673af6a9c32SJohan Hedberg HCI_CONN_FLUSH_KEY, 6744dae2798SJohan Hedberg HCI_CONN_ENCRYPT, 6754dae2798SJohan Hedberg HCI_CONN_AUTH, 6764dae2798SJohan Hedberg HCI_CONN_SECURE, 6774dae2798SJohan Hedberg HCI_CONN_FIPS, 678fe59a05fSJohan Hedberg HCI_CONN_STK_ENCRYPT, 679977f8fceSJohan Hedberg HCI_CONN_AUTH_INITIATOR, 680f94b665dSJohan Hedberg HCI_CONN_DROP, 68189cbb063SAlfonso Acosta HCI_CONN_PARAM_REMOVAL_PEND, 682fe8bc5acSJohan Hedberg HCI_CONN_NEW_LINK_KEY, 683158e9218SJakub Pawlowski HCI_CONN_SCANNING, 684160b9251SSzymon Janc HCI_CONN_AUTH_FAILURE, 6851da177e4SLinus Torvalds }; 6861da177e4SLinus Torvalds 687aa64a8b5SJohan Hedberg static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) 688aa64a8b5SJohan Hedberg { 689aa64a8b5SJohan Hedberg struct hci_dev *hdev = conn->hdev; 690d7a5a11dSMarcel Holtmann return hci_dev_test_flag(hdev, HCI_SSP_ENABLED) && 691c3c7ea65SGustavo Padovan test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); 692aa64a8b5SJohan Hedberg } 693aa64a8b5SJohan Hedberg 694eb9a8f3fSMarcel Holtmann static inline bool hci_conn_sc_enabled(struct hci_conn *conn) 695eb9a8f3fSMarcel Holtmann { 696eb9a8f3fSMarcel Holtmann struct hci_dev *hdev = conn->hdev; 697d7a5a11dSMarcel Holtmann return hci_dev_test_flag(hdev, HCI_SC_ENABLED) && 698eb9a8f3fSMarcel Holtmann test_bit(HCI_CONN_SC_ENABLED, &conn->flags); 699eb9a8f3fSMarcel Holtmann } 700eb9a8f3fSMarcel Holtmann 7011da177e4SLinus Torvalds static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) 7021da177e4SLinus Torvalds { 7031da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 704bf4c6325SGustavo F. Padovan list_add_rcu(&c->list, &h->list); 705fcd89c09SVille Tervo switch (c->type) { 706fcd89c09SVille Tervo case ACL_LINK: 7071da177e4SLinus Torvalds h->acl_num++; 708fcd89c09SVille Tervo break; 709bd1eb66bSAndrei Emeltchenko case AMP_LINK: 710bd1eb66bSAndrei Emeltchenko h->amp_num++; 711bd1eb66bSAndrei Emeltchenko break; 712fcd89c09SVille Tervo case LE_LINK: 713fcd89c09SVille Tervo h->le_num++; 714f8218dc6SJohan Hedberg if (c->role == HCI_ROLE_SLAVE) 715f8218dc6SJohan Hedberg h->le_num_slave++; 716fcd89c09SVille Tervo break; 717fcd89c09SVille Tervo case SCO_LINK: 718fcd89c09SVille Tervo case ESCO_LINK: 7191da177e4SLinus Torvalds h->sco_num++; 720fcd89c09SVille Tervo break; 721fcd89c09SVille Tervo } 7221da177e4SLinus Torvalds } 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) 7251da177e4SLinus Torvalds { 7261da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 727bf4c6325SGustavo F. Padovan 728bf4c6325SGustavo F. Padovan list_del_rcu(&c->list); 729bf4c6325SGustavo F. Padovan synchronize_rcu(); 730bf4c6325SGustavo F. Padovan 731fcd89c09SVille Tervo switch (c->type) { 732fcd89c09SVille Tervo case ACL_LINK: 7331da177e4SLinus Torvalds h->acl_num--; 734fcd89c09SVille Tervo break; 735bd1eb66bSAndrei Emeltchenko case AMP_LINK: 736bd1eb66bSAndrei Emeltchenko h->amp_num--; 737bd1eb66bSAndrei Emeltchenko break; 738fcd89c09SVille Tervo case LE_LINK: 739fcd89c09SVille Tervo h->le_num--; 740f8218dc6SJohan Hedberg if (c->role == HCI_ROLE_SLAVE) 741f8218dc6SJohan Hedberg h->le_num_slave--; 742fcd89c09SVille Tervo break; 743fcd89c09SVille Tervo case SCO_LINK: 744fcd89c09SVille Tervo case ESCO_LINK: 7451da177e4SLinus Torvalds h->sco_num--; 746fcd89c09SVille Tervo break; 747fcd89c09SVille Tervo } 7481da177e4SLinus Torvalds } 7491da177e4SLinus Torvalds 75052087a79SLuiz Augusto von Dentz static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type) 75152087a79SLuiz Augusto von Dentz { 75252087a79SLuiz Augusto von Dentz struct hci_conn_hash *h = &hdev->conn_hash; 75352087a79SLuiz Augusto von Dentz switch (type) { 75452087a79SLuiz Augusto von Dentz case ACL_LINK: 75552087a79SLuiz Augusto von Dentz return h->acl_num; 756bd1eb66bSAndrei Emeltchenko case AMP_LINK: 757bd1eb66bSAndrei Emeltchenko return h->amp_num; 75852087a79SLuiz Augusto von Dentz case LE_LINK: 75952087a79SLuiz Augusto von Dentz return h->le_num; 76052087a79SLuiz Augusto von Dentz case SCO_LINK: 76152087a79SLuiz Augusto von Dentz case ESCO_LINK: 76252087a79SLuiz Augusto von Dentz return h->sco_num; 76352087a79SLuiz Augusto von Dentz default: 76452087a79SLuiz Augusto von Dentz return 0; 76552087a79SLuiz Augusto von Dentz } 76652087a79SLuiz Augusto von Dentz } 76752087a79SLuiz Augusto von Dentz 768f4f07505SJohan Hedberg static inline unsigned int hci_conn_count(struct hci_dev *hdev) 769f4f07505SJohan Hedberg { 770f4f07505SJohan Hedberg struct hci_conn_hash *c = &hdev->conn_hash; 771f4f07505SJohan Hedberg 772f4f07505SJohan Hedberg return c->acl_num + c->amp_num + c->sco_num + c->le_num; 773f4f07505SJohan Hedberg } 774f4f07505SJohan Hedberg 775845472e8SMarcel Holtmann static inline __u8 hci_conn_lookup_type(struct hci_dev *hdev, __u16 handle) 776845472e8SMarcel Holtmann { 777845472e8SMarcel Holtmann struct hci_conn_hash *h = &hdev->conn_hash; 778845472e8SMarcel Holtmann struct hci_conn *c; 779845472e8SMarcel Holtmann __u8 type = INVALID_LINK; 780845472e8SMarcel Holtmann 781845472e8SMarcel Holtmann rcu_read_lock(); 782845472e8SMarcel Holtmann 783845472e8SMarcel Holtmann list_for_each_entry_rcu(c, &h->list, list) { 784845472e8SMarcel Holtmann if (c->handle == handle) { 785845472e8SMarcel Holtmann type = c->type; 786845472e8SMarcel Holtmann break; 787845472e8SMarcel Holtmann } 788845472e8SMarcel Holtmann } 789845472e8SMarcel Holtmann 790845472e8SMarcel Holtmann rcu_read_unlock(); 791845472e8SMarcel Holtmann 792845472e8SMarcel Holtmann return type; 793845472e8SMarcel Holtmann } 794845472e8SMarcel Holtmann 7951da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, 7961da177e4SLinus Torvalds __u16 handle) 7971da177e4SLinus Torvalds { 7981da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 7991da177e4SLinus Torvalds struct hci_conn *c; 8001da177e4SLinus Torvalds 801bf4c6325SGustavo F. Padovan rcu_read_lock(); 802bf4c6325SGustavo F. Padovan 803bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 804bf4c6325SGustavo F. Padovan if (c->handle == handle) { 805bf4c6325SGustavo F. Padovan rcu_read_unlock(); 8061da177e4SLinus Torvalds return c; 8071da177e4SLinus Torvalds } 808bf4c6325SGustavo F. Padovan } 809bf4c6325SGustavo F. Padovan rcu_read_unlock(); 810bf4c6325SGustavo F. Padovan 8111da177e4SLinus Torvalds return NULL; 8121da177e4SLinus Torvalds } 8131da177e4SLinus Torvalds 8141da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, 8151da177e4SLinus Torvalds __u8 type, bdaddr_t *ba) 8161da177e4SLinus Torvalds { 8171da177e4SLinus Torvalds struct hci_conn_hash *h = &hdev->conn_hash; 8181da177e4SLinus Torvalds struct hci_conn *c; 8191da177e4SLinus Torvalds 820bf4c6325SGustavo F. Padovan rcu_read_lock(); 821bf4c6325SGustavo F. Padovan 822bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 823bf4c6325SGustavo F. Padovan if (c->type == type && !bacmp(&c->dst, ba)) { 824bf4c6325SGustavo F. Padovan rcu_read_unlock(); 8251da177e4SLinus Torvalds return c; 8261da177e4SLinus Torvalds } 827bf4c6325SGustavo F. Padovan } 828bf4c6325SGustavo F. Padovan 829bf4c6325SGustavo F. Padovan rcu_read_unlock(); 830bf4c6325SGustavo F. Padovan 8311da177e4SLinus Torvalds return NULL; 8321da177e4SLinus Torvalds } 8331da177e4SLinus Torvalds 8341b51c7b6SJohan Hedberg static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev, 8351b51c7b6SJohan Hedberg bdaddr_t *ba, 8361b51c7b6SJohan Hedberg __u8 ba_type) 8371b51c7b6SJohan Hedberg { 8381b51c7b6SJohan Hedberg struct hci_conn_hash *h = &hdev->conn_hash; 8391b51c7b6SJohan Hedberg struct hci_conn *c; 8401b51c7b6SJohan Hedberg 8411b51c7b6SJohan Hedberg rcu_read_lock(); 8421b51c7b6SJohan Hedberg 8431b51c7b6SJohan Hedberg list_for_each_entry_rcu(c, &h->list, list) { 8441b51c7b6SJohan Hedberg if (c->type != LE_LINK) 8451b51c7b6SJohan Hedberg continue; 8461b51c7b6SJohan Hedberg 8471b51c7b6SJohan Hedberg if (ba_type == c->dst_type && !bacmp(&c->dst, ba)) { 8481b51c7b6SJohan Hedberg rcu_read_unlock(); 8491b51c7b6SJohan Hedberg return c; 8501b51c7b6SJohan Hedberg } 8511b51c7b6SJohan Hedberg } 8521b51c7b6SJohan Hedberg 8531b51c7b6SJohan Hedberg rcu_read_unlock(); 8541b51c7b6SJohan Hedberg 8551b51c7b6SJohan Hedberg return NULL; 8561b51c7b6SJohan Hedberg } 8571b51c7b6SJohan Hedberg 8584c67bc74SMarcel Holtmann static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, 8594c67bc74SMarcel Holtmann __u8 type, __u16 state) 8604c67bc74SMarcel Holtmann { 8614c67bc74SMarcel Holtmann struct hci_conn_hash *h = &hdev->conn_hash; 8624c67bc74SMarcel Holtmann struct hci_conn *c; 8634c67bc74SMarcel Holtmann 864bf4c6325SGustavo F. Padovan rcu_read_lock(); 865bf4c6325SGustavo F. Padovan 866bf4c6325SGustavo F. Padovan list_for_each_entry_rcu(c, &h->list, list) { 867bf4c6325SGustavo F. Padovan if (c->type == type && c->state == state) { 868bf4c6325SGustavo F. Padovan rcu_read_unlock(); 8694c67bc74SMarcel Holtmann return c; 8704c67bc74SMarcel Holtmann } 871bf4c6325SGustavo F. Padovan } 872bf4c6325SGustavo F. Padovan 873bf4c6325SGustavo F. Padovan rcu_read_unlock(); 874bf4c6325SGustavo F. Padovan 8754c67bc74SMarcel Holtmann return NULL; 8764c67bc74SMarcel Holtmann } 8774c67bc74SMarcel Holtmann 878e7d9ab73SJakub Pawlowski static inline struct hci_conn *hci_lookup_le_connect(struct hci_dev *hdev) 879e7d9ab73SJakub Pawlowski { 880e7d9ab73SJakub Pawlowski struct hci_conn_hash *h = &hdev->conn_hash; 881e7d9ab73SJakub Pawlowski struct hci_conn *c; 882e7d9ab73SJakub Pawlowski 883e7d9ab73SJakub Pawlowski rcu_read_lock(); 884e7d9ab73SJakub Pawlowski 885e7d9ab73SJakub Pawlowski list_for_each_entry_rcu(c, &h->list, list) { 886e7d9ab73SJakub Pawlowski if (c->type == LE_LINK && c->state == BT_CONNECT && 887e7d9ab73SJakub Pawlowski !test_bit(HCI_CONN_SCANNING, &c->flags)) { 888e7d9ab73SJakub Pawlowski rcu_read_unlock(); 889e7d9ab73SJakub Pawlowski return c; 890e7d9ab73SJakub Pawlowski } 891e7d9ab73SJakub Pawlowski } 892e7d9ab73SJakub Pawlowski 893e7d9ab73SJakub Pawlowski rcu_read_unlock(); 894e7d9ab73SJakub Pawlowski 895e7d9ab73SJakub Pawlowski return NULL; 896e7d9ab73SJakub Pawlowski } 897e7d9ab73SJakub Pawlowski 898e3b679d5SJohan Hedberg int hci_disconnect(struct hci_conn *conn, __u8 reason); 8992dea632fSFrédéric Dalleau bool hci_setup_sync(struct hci_conn *conn, __u16 handle); 900e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status); 9011da177e4SLinus Torvalds 902a5c4e309SJohan Hedberg struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, 903a5c4e309SJohan Hedberg u8 role); 9041da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn); 9051da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev); 906a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev); 9071da177e4SLinus Torvalds 90873d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn); 9099472007cSAndrei Emeltchenko void hci_chan_del(struct hci_chan *chan); 9102c33c06aSGustavo F. Padovan void hci_chan_list_flush(struct hci_conn *conn); 91142c4e53eSAndrei Emeltchenko struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle); 91273d80debSLuiz Augusto von Dentz 913f75113a2SJakub Pawlowski struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst, 914f75113a2SJakub Pawlowski u8 dst_type, u8 sec_level, 9150ad06aa6SJohan Hedberg u16 conn_timeout); 91604a6c589SAndre Guedes struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, 917cdd6275eSJohan Hedberg u8 dst_type, u8 sec_level, u16 conn_timeout, 918082f2300SSzymon Janc u8 role, bdaddr_t *direct_rpa); 91904a6c589SAndre Guedes struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst, 92004a6c589SAndre Guedes u8 sec_level, u8 auth_type); 92110c62ddcSFrédéric Dalleau struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, 92210c62ddcSFrédéric Dalleau __u16 setting); 923e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn); 924b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); 925e7cafc45SJohan Hedberg int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, 926e7cafc45SJohan Hedberg bool initiator); 9278c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role); 9281da177e4SLinus Torvalds 92914b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); 9301da177e4SLinus Torvalds 93106c053fbSAndre Guedes void hci_le_conn_failed(struct hci_conn *conn, u8 status); 93206c053fbSAndre Guedes 9338d12356fSDavid Herrmann /* 9348d12356fSDavid Herrmann * hci_conn_get() and hci_conn_put() are used to control the life-time of an 9358d12356fSDavid Herrmann * "hci_conn" object. They do not guarantee that the hci_conn object is running, 9368d12356fSDavid Herrmann * working or anything else. They just guarantee that the object is available 9378d12356fSDavid Herrmann * and can be dereferenced. So you can use its locks, local variables and any 9388d12356fSDavid Herrmann * other constant data. 9398d12356fSDavid Herrmann * Before accessing runtime data, you _must_ lock the object and then check that 9408d12356fSDavid Herrmann * it is still running. As soon as you release the locks, the connection might 9418d12356fSDavid Herrmann * get dropped, though. 9428d12356fSDavid Herrmann * 9438d12356fSDavid Herrmann * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control 9448d12356fSDavid Herrmann * how long the underlying connection is held. So every channel that runs on the 9458d12356fSDavid Herrmann * hci_conn object calls this to prevent the connection from disappearing. As 9468d12356fSDavid Herrmann * long as you hold a device, you must also guarantee that you have a valid 9478d12356fSDavid Herrmann * reference to the device via hci_conn_get() (or the initial reference from 9488d12356fSDavid Herrmann * hci_conn_add()). 9498d12356fSDavid Herrmann * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't 9508d12356fSDavid Herrmann * break because nobody cares for that. But this means, we cannot use 9518d12356fSDavid Herrmann * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). 9528d12356fSDavid Herrmann */ 9538d12356fSDavid Herrmann 95451bb8457SJohan Hedberg static inline struct hci_conn *hci_conn_get(struct hci_conn *conn) 9558d12356fSDavid Herrmann { 9568d12356fSDavid Herrmann get_device(&conn->dev); 95751bb8457SJohan Hedberg return conn; 9588d12356fSDavid Herrmann } 9598d12356fSDavid Herrmann 9608d12356fSDavid Herrmann static inline void hci_conn_put(struct hci_conn *conn) 9618d12356fSDavid Herrmann { 9628d12356fSDavid Herrmann put_device(&conn->dev); 9638d12356fSDavid Herrmann } 9648d12356fSDavid Herrmann 9651da177e4SLinus Torvalds static inline void hci_conn_hold(struct hci_conn *conn) 9661da177e4SLinus Torvalds { 96771becf0cSAndrei Emeltchenko BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); 96838b3fef1SAndrei Emeltchenko 9691da177e4SLinus Torvalds atomic_inc(&conn->refcnt); 9702f304d1eSAndre Guedes cancel_delayed_work(&conn->disc_work); 9711da177e4SLinus Torvalds } 9721da177e4SLinus Torvalds 97376a68ba0SDavid Herrmann static inline void hci_conn_drop(struct hci_conn *conn) 9741da177e4SLinus Torvalds { 97571becf0cSAndrei Emeltchenko BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); 97638b3fef1SAndrei Emeltchenko 9771da177e4SLinus Torvalds if (atomic_dec_and_test(&conn->refcnt)) { 97804837f64SMarcel Holtmann unsigned long timeo; 979716e4ab5SAndrei Emeltchenko 980716e4ab5SAndrei Emeltchenko switch (conn->type) { 981716e4ab5SAndrei Emeltchenko case ACL_LINK: 982716e4ab5SAndrei Emeltchenko case LE_LINK: 983a74a84f6SJohan Hedberg cancel_delayed_work(&conn->idle_work); 9846ac59344SMarcel Holtmann if (conn->state == BT_CONNECTED) { 9855f246e89SAndrei Emeltchenko timeo = conn->disc_timeout; 98604837f64SMarcel Holtmann if (!conn->out) 987052b30b0SMarcel Holtmann timeo *= 2; 9885a9d0a3fSWaldemar Rymarkiewicz } else { 989eb78d7e5SJohan Hedberg timeo = 0; 9905a9d0a3fSWaldemar Rymarkiewicz } 991716e4ab5SAndrei Emeltchenko break; 992716e4ab5SAndrei Emeltchenko 993716e4ab5SAndrei Emeltchenko case AMP_LINK: 994716e4ab5SAndrei Emeltchenko timeo = conn->disc_timeout; 995716e4ab5SAndrei Emeltchenko break; 996716e4ab5SAndrei Emeltchenko 997716e4ab5SAndrei Emeltchenko default: 998eb78d7e5SJohan Hedberg timeo = 0; 999716e4ab5SAndrei Emeltchenko break; 10005a9d0a3fSWaldemar Rymarkiewicz } 1001716e4ab5SAndrei Emeltchenko 10022f304d1eSAndre Guedes cancel_delayed_work(&conn->disc_work); 100319c40e3bSGustavo F. Padovan queue_delayed_work(conn->hdev->workqueue, 10041931782bSVinicius Costa Gomes &conn->disc_work, timeo); 10051da177e4SLinus Torvalds } 10061da177e4SLinus Torvalds } 10071da177e4SLinus Torvalds 10081da177e4SLinus Torvalds /* ----- HCI Devices ----- */ 1009dc946bd8SDavid Herrmann static inline void hci_dev_put(struct hci_dev *d) 10101da177e4SLinus Torvalds { 1011376261aeSAndrei Emeltchenko BT_DBG("%s orig refcnt %d", d->name, 10122c935bc5SPeter Zijlstra kref_read(&d->dev.kobj.kref)); 1013376261aeSAndrei Emeltchenko 10144c724c71SDavid Herrmann put_device(&d->dev); 1015010666a1SDavid Herrmann } 10161da177e4SLinus Torvalds 1017dc946bd8SDavid Herrmann static inline struct hci_dev *hci_dev_hold(struct hci_dev *d) 10181da177e4SLinus Torvalds { 1019376261aeSAndrei Emeltchenko BT_DBG("%s orig refcnt %d", d->name, 10202c935bc5SPeter Zijlstra kref_read(&d->dev.kobj.kref)); 1021376261aeSAndrei Emeltchenko 10224c724c71SDavid Herrmann get_device(&d->dev); 10231da177e4SLinus Torvalds return d; 10241da177e4SLinus Torvalds } 10251da177e4SLinus Torvalds 102609fd0de5SGustavo F. Padovan #define hci_dev_lock(d) mutex_lock(&d->lock) 102709fd0de5SGustavo F. Padovan #define hci_dev_unlock(d) mutex_unlock(&d->lock) 10281da177e4SLinus Torvalds 1029aa2b86d7SDavid Herrmann #define to_hci_dev(d) container_of(d, struct hci_dev, dev) 10303dc07322SDavid Herrmann #define to_hci_conn(c) container_of(c, struct hci_conn, dev) 1031aa2b86d7SDavid Herrmann 1032155961e8SDavid Herrmann static inline void *hci_get_drvdata(struct hci_dev *hdev) 1033155961e8SDavid Herrmann { 1034155961e8SDavid Herrmann return dev_get_drvdata(&hdev->dev); 1035155961e8SDavid Herrmann } 1036155961e8SDavid Herrmann 1037155961e8SDavid Herrmann static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) 1038155961e8SDavid Herrmann { 1039155961e8SDavid Herrmann dev_set_drvdata(&hdev->dev, data); 1040155961e8SDavid Herrmann } 1041155961e8SDavid Herrmann 10421da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index); 104339385cb5SJohan Hedberg struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, u8 src_type); 10441da177e4SLinus Torvalds 10451da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void); 10461da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev); 10471da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev); 104859735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev); 10491da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev); 10501da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev); 105175e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev); 1052f962fe32SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); 1053f962fe32SMarcel Holtmann int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb); 10541aabbbceSNicolas Iooss __printf(2, 3) void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...); 10551aabbbceSNicolas Iooss __printf(2, 3) void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...); 10561da177e4SLinus Torvalds int hci_dev_open(__u16 dev); 10571da177e4SLinus Torvalds int hci_dev_close(__u16 dev); 10586b3cc1dbSSimon Fels int hci_dev_do_close(struct hci_dev *hdev); 10591da177e4SLinus Torvalds int hci_dev_reset(__u16 dev); 10601da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev); 10611da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg); 10621da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg); 10631da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg); 10641da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg); 10651da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); 106640be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); 10671da177e4SLinus Torvalds int hci_inquiry(void __user *arg); 10681da177e4SLinus Torvalds 1069dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list, 1070b9ee0a78SMarcel Holtmann bdaddr_t *bdaddr, u8 type); 1071b950aa88SAnkit Navik struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk( 1072b950aa88SAnkit Navik struct list_head *list, bdaddr_t *bdaddr, 1073b950aa88SAnkit Navik u8 type); 1074dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type); 1075b950aa88SAnkit Navik int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, 1076b950aa88SAnkit Navik u8 type, u8 *peer_irk, u8 *local_irk); 1077dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type); 1078b950aa88SAnkit Navik int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr, 1079b950aa88SAnkit Navik u8 type); 1080dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *list); 1081d2ab0ac1SMarcel Holtmann 108215819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, 108315819a70SAndre Guedes bdaddr_t *addr, u8 addr_type); 108451d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, 108551d167c0SMarcel Holtmann bdaddr_t *addr, u8 addr_type); 108615819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); 108755af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev); 108815819a70SAndre Guedes 1089501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, 1090501f8827SJohan Hedberg bdaddr_t *addr, 1091501f8827SJohan Hedberg u8 addr_type); 109277a77a30SAndre Guedes 109335f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev); 10942aeb9a1aSJohan Hedberg 109535f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev); 109655ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 1097567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, 10987652ff6aSJohan Hedberg bdaddr_t *bdaddr, u8 *val, u8 type, 10997652ff6aSJohan Hedberg u8 pin_len, bool *persistent); 1100ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 110135d70271SJohan Hedberg u8 addr_type, u8 type, u8 authenticated, 1102fe39c7b2SMarcel Holtmann u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand); 1103f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, 1104e804d25dSJohan Hedberg u8 addr_type, u8 role); 1105e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type); 110635f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev); 110755ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); 110855ed8ca1SJohan Hedberg 1109970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa); 1110970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, 1111970c4e46SJohan Hedberg u8 addr_type); 1112ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, 1113ca9142b8SJohan Hedberg u8 addr_type, u8 val[16], bdaddr_t *rpa); 1114a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type); 1115970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev); 1116970c4e46SJohan Hedberg 111755e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); 111855e76b38SJohan Hedberg 111935f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev); 11202763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev, 11216928a924SJohan Hedberg bdaddr_t *bdaddr, u8 bdaddr_type); 11220798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 11236928a924SJohan Hedberg u8 bdaddr_type, u8 *hash192, u8 *rand192, 112438da1703SJohan Hedberg u8 *hash256, u8 *rand256); 11256928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, 11266928a924SJohan Hedberg u8 bdaddr_type); 11272763eda6SSzymon Janc 1128d2609b34SFlorian Grandel void hci_adv_instances_clear(struct hci_dev *hdev); 1129d2609b34SFlorian Grandel struct adv_info *hci_find_adv_instance(struct hci_dev *hdev, u8 instance); 1130d2609b34SFlorian Grandel struct adv_info *hci_get_next_instance(struct hci_dev *hdev, u8 instance); 1131d2609b34SFlorian Grandel int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags, 1132d2609b34SFlorian Grandel u16 adv_data_len, u8 *adv_data, 1133d2609b34SFlorian Grandel u16 scan_rsp_len, u8 *scan_rsp_data, 1134d2609b34SFlorian Grandel u16 timeout, u16 duration); 1135d2609b34SFlorian Grandel int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance); 1136a73c046aSJaganath Kanakkassery void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired); 1137d2609b34SFlorian Grandel 11381da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); 11391da177e4SLinus Torvalds 11400ac7e700SDavid Herrmann void hci_init_sysfs(struct hci_dev *hdev); 1141a67e899cSMarcel Holtmann void hci_conn_init_sysfs(struct hci_conn *conn); 1142b219e3acSMarcel Holtmann void hci_conn_add_sysfs(struct hci_conn *conn); 1143b219e3acSMarcel Holtmann void hci_conn_del_sysfs(struct hci_conn *conn); 11441da177e4SLinus Torvalds 11456935e0f5SDavid Herrmann #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) 11461da177e4SLinus Torvalds 11471da177e4SLinus Torvalds /* ----- LMP capabilities ----- */ 1148cad718edSJohan Hedberg #define lmp_encrypt_capable(dev) ((dev)->features[0][0] & LMP_ENCRYPT) 1149cad718edSJohan Hedberg #define lmp_rswitch_capable(dev) ((dev)->features[0][0] & LMP_RSWITCH) 1150cad718edSJohan Hedberg #define lmp_hold_capable(dev) ((dev)->features[0][0] & LMP_HOLD) 1151cad718edSJohan Hedberg #define lmp_sniff_capable(dev) ((dev)->features[0][0] & LMP_SNIFF) 1152cad718edSJohan Hedberg #define lmp_park_capable(dev) ((dev)->features[0][1] & LMP_PARK) 1153cad718edSJohan Hedberg #define lmp_inq_rssi_capable(dev) ((dev)->features[0][3] & LMP_RSSI_INQ) 1154cad718edSJohan Hedberg #define lmp_esco_capable(dev) ((dev)->features[0][3] & LMP_ESCO) 1155cad718edSJohan Hedberg #define lmp_bredr_capable(dev) (!((dev)->features[0][4] & LMP_NO_BREDR)) 1156cad718edSJohan Hedberg #define lmp_le_capable(dev) ((dev)->features[0][4] & LMP_LE) 1157cad718edSJohan Hedberg #define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR) 1158cad718edSJohan Hedberg #define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC) 1159cad718edSJohan Hedberg #define lmp_ext_inq_capable(dev) ((dev)->features[0][6] & LMP_EXT_INQ) 1160cad718edSJohan Hedberg #define lmp_le_br_capable(dev) (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR)) 1161cad718edSJohan Hedberg #define lmp_ssp_capable(dev) ((dev)->features[0][6] & LMP_SIMPLE_PAIR) 1162cad718edSJohan Hedberg #define lmp_no_flush_capable(dev) ((dev)->features[0][6] & LMP_NO_FLUSH) 1163cad718edSJohan Hedberg #define lmp_lsto_capable(dev) ((dev)->features[0][7] & LMP_LSTO) 1164cad718edSJohan Hedberg #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR) 1165cad718edSJohan Hedberg #define lmp_ext_feat_capable(dev) ((dev)->features[0][7] & LMP_EXTFEATURES) 116607a5c61eSFrédéric Dalleau #define lmp_transp_capable(dev) ((dev)->features[0][2] & LMP_TRANSPARENT) 11675075b972SJaganath Kanakkassery #define lmp_edr_2m_capable(dev) ((dev)->features[0][3] & LMP_EDR_2M) 11685075b972SJaganath Kanakkassery #define lmp_edr_3m_capable(dev) ((dev)->features[0][3] & LMP_EDR_3M) 11695075b972SJaganath Kanakkassery #define lmp_edr_3slot_capable(dev) ((dev)->features[0][4] & LMP_EDR_3SLOT) 11705075b972SJaganath Kanakkassery #define lmp_edr_5slot_capable(dev) ((dev)->features[0][5] & LMP_EDR_5SLOT) 11711da177e4SLinus Torvalds 1172eead27daSAndre Guedes /* ----- Extended LMP capabilities ----- */ 117353b834d2SMarcel Holtmann #define lmp_csb_master_capable(dev) ((dev)->features[2][0] & LMP_CSB_MASTER) 117453b834d2SMarcel Holtmann #define lmp_csb_slave_capable(dev) ((dev)->features[2][0] & LMP_CSB_SLAVE) 117553b834d2SMarcel Holtmann #define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN) 117653b834d2SMarcel Holtmann #define lmp_sync_scan_capable(dev) ((dev)->features[2][0] & LMP_SYNC_SCAN) 1177d5991585SMarcel Holtmann #define lmp_sc_capable(dev) ((dev)->features[2][1] & LMP_SC) 1178d5991585SMarcel Holtmann #define lmp_ping_capable(dev) ((dev)->features[2][1] & LMP_PING) 117953b834d2SMarcel Holtmann 118053b834d2SMarcel Holtmann /* ----- Host capabilities ----- */ 1181cad718edSJohan Hedberg #define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP) 1182d5991585SMarcel Holtmann #define lmp_host_sc_capable(dev) ((dev)->features[1][0] & LMP_HOST_SC) 1183cad718edSJohan Hedberg #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) 1184cad718edSJohan Hedberg #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) 1185eead27daSAndre Guedes 1186d7a5a11dSMarcel Holtmann #define hdev_is_powered(dev) (test_bit(HCI_UP, &(dev)->flags) && \ 1187d7a5a11dSMarcel Holtmann !hci_dev_test_flag(dev, HCI_AUTO_OFF)) 118805b3c3e7SMarcel Holtmann #define bredr_sc_enabled(dev) (lmp_sc_capable(dev) && \ 1189d7a5a11dSMarcel Holtmann hci_dev_test_flag(dev, HCI_SC_ENABLED)) 1190432df05eSJohan Hedberg 119145bdd86eSJaganath Kanakkassery #define scan_1m(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_1M) || \ 119245bdd86eSJaganath Kanakkassery ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_1M)) 119345bdd86eSJaganath Kanakkassery 119445bdd86eSJaganath Kanakkassery #define scan_2m(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_2M) || \ 119545bdd86eSJaganath Kanakkassery ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_2M)) 119645bdd86eSJaganath Kanakkassery 119745bdd86eSJaganath Kanakkassery #define scan_coded(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_CODED) || \ 119845bdd86eSJaganath Kanakkassery ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED)) 119945bdd86eSJaganath Kanakkassery 1200a2344b9eSJaganath Kanakkassery /* Use ext scanning if set ext scan param and ext scan enable is supported */ 1201a2344b9eSJaganath Kanakkassery #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \ 1202a2344b9eSJaganath Kanakkassery ((dev)->commands[37] & 0x40)) 12034d94f95dSJaganath Kanakkassery /* Use ext create connection if command is supported */ 12044d94f95dSJaganath Kanakkassery #define use_ext_conn(dev) ((dev)->commands[37] & 0x80) 1205a2344b9eSJaganath Kanakkassery 12066b49bcb4SJaganath Kanakkassery /* Extended advertising support */ 12076b49bcb4SJaganath Kanakkassery #define ext_adv_capable(dev) (((dev)->le_features[1] & HCI_LE_EXT_ADV)) 12086b49bcb4SJaganath Kanakkassery 12091da177e4SLinus Torvalds /* ----- HCI protocols ----- */ 121020714bfeSFrédéric Dalleau #define HCI_PROTO_DEFER 0x01 121120714bfeSFrédéric Dalleau 12125a9d0a3fSWaldemar Rymarkiewicz static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, 121320714bfeSFrédéric Dalleau __u8 type, __u8 *flags) 12141da177e4SLinus Torvalds { 1215686ebf28SUlisses Furquim switch (type) { 1216686ebf28SUlisses Furquim case ACL_LINK: 1217686ebf28SUlisses Furquim return l2cap_connect_ind(hdev, bdaddr); 12181da177e4SLinus Torvalds 1219686ebf28SUlisses Furquim case SCO_LINK: 1220686ebf28SUlisses Furquim case ESCO_LINK: 122120714bfeSFrédéric Dalleau return sco_connect_ind(hdev, bdaddr, flags); 12221da177e4SLinus Torvalds 1223686ebf28SUlisses Furquim default: 1224686ebf28SUlisses Furquim BT_ERR("unknown link type %d", type); 1225686ebf28SUlisses Furquim return -EINVAL; 1226686ebf28SUlisses Furquim } 12271da177e4SLinus Torvalds } 12281da177e4SLinus Torvalds 12292950f21aSMarcel Holtmann static inline int hci_proto_disconn_ind(struct hci_conn *conn) 12302950f21aSMarcel Holtmann { 1231686ebf28SUlisses Furquim if (conn->type != ACL_LINK && conn->type != LE_LINK) 1232686ebf28SUlisses Furquim return HCI_ERROR_REMOTE_USER_TERM; 12332950f21aSMarcel Holtmann 1234686ebf28SUlisses Furquim return l2cap_disconn_ind(conn); 12352950f21aSMarcel Holtmann } 12362950f21aSMarcel Holtmann 12371da177e4SLinus Torvalds /* ----- HCI callbacks ----- */ 12381da177e4SLinus Torvalds struct hci_cb { 12391da177e4SLinus Torvalds struct list_head list; 12401da177e4SLinus Torvalds 12411da177e4SLinus Torvalds char *name; 12421da177e4SLinus Torvalds 1243539c496dSJohan Hedberg void (*connect_cfm) (struct hci_conn *conn, __u8 status); 12443a6d576bSJohan Hedberg void (*disconn_cfm) (struct hci_conn *conn, __u8 status); 12455a9d0a3fSWaldemar Rymarkiewicz void (*security_cfm) (struct hci_conn *conn, __u8 status, 12465a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt); 12471da177e4SLinus Torvalds void (*key_change_cfm) (struct hci_conn *conn, __u8 status); 12481da177e4SLinus Torvalds void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); 12491da177e4SLinus Torvalds }; 12501da177e4SLinus Torvalds 1251539c496dSJohan Hedberg static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status) 1252539c496dSJohan Hedberg { 1253539c496dSJohan Hedberg struct hci_cb *cb; 1254539c496dSJohan Hedberg 1255539c496dSJohan Hedberg mutex_lock(&hci_cb_list_lock); 1256539c496dSJohan Hedberg list_for_each_entry(cb, &hci_cb_list, list) { 1257539c496dSJohan Hedberg if (cb->connect_cfm) 1258539c496dSJohan Hedberg cb->connect_cfm(conn, status); 1259539c496dSJohan Hedberg } 1260539c496dSJohan Hedberg mutex_unlock(&hci_cb_list_lock); 1261539c496dSJohan Hedberg 1262539c496dSJohan Hedberg if (conn->connect_cfm_cb) 1263539c496dSJohan Hedberg conn->connect_cfm_cb(conn, status); 1264539c496dSJohan Hedberg } 1265539c496dSJohan Hedberg 12663a6d576bSJohan Hedberg static inline void hci_disconn_cfm(struct hci_conn *conn, __u8 reason) 12673a6d576bSJohan Hedberg { 12683a6d576bSJohan Hedberg struct hci_cb *cb; 12693a6d576bSJohan Hedberg 12703a6d576bSJohan Hedberg mutex_lock(&hci_cb_list_lock); 12713a6d576bSJohan Hedberg list_for_each_entry(cb, &hci_cb_list, list) { 12723a6d576bSJohan Hedberg if (cb->disconn_cfm) 12733a6d576bSJohan Hedberg cb->disconn_cfm(conn, reason); 12743a6d576bSJohan Hedberg } 12753a6d576bSJohan Hedberg mutex_unlock(&hci_cb_list_lock); 12763a6d576bSJohan Hedberg 12773a6d576bSJohan Hedberg if (conn->disconn_cfm_cb) 12783a6d576bSJohan Hedberg conn->disconn_cfm_cb(conn, reason); 12793a6d576bSJohan Hedberg } 12803a6d576bSJohan Hedberg 12811da177e4SLinus Torvalds static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) 12821da177e4SLinus Torvalds { 1283711584eaSDenis Kirjanov struct hci_cb *cb; 12848c1b2355SMarcel Holtmann __u8 encrypt; 12851da177e4SLinus Torvalds 128651a8efd7SJohan Hedberg if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) 12878c1b2355SMarcel Holtmann return; 12888c1b2355SMarcel Holtmann 12894dae2798SJohan Hedberg encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00; 12908c1b2355SMarcel Holtmann 1291fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 1292711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 12938c1b2355SMarcel Holtmann if (cb->security_cfm) 12948c1b2355SMarcel Holtmann cb->security_cfm(conn, status, encrypt); 12951da177e4SLinus Torvalds } 1296fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 1297354fe804SJohan Hedberg 1298354fe804SJohan Hedberg if (conn->security_cfm_cb) 1299354fe804SJohan Hedberg conn->security_cfm_cb(conn, status); 13001da177e4SLinus Torvalds } 13011da177e4SLinus Torvalds 13025a9d0a3fSWaldemar Rymarkiewicz static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, 13035a9d0a3fSWaldemar Rymarkiewicz __u8 encrypt) 13041da177e4SLinus Torvalds { 1305711584eaSDenis Kirjanov struct hci_cb *cb; 13061da177e4SLinus Torvalds 1307435fef20SMarcel Holtmann if (conn->sec_level == BT_SECURITY_SDP) 1308435fef20SMarcel Holtmann conn->sec_level = BT_SECURITY_LOW; 1309435fef20SMarcel Holtmann 131088167aedSVinicius Costa Gomes if (conn->pending_sec_level > conn->sec_level) 131188167aedSVinicius Costa Gomes conn->sec_level = conn->pending_sec_level; 131288167aedSVinicius Costa Gomes 1313fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 1314711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 13158c1b2355SMarcel Holtmann if (cb->security_cfm) 13168c1b2355SMarcel Holtmann cb->security_cfm(conn, status, encrypt); 13171da177e4SLinus Torvalds } 1318fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 1319354fe804SJohan Hedberg 1320354fe804SJohan Hedberg if (conn->security_cfm_cb) 1321354fe804SJohan Hedberg conn->security_cfm_cb(conn, status); 13221da177e4SLinus Torvalds } 13231da177e4SLinus Torvalds 13241da177e4SLinus Torvalds static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) 13251da177e4SLinus Torvalds { 1326711584eaSDenis Kirjanov struct hci_cb *cb; 13271da177e4SLinus Torvalds 1328fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 1329711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 13301da177e4SLinus Torvalds if (cb->key_change_cfm) 13311da177e4SLinus Torvalds cb->key_change_cfm(conn, status); 13321da177e4SLinus Torvalds } 1333fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 13341da177e4SLinus Torvalds } 13351da177e4SLinus Torvalds 13365a9d0a3fSWaldemar Rymarkiewicz static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, 13375a9d0a3fSWaldemar Rymarkiewicz __u8 role) 13381da177e4SLinus Torvalds { 1339711584eaSDenis Kirjanov struct hci_cb *cb; 13401da177e4SLinus Torvalds 1341fba7ecf0SJohan Hedberg mutex_lock(&hci_cb_list_lock); 1342711584eaSDenis Kirjanov list_for_each_entry(cb, &hci_cb_list, list) { 13431da177e4SLinus Torvalds if (cb->role_switch_cfm) 13441da177e4SLinus Torvalds cb->role_switch_cfm(conn, status, role); 13451da177e4SLinus Torvalds } 1346fba7ecf0SJohan Hedberg mutex_unlock(&hci_cb_list_lock); 13471da177e4SLinus Torvalds } 13481da177e4SLinus Torvalds 13490d3b7f64SJohan Hedberg static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type, 13500d3b7f64SJohan Hedberg size_t *data_len) 13516759a675SJohan Hedberg { 135284d9d071SJohan Hedberg size_t parsed = 0; 13536759a675SJohan Hedberg 13540d3b7f64SJohan Hedberg if (eir_len < 2) 13550d3b7f64SJohan Hedberg return NULL; 13566c0c331eSJohan Hedberg 13570d3b7f64SJohan Hedberg while (parsed < eir_len - 1) { 13580d3b7f64SJohan Hedberg u8 field_len = eir[0]; 13596759a675SJohan Hedberg 13606759a675SJohan Hedberg if (field_len == 0) 13616759a675SJohan Hedberg break; 13626759a675SJohan Hedberg 13636759a675SJohan Hedberg parsed += field_len + 1; 13646759a675SJohan Hedberg 13650d3b7f64SJohan Hedberg if (parsed > eir_len) 13666759a675SJohan Hedberg break; 13676759a675SJohan Hedberg 13680d3b7f64SJohan Hedberg if (eir[1] != type) { 13690d3b7f64SJohan Hedberg eir += field_len + 1; 13700d3b7f64SJohan Hedberg continue; 13716759a675SJohan Hedberg } 13726759a675SJohan Hedberg 13730d3b7f64SJohan Hedberg /* Zero length data */ 13740d3b7f64SJohan Hedberg if (field_len == 1) 13750d3b7f64SJohan Hedberg return NULL; 13760d3b7f64SJohan Hedberg 13770d3b7f64SJohan Hedberg if (data_len) 13780d3b7f64SJohan Hedberg *data_len = field_len - 1; 13790d3b7f64SJohan Hedberg 13800d3b7f64SJohan Hedberg return &eir[2]; 13810d3b7f64SJohan Hedberg } 13820d3b7f64SJohan Hedberg 13830d3b7f64SJohan Hedberg return NULL; 13846759a675SJohan Hedberg } 13856759a675SJohan Hedberg 1386301cb2d8SJohan Hedberg static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type) 1387301cb2d8SJohan Hedberg { 1388dbbfa2abSAndre Guedes if (addr_type != ADDR_LE_DEV_RANDOM) 1389301cb2d8SJohan Hedberg return false; 1390301cb2d8SJohan Hedberg 1391301cb2d8SJohan Hedberg if ((bdaddr->b[5] & 0xc0) == 0x40) 1392301cb2d8SJohan Hedberg return true; 1393301cb2d8SJohan Hedberg 1394301cb2d8SJohan Hedberg return false; 1395301cb2d8SJohan Hedberg } 1396301cb2d8SJohan Hedberg 1397c46245b3SJohan Hedberg static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type) 1398c46245b3SJohan Hedberg { 1399c46245b3SJohan Hedberg if (addr_type == ADDR_LE_DEV_PUBLIC) 1400c46245b3SJohan Hedberg return true; 1401c46245b3SJohan Hedberg 1402c46245b3SJohan Hedberg /* Check for Random Static address type */ 1403c46245b3SJohan Hedberg if ((addr->b[5] & 0xc0) == 0xc0) 1404c46245b3SJohan Hedberg return true; 1405c46245b3SJohan Hedberg 1406c46245b3SJohan Hedberg return false; 1407c46245b3SJohan Hedberg } 1408c46245b3SJohan Hedberg 14092426f3a5SJohan Hedberg static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev, 14102426f3a5SJohan Hedberg bdaddr_t *bdaddr, u8 addr_type) 14112426f3a5SJohan Hedberg { 14122426f3a5SJohan Hedberg if (!hci_bdaddr_is_rpa(bdaddr, addr_type)) 14132426f3a5SJohan Hedberg return NULL; 14142426f3a5SJohan Hedberg 14152426f3a5SJohan Hedberg return hci_find_irk_by_rpa(hdev, bdaddr); 14162426f3a5SJohan Hedberg } 14172426f3a5SJohan Hedberg 1418d4905f24SAndre Guedes static inline int hci_check_conn_params(u16 min, u16 max, u16 latency, 1419d4905f24SAndre Guedes u16 to_multiplier) 1420d4905f24SAndre Guedes { 1421d4905f24SAndre Guedes u16 max_latency; 1422d4905f24SAndre Guedes 1423d4905f24SAndre Guedes if (min > max || min < 6 || max > 3200) 1424d4905f24SAndre Guedes return -EINVAL; 1425d4905f24SAndre Guedes 1426d4905f24SAndre Guedes if (to_multiplier < 10 || to_multiplier > 3200) 1427d4905f24SAndre Guedes return -EINVAL; 1428d4905f24SAndre Guedes 1429d4905f24SAndre Guedes if (max >= to_multiplier * 8) 1430d4905f24SAndre Guedes return -EINVAL; 1431d4905f24SAndre Guedes 14328757825bSSeungyoun Ju max_latency = (to_multiplier * 4 / max) - 1; 1433d4905f24SAndre Guedes if (latency > 499 || latency > max_latency) 1434d4905f24SAndre Guedes return -EINVAL; 1435d4905f24SAndre Guedes 1436d4905f24SAndre Guedes return 0; 1437d4905f24SAndre Guedes } 1438d4905f24SAndre Guedes 14391da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *hcb); 14401da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *hcb); 14411da177e4SLinus Torvalds 144275e84b7cSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 144307dc93ddSJohan Hedberg const void *param, u32 timeout); 14447b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, 144507dc93ddSJohan Hedberg const void *param, u8 event, u32 timeout); 1446d6ee6ad7SLoic Poulain int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen, 1447d6ee6ad7SLoic Poulain const void *param); 144875e84b7cSJohan Hedberg 144907dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, 145007dc93ddSJohan Hedberg const void *param); 145173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); 14520d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); 14531da177e4SLinus Torvalds 1454a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); 14551da177e4SLinus Torvalds 1456fbef168fSLoic Poulain struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, 1457fbef168fSLoic Poulain const void *param, u32 timeout); 1458fbef168fSLoic Poulain 14591da177e4SLinus Torvalds /* ----- HCI Sockets ----- */ 1460470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); 14617129069eSJohan Hedberg void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, 1462c08b1a1dSMarcel Holtmann int flag, struct sock *skip_sk); 1463cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb); 146438ceaa00SMarcel Holtmann void hci_send_monitor_ctrl_event(struct hci_dev *hdev, u16 event, 146538ceaa00SMarcel Holtmann void *data, u16 data_len, ktime_t tstamp, 146638ceaa00SMarcel Holtmann int flag, struct sock *skip_sk); 14671da177e4SLinus Torvalds 1468040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event); 1469040030efSMarcel Holtmann 1470a958452aSMarcel Holtmann #define HCI_MGMT_VAR_LEN BIT(0) 1471a958452aSMarcel Holtmann #define HCI_MGMT_NO_HDEV BIT(1) 1472a958452aSMarcel Holtmann #define HCI_MGMT_UNTRUSTED BIT(2) 1473a958452aSMarcel Holtmann #define HCI_MGMT_UNCONFIGURED BIT(3) 1474b9a245fbSJohan Hedberg 1475801c1e8dSJohan Hedberg struct hci_mgmt_handler { 1476801c1e8dSJohan Hedberg int (*func) (struct sock *sk, struct hci_dev *hdev, void *data, 1477801c1e8dSJohan Hedberg u16 data_len); 1478801c1e8dSJohan Hedberg size_t data_len; 1479b9a245fbSJohan Hedberg unsigned long flags; 1480801c1e8dSJohan Hedberg }; 1481801c1e8dSJohan Hedberg 1482801c1e8dSJohan Hedberg struct hci_mgmt_chan { 1483801c1e8dSJohan Hedberg struct list_head list; 1484801c1e8dSJohan Hedberg unsigned short channel; 1485801c1e8dSJohan Hedberg size_t handler_count; 1486801c1e8dSJohan Hedberg const struct hci_mgmt_handler *handlers; 148788b94ce9SJohan Hedberg void (*hdev_init) (struct sock *sk, struct hci_dev *hdev); 1488801c1e8dSJohan Hedberg }; 1489801c1e8dSJohan Hedberg 1490801c1e8dSJohan Hedberg int hci_mgmt_chan_register(struct hci_mgmt_chan *c); 1491801c1e8dSJohan Hedberg void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c); 1492801c1e8dSJohan Hedberg 14930381101fSJohan Hedberg /* Management interface */ 1494591f47f3SAndre Guedes #define DISCOV_TYPE_BREDR (BIT(BDADDR_BREDR)) 1495591f47f3SAndre Guedes #define DISCOV_TYPE_LE (BIT(BDADDR_LE_PUBLIC) | \ 1496591f47f3SAndre Guedes BIT(BDADDR_LE_RANDOM)) 1497591f47f3SAndre Guedes #define DISCOV_TYPE_INTERLEAVED (BIT(BDADDR_BREDR) | \ 1498591f47f3SAndre Guedes BIT(BDADDR_LE_PUBLIC) | \ 1499591f47f3SAndre Guedes BIT(BDADDR_LE_RANDOM)) 1500f39799f5SAndre Guedes 15010d8cc935SAndre Guedes /* These LE scan and inquiry parameters were chosen according to LE General 15020d8cc935SAndre Guedes * Discovery Procedure specification. 15030d8cc935SAndre Guedes */ 15040d8cc935SAndre Guedes #define DISCOV_LE_SCAN_WIN 0x12 15050d8cc935SAndre Guedes #define DISCOV_LE_SCAN_INT 0x12 15063d5a76f0SLukasz Rymanowski #define DISCOV_LE_TIMEOUT 10240 /* msec */ 1507ae55f598SLukasz Rymanowski #define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */ 15080d8cc935SAndre Guedes #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 15090d8cc935SAndre Guedes #define DISCOV_BREDR_INQUIRY_LEN 0x08 15104b0e0cedSJakub Pawlowski #define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */ 15110d8cc935SAndre Guedes 151203c979c4SMarcel Holtmann void mgmt_fill_version_info(void *ver); 151391a668b0SJohan Hedberg int mgmt_new_settings(struct hci_dev *hdev); 1514bf6b56dbSMarcel Holtmann void mgmt_index_added(struct hci_dev *hdev); 1515bf6b56dbSMarcel Holtmann void mgmt_index_removed(struct hci_dev *hdev); 15163eec705eSMarcel Holtmann void mgmt_set_powered_failed(struct hci_dev *hdev, int err); 15172ff13894SJohan Hedberg void mgmt_power_on(struct hci_dev *hdev, int err); 15182ff13894SJohan Hedberg void __mgmt_power_off(struct hci_dev *hdev); 1519dc4a5ee2SMarcel Holtmann void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, 1520745c0ce3SVishal Agarwal bool persistent); 152148ec92faSAlfonso Acosta void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, 152248ec92faSAlfonso Acosta u32 flags, u8 *name, u8 name_len); 15239b80ec5eSMarcel Holtmann void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, 152412d4a3b2SJohan Hedberg u8 link_type, u8 addr_type, u8 reason, 152512d4a3b2SJohan Hedberg bool mgmt_connected); 15267892924cSMarcel Holtmann void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, 152788c3df13SJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1528445608d0SMarcel Holtmann void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 152948264f06SJohan Hedberg u8 addr_type, u8 status); 1530ce0e4a0dSMarcel Holtmann void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure); 1531e669cf80SMarcel Holtmann void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1532c35938b2SSzymon Janc u8 status); 15333eb38528SMarcel Holtmann void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1534744cf19eSJohan Hedberg u8 status); 1535744cf19eSJohan Hedberg int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 153639adbffeSJohan Hedberg u8 link_type, u8 addr_type, u32 value, 1537272d90dfSJohan Hedberg u8 confirm_hint); 1538744cf19eSJohan Hedberg int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1539272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1540272d90dfSJohan Hedberg int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1541272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1542272d90dfSJohan Hedberg int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, 1543272d90dfSJohan Hedberg u8 link_type, u8 addr_type); 1544604086b7SBrian Gix int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1545272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 1546272d90dfSJohan Hedberg int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, 1547272d90dfSJohan Hedberg u8 link_type, u8 addr_type, u8 status); 154892a25256SJohan Hedberg int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, 154992a25256SJohan Hedberg u8 link_type, u8 addr_type, u32 passkey, 155092a25256SJohan Hedberg u8 entered); 1551e1e930f5SJohan Hedberg void mgmt_auth_failed(struct hci_conn *conn, u8 status); 1552464996aeSMarcel Holtmann void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); 15533e248560SMarcel Holtmann void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); 15544e1b0245SMarcel Holtmann void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, 15557f9a903cSMarcel Holtmann u8 status); 15567667da34SMarcel Holtmann void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status); 1557e68f072bSJohan Hedberg void mgmt_start_discovery_complete(struct hci_dev *hdev, u8 status); 15582154d3f4SJohan Hedberg void mgmt_stop_discovery_complete(struct hci_dev *hdev, u8 status); 1559901801b9SMarcel Holtmann void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1560af58925cSMarcel Holtmann u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, 1561af58925cSMarcel Holtmann u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len); 15629cf12aeeSMarcel Holtmann void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, 1563b644ba33SJohan Hedberg u8 addr_type, s8 rssi, u8 *name, u8 name_len); 15642f1e063bSMarcel Holtmann void mgmt_discovering(struct hci_dev *hdev, u8 discovering); 156584c61d92SJohan Hedberg bool mgmt_powering_down(struct hci_dev *hdev); 156653ac6ab6SMarcel Holtmann void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); 1567cad20c27SJohan Hedberg void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent); 156853ac6ab6SMarcel Holtmann void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, 156953ac6ab6SMarcel Holtmann bool persistent); 1570ffb5a827SAndre Guedes void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr, 1571f4869e2aSJohan Hedberg u8 bdaddr_type, u8 store_hint, u16 min_interval, 1572f4869e2aSJohan Hedberg u16 max_interval, u16 latency, u16 timeout); 1573f4a407beSJohan Hedberg void mgmt_smp_complete(struct hci_conn *conn, bool complete); 1574f2252570SJohan Hedberg bool mgmt_get_connectable(struct hci_dev *hdev); 157553c0ba74SJohan Hedberg void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status); 1576aed1a885SJohan Hedberg void mgmt_set_discoverable_complete(struct hci_dev *hdev, u8 status); 1577f2252570SJohan Hedberg u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev); 1578f2252570SJohan Hedberg void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev, 1579f2252570SJohan Hedberg u8 instance); 1580f2252570SJohan Hedberg void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev, 1581f2252570SJohan Hedberg u8 instance); 1582b7c23df8SJaganath Kanakkassery int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip); 1583346af67bSVinicius Costa Gomes 15847d6ca693SJohan Hedberg u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, 15857d6ca693SJohan Hedberg u16 to_multiplier); 1586fe39c7b2SMarcel Holtmann void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand, 15878b76ce34SJohan Hedberg __u8 ltk[16], __u8 key_size); 15882519a1fcSAndre Guedes 1589a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr, 1590a1f4c318SJohan Hedberg u8 *bdaddr_type); 1591ebd3a747SJohan Hedberg 15925d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_MASK 0x0003 15935d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_CVSD 0x0000 15945d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_TRANSP 0x0003 15955d4d62f6SFrédéric Dalleau 15961da177e4SLinus Torvalds #endif /* __HCI_CORE_H */ 1597