xref: /openbmc/linux/include/net/bluetooth/hci_core.h (revision 30d65e08)
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