xref: /openbmc/linux/include/net/bluetooth/hci_core.h (revision ff50e8af)
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 
281da177e4SLinus Torvalds #include <net/bluetooth/hci.h>
29f49daa81SMarcel Holtmann #include <net/bluetooth/hci_sock.h>
301da177e4SLinus Torvalds 
315e59b791SLuiz Augusto von Dentz /* HCI priority */
325e59b791SLuiz Augusto von Dentz #define HCI_PRIO_MAX	7
335e59b791SLuiz Augusto von Dentz 
341da177e4SLinus Torvalds /* HCI Core structures */
351da177e4SLinus Torvalds struct inquiry_data {
361da177e4SLinus Torvalds 	bdaddr_t	bdaddr;
371da177e4SLinus Torvalds 	__u8		pscan_rep_mode;
381da177e4SLinus Torvalds 	__u8		pscan_period_mode;
391da177e4SLinus Torvalds 	__u8		pscan_mode;
401da177e4SLinus Torvalds 	__u8		dev_class[3];
411ebb9252SMarcel Holtmann 	__le16		clock_offset;
421da177e4SLinus Torvalds 	__s8		rssi;
4341a96212SMarcel Holtmann 	__u8		ssp_mode;
441da177e4SLinus Torvalds };
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds struct inquiry_entry {
47561aafbcSJohan Hedberg 	struct list_head	all;		/* inq_cache.all */
48561aafbcSJohan Hedberg 	struct list_head	list;		/* unknown or resolve */
49561aafbcSJohan Hedberg 	enum {
50561aafbcSJohan Hedberg 		NAME_NOT_KNOWN,
51561aafbcSJohan Hedberg 		NAME_NEEDED,
52561aafbcSJohan Hedberg 		NAME_PENDING,
53561aafbcSJohan Hedberg 		NAME_KNOWN,
54561aafbcSJohan Hedberg 	} name_state;
551da177e4SLinus Torvalds 	__u32			timestamp;
561da177e4SLinus Torvalds 	struct inquiry_data	data;
571da177e4SLinus Torvalds };
581da177e4SLinus Torvalds 
5930883512SJohan Hedberg struct discovery_state {
604aab14e5SAndre Guedes 	int			type;
61ff9ef578SJohan Hedberg 	enum {
62ff9ef578SJohan Hedberg 		DISCOVERY_STOPPED,
63ff9ef578SJohan Hedberg 		DISCOVERY_STARTING,
64343f935bSAndre Guedes 		DISCOVERY_FINDING,
6530dc78e1SJohan Hedberg 		DISCOVERY_RESOLVING,
66ff9ef578SJohan Hedberg 		DISCOVERY_STOPPING,
67ff9ef578SJohan Hedberg 	} state;
68561aafbcSJohan Hedberg 	struct list_head	all;	/* All devices found during inquiry */
69561aafbcSJohan Hedberg 	struct list_head	unknown;	/* Name state not known */
70561aafbcSJohan Hedberg 	struct list_head	resolve;	/* Name needs to be resolved */
711da177e4SLinus Torvalds 	__u32			timestamp;
72b9a6328fSJohan Hedberg 	bdaddr_t		last_adv_addr;
73b9a6328fSJohan Hedberg 	u8			last_adv_addr_type;
74ff5cd29fSJohan Hedberg 	s8			last_adv_rssi;
75c70a7e4cSMarcel Holtmann 	u32			last_adv_flags;
76b9a6328fSJohan Hedberg 	u8			last_adv_data[HCI_MAX_AD_LENGTH];
77b9a6328fSJohan Hedberg 	u8			last_adv_data_len;
78da25cf6aSMarcel Holtmann 	bool			report_invalid_rssi;
7982f8b651SJakub Pawlowski 	bool			result_filtering;
8037eab042SJakub Pawlowski 	s8			rssi;
8137eab042SJakub Pawlowski 	u16			uuid_count;
8237eab042SJakub Pawlowski 	u8			(*uuids)[16];
832d28cfe7SJakub Pawlowski 	unsigned long		scan_start;
842d28cfe7SJakub Pawlowski 	unsigned long		scan_duration;
851da177e4SLinus Torvalds };
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds struct hci_conn_hash {
881da177e4SLinus Torvalds 	struct list_head list;
891da177e4SLinus Torvalds 	unsigned int     acl_num;
90bd1eb66bSAndrei Emeltchenko 	unsigned int     amp_num;
911da177e4SLinus Torvalds 	unsigned int     sco_num;
92fcd89c09SVille Tervo 	unsigned int     le_num;
93f8218dc6SJohan Hedberg 	unsigned int     le_num_slave;
941da177e4SLinus Torvalds };
951da177e4SLinus Torvalds 
96f0358568SJohan Hedberg struct bdaddr_list {
97f0358568SJohan Hedberg 	struct list_head list;
98f0358568SJohan Hedberg 	bdaddr_t bdaddr;
99b9ee0a78SMarcel Holtmann 	u8 bdaddr_type;
100f0358568SJohan Hedberg };
1012aeb9a1aSJohan Hedberg 
1022aeb9a1aSJohan Hedberg struct bt_uuid {
1032aeb9a1aSJohan Hedberg 	struct list_head list;
1042aeb9a1aSJohan Hedberg 	u8 uuid[16];
10583be8ecaSJohan Hedberg 	u8 size;
1061aff6f09SJohan Hedberg 	u8 svc_hint;
1072aeb9a1aSJohan Hedberg };
1082aeb9a1aSJohan Hedberg 
1097ee4ea36SMarcel Holtmann struct smp_csrk {
1107ee4ea36SMarcel Holtmann 	bdaddr_t bdaddr;
1117ee4ea36SMarcel Holtmann 	u8 bdaddr_type;
1124cd3928aSJohan Hedberg 	u8 type;
1137ee4ea36SMarcel Holtmann 	u8 val[16];
1147ee4ea36SMarcel Holtmann };
1157ee4ea36SMarcel Holtmann 
116b899efafSVinicius Costa Gomes struct smp_ltk {
117b899efafSVinicius Costa Gomes 	struct list_head list;
118970d0f1bSJohan Hedberg 	struct rcu_head rcu;
119b899efafSVinicius Costa Gomes 	bdaddr_t bdaddr;
120b899efafSVinicius Costa Gomes 	u8 bdaddr_type;
121b899efafSVinicius Costa Gomes 	u8 authenticated;
122b899efafSVinicius Costa Gomes 	u8 type;
123b899efafSVinicius Costa Gomes 	u8 enc_size;
124b899efafSVinicius Costa Gomes 	__le16 ediv;
125fe39c7b2SMarcel Holtmann 	__le64 rand;
126b899efafSVinicius Costa Gomes 	u8 val[16];
12703c515d7SMarcel Holtmann };
128b899efafSVinicius Costa Gomes 
129970c4e46SJohan Hedberg struct smp_irk {
130970c4e46SJohan Hedberg 	struct list_head list;
131adae20cbSJohan Hedberg 	struct rcu_head rcu;
132970c4e46SJohan Hedberg 	bdaddr_t rpa;
133970c4e46SJohan Hedberg 	bdaddr_t bdaddr;
134970c4e46SJohan Hedberg 	u8 addr_type;
135970c4e46SJohan Hedberg 	u8 val[16];
136970c4e46SJohan Hedberg };
137970c4e46SJohan Hedberg 
13855ed8ca1SJohan Hedberg struct link_key {
13955ed8ca1SJohan Hedberg 	struct list_head list;
1400378b597SJohan Hedberg 	struct rcu_head rcu;
14155ed8ca1SJohan Hedberg 	bdaddr_t bdaddr;
14255ed8ca1SJohan Hedberg 	u8 type;
1439b3b4460SAndrei Emeltchenko 	u8 val[HCI_LINK_KEY_SIZE];
14455ed8ca1SJohan Hedberg 	u8 pin_len;
14555ed8ca1SJohan Hedberg };
14655ed8ca1SJohan Hedberg 
1472763eda6SSzymon Janc struct oob_data {
1482763eda6SSzymon Janc 	struct list_head list;
1492763eda6SSzymon Janc 	bdaddr_t bdaddr;
1506928a924SJohan Hedberg 	u8 bdaddr_type;
151f7697b16SMarcel Holtmann 	u8 present;
152519ca9d0SMarcel Holtmann 	u8 hash192[16];
15338da1703SJohan Hedberg 	u8 rand192[16];
154519ca9d0SMarcel Holtmann 	u8 hash256[16];
15538da1703SJohan Hedberg 	u8 rand256[16];
1562763eda6SSzymon Janc };
1572763eda6SSzymon Janc 
158203fea01SArman Uguray struct adv_info {
159912098a6SArman Uguray 	struct delayed_work timeout_exp;
160203fea01SArman Uguray 	__u8	instance;
161203fea01SArman Uguray 	__u32	flags;
162912098a6SArman Uguray 	__u16	timeout;
163203fea01SArman Uguray 	__u16	adv_data_len;
164203fea01SArman Uguray 	__u8	adv_data[HCI_MAX_AD_LENGTH];
165203fea01SArman Uguray 	__u16	scan_rsp_len;
166203fea01SArman Uguray 	__u8	scan_rsp_data[HCI_MAX_AD_LENGTH];
167203fea01SArman Uguray };
168203fea01SArman Uguray 
169490c5babSJohan Hedberg #define HCI_MAX_SHORT_NAME_LENGTH	10
170490c5babSJohan Hedberg 
171d6bfd59cSJohan Hedberg /* Default LE RPA expiry time, 15 minutes */
172d6bfd59cSJohan Hedberg #define HCI_DEFAULT_RPA_TIMEOUT		(15 * 60)
173d6bfd59cSJohan Hedberg 
17431ad1691SAndrzej Kaczmarek /* Default min/max age of connection information (1s/3s) */
17531ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MIN_AGE	1000
17631ad1691SAndrzej Kaczmarek #define DEFAULT_CONN_INFO_MAX_AGE	3000
17731ad1691SAndrzej Kaczmarek 
178903e4541SAndrei Emeltchenko struct amp_assoc {
179903e4541SAndrei Emeltchenko 	__u16	len;
180903e4541SAndrei Emeltchenko 	__u16	offset;
18193c284eeSAndrei Emeltchenko 	__u16	rem_len;
18293c284eeSAndrei Emeltchenko 	__u16	len_so_far;
183903e4541SAndrei Emeltchenko 	__u8	data[HCI_MAX_AMP_ASSOC_SIZE];
184903e4541SAndrei Emeltchenko };
185903e4541SAndrei Emeltchenko 
186d2c5d77fSJohan Hedberg #define HCI_MAX_PAGES	3
187cad718edSJohan Hedberg 
1881da177e4SLinus Torvalds struct hci_dev {
1891da177e4SLinus Torvalds 	struct list_head list;
19009fd0de5SGustavo F. Padovan 	struct mutex	lock;
1911da177e4SLinus Torvalds 
1921da177e4SLinus Torvalds 	char		name[8];
1931da177e4SLinus Torvalds 	unsigned long	flags;
1941da177e4SLinus Torvalds 	__u16		id;
195c13854ceSMarcel Holtmann 	__u8		bus;
196943da25dSMarcel Holtmann 	__u8		dev_type;
1971da177e4SLinus Torvalds 	bdaddr_t	bdaddr;
198e30d3f5fSMarcel Holtmann 	bdaddr_t	setup_addr;
19924c457e2SMarcel Holtmann 	bdaddr_t	public_addr;
2007a4cd51dSMarcel Holtmann 	bdaddr_t	random_addr;
201d13eafceSMarcel Holtmann 	bdaddr_t	static_addr;
20256ed2cb8SJohan Hedberg 	__u8		adv_addr_type;
2031f6c6378SJohan Hedberg 	__u8		dev_name[HCI_MAX_NAME_LENGTH];
204490c5babSJohan Hedberg 	__u8		short_name[HCI_MAX_SHORT_NAME_LENGTH];
20580a1e1dbSJohan Hedberg 	__u8		eir[HCI_MAX_EIR_LENGTH];
206a9de9248SMarcel Holtmann 	__u8		dev_class[3];
2071aff6f09SJohan Hedberg 	__u8		major_class;
2081aff6f09SJohan Hedberg 	__u8		minor_class;
209d2c5d77fSJohan Hedberg 	__u8		max_page;
210cad718edSJohan Hedberg 	__u8		features[HCI_MAX_PAGES][8];
21160e77321SJohan Hedberg 	__u8		le_features[8];
212cf1d081fSJohan Hedberg 	__u8		le_white_list_size;
2139b008c04SJohan Hedberg 	__u8		le_states[8];
214a9de9248SMarcel Holtmann 	__u8		commands[64];
2151143e5a6SMarcel Holtmann 	__u8		hci_ver;
2161143e5a6SMarcel Holtmann 	__u16		hci_rev;
217d5859e22SJohan Hedberg 	__u8		lmp_ver;
2181143e5a6SMarcel Holtmann 	__u16		manufacturer;
2197d69230cSAndrei Emeltchenko 	__u16		lmp_subver;
2201da177e4SLinus Torvalds 	__u16		voice_setting;
221b4cb9fb2SMarcel Holtmann 	__u8		num_iac;
222c2f0f979SMarcel Holtmann 	__u8		stored_max_keys;
223c2f0f979SMarcel Holtmann 	__u8		stored_num_keys;
22417fa4b9dSJohan Hedberg 	__u8		io_capability;
22591c4e9b1SMarcel Holtmann 	__s8		inq_tx_power;
226f332ec66SJohan Hedberg 	__u16		page_scan_interval;
227f332ec66SJohan Hedberg 	__u16		page_scan_window;
228f332ec66SJohan Hedberg 	__u8		page_scan_type;
2293f959d46SMarcel Holtmann 	__u8		le_adv_channel_map;
230628531c9SGeorg Lukas 	__u16		le_adv_min_interval;
231628531c9SGeorg Lukas 	__u16		le_adv_max_interval;
232533553f8SMarcel Holtmann 	__u8		le_scan_type;
233bef64738SMarcel Holtmann 	__u16		le_scan_interval;
234bef64738SMarcel Holtmann 	__u16		le_scan_window;
2354e70c7e7SMarcel Holtmann 	__u16		le_conn_min_interval;
2364e70c7e7SMarcel Holtmann 	__u16		le_conn_max_interval;
23704fb7d90SMarcel Holtmann 	__u16		le_conn_latency;
23804fb7d90SMarcel Holtmann 	__u16		le_supv_timeout;
239a8e1bfaaSMarcel Holtmann 	__u16		le_def_tx_len;
240a8e1bfaaSMarcel Holtmann 	__u16		le_def_tx_time;
241a8e1bfaaSMarcel Holtmann 	__u16		le_max_tx_len;
242a8e1bfaaSMarcel Holtmann 	__u16		le_max_tx_time;
243a8e1bfaaSMarcel Holtmann 	__u16		le_max_rx_len;
244a8e1bfaaSMarcel Holtmann 	__u16		le_max_rx_time;
245b9a7a61eSLukasz Rymanowski 	__u16		discov_interleaved_timeout;
24631ad1691SAndrzej Kaczmarek 	__u16		conn_info_min_age;
24731ad1691SAndrzej Kaczmarek 	__u16		conn_info_max_age;
24806f5b778SMarcel Holtmann 	__u8		ssp_debug_mode;
249c7741d16SMarcel Holtmann 	__u8		hw_error_code;
25033f35721SJohan Hedberg 	__u32		clock;
251f332ec66SJohan Hedberg 
2522b9be137SMarcel Holtmann 	__u16		devid_source;
2532b9be137SMarcel Holtmann 	__u16		devid_vendor;
2542b9be137SMarcel Holtmann 	__u16		devid_product;
2552b9be137SMarcel Holtmann 	__u16		devid_version;
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 	__u16		pkt_type;
2585b7f9909SMarcel Holtmann 	__u16		esco_type;
2591da177e4SLinus Torvalds 	__u16		link_policy;
2601da177e4SLinus Torvalds 	__u16		link_mode;
2611da177e4SLinus Torvalds 
26204837f64SMarcel Holtmann 	__u32		idle_timeout;
26304837f64SMarcel Holtmann 	__u16		sniff_min_interval;
26404837f64SMarcel Holtmann 	__u16		sniff_max_interval;
26504837f64SMarcel Holtmann 
266928abaa7SAndrei Emeltchenko 	__u8		amp_status;
267928abaa7SAndrei Emeltchenko 	__u32		amp_total_bw;
268928abaa7SAndrei Emeltchenko 	__u32		amp_max_bw;
269928abaa7SAndrei Emeltchenko 	__u32		amp_min_latency;
270928abaa7SAndrei Emeltchenko 	__u32		amp_max_pdu;
271928abaa7SAndrei Emeltchenko 	__u8		amp_type;
272928abaa7SAndrei Emeltchenko 	__u16		amp_pal_cap;
273928abaa7SAndrei Emeltchenko 	__u16		amp_assoc_size;
274928abaa7SAndrei Emeltchenko 	__u32		amp_max_flush_to;
275928abaa7SAndrei Emeltchenko 	__u32		amp_be_flush_to;
276928abaa7SAndrei Emeltchenko 
277903e4541SAndrei Emeltchenko 	struct amp_assoc	loc_assoc;
278903e4541SAndrei Emeltchenko 
2791e89cffbSAndrei Emeltchenko 	__u8		flow_ctl_mode;
2801e89cffbSAndrei Emeltchenko 
2819f61656aSJohan Hedberg 	unsigned int	auto_accept_delay;
2829f61656aSJohan Hedberg 
2831da177e4SLinus Torvalds 	unsigned long	quirks;
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds 	atomic_t	cmd_cnt;
2861da177e4SLinus Torvalds 	unsigned int	acl_cnt;
2871da177e4SLinus Torvalds 	unsigned int	sco_cnt;
2886ed58ec5SVille Tervo 	unsigned int	le_cnt;
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds 	unsigned int	acl_mtu;
2911da177e4SLinus Torvalds 	unsigned int	sco_mtu;
2926ed58ec5SVille Tervo 	unsigned int	le_mtu;
2931da177e4SLinus Torvalds 	unsigned int	acl_pkts;
2941da177e4SLinus Torvalds 	unsigned int	sco_pkts;
2956ed58ec5SVille Tervo 	unsigned int	le_pkts;
2961da177e4SLinus Torvalds 
297350ee4cfSAndrei Emeltchenko 	__u16		block_len;
298350ee4cfSAndrei Emeltchenko 	__u16		block_mtu;
299350ee4cfSAndrei Emeltchenko 	__u16		num_blocks;
300350ee4cfSAndrei Emeltchenko 	__u16		block_cnt;
301350ee4cfSAndrei Emeltchenko 
3021da177e4SLinus Torvalds 	unsigned long	acl_last_tx;
3031da177e4SLinus Torvalds 	unsigned long	sco_last_tx;
3046ed58ec5SVille Tervo 	unsigned long	le_last_tx;
3051da177e4SLinus Torvalds 
306f48fd9c8SMarcel Holtmann 	struct workqueue_struct	*workqueue;
3076ead1bbcSJohan Hedberg 	struct workqueue_struct	*req_workqueue;
308f48fd9c8SMarcel Holtmann 
309ab81cbf9SJohan Hedberg 	struct work_struct	power_on;
3103243553fSJohan Hedberg 	struct delayed_work	power_off;
311c7741d16SMarcel Holtmann 	struct work_struct	error_reset;
312ab81cbf9SJohan Hedberg 
31316ab91abSJohan Hedberg 	__u16			discov_timeout;
31416ab91abSJohan Hedberg 	struct delayed_work	discov_off;
31516ab91abSJohan Hedberg 
3167d78525dSJohan Hedberg 	struct delayed_work	service_cache;
3177d78525dSJohan Hedberg 
31865cc2b49SMarcel Holtmann 	struct delayed_work	cmd_timer;
319b78752ccSMarcel Holtmann 
320b78752ccSMarcel Holtmann 	struct work_struct	rx_work;
321c347b765SGustavo F. Padovan 	struct work_struct	cmd_work;
3223eff45eaSGustavo F. Padovan 	struct work_struct	tx_work;
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds 	struct sk_buff_head	rx_q;
3251da177e4SLinus Torvalds 	struct sk_buff_head	raw_q;
3261da177e4SLinus Torvalds 	struct sk_buff_head	cmd_q;
3271da177e4SLinus Torvalds 
3281da177e4SLinus Torvalds 	struct sk_buff		*sent_cmd;
3291da177e4SLinus Torvalds 
330a6a67efdSThomas Gleixner 	struct mutex		req_lock;
3311da177e4SLinus Torvalds 	wait_queue_head_t	req_wait_q;
3321da177e4SLinus Torvalds 	__u32			req_status;
3331da177e4SLinus Torvalds 	__u32			req_result;
334f60cb305SJohan Hedberg 	struct sk_buff		*req_skb;
335a5040efaSJohan Hedberg 
33670db83c4SJohan Hedberg 	void			*smp_data;
337ef8efe4bSJohan Hedberg 	void			*smp_bredr_data;
3382e58ef3eSJohan Hedberg 
33930883512SJohan Hedberg 	struct discovery_state	discovery;
3401da177e4SLinus Torvalds 	struct hci_conn_hash	conn_hash;
3415c136e90SAndre Guedes 
3425c136e90SAndre Guedes 	struct list_head	mgmt_pending;
343ea4bd8baSDavid Miller 	struct list_head	blacklist;
3446659358eSJohan Hedberg 	struct list_head	whitelist;
3452aeb9a1aSJohan Hedberg 	struct list_head	uuids;
34655ed8ca1SJohan Hedberg 	struct list_head	link_keys;
347b899efafSVinicius Costa Gomes 	struct list_head	long_term_keys;
348970c4e46SJohan Hedberg 	struct list_head	identity_resolving_keys;
3492763eda6SSzymon Janc 	struct list_head	remote_oob_data;
350d2ab0ac1SMarcel Holtmann 	struct list_head	le_white_list;
35115819a70SAndre Guedes 	struct list_head	le_conn_params;
35277a77a30SAndre Guedes 	struct list_head	pend_le_conns;
35366f8455aSJohan Hedberg 	struct list_head	pend_le_reports;
3542763eda6SSzymon Janc 
3551da177e4SLinus Torvalds 	struct hci_dev_stats	stat;
3561da177e4SLinus Torvalds 
3571da177e4SLinus Torvalds 	atomic_t		promisc;
3581da177e4SLinus Torvalds 
359ca325f69SMarcel Holtmann 	struct dentry		*debugfs;
360ca325f69SMarcel Holtmann 
361a91f2e39SMarcel Holtmann 	struct device		dev;
3621da177e4SLinus Torvalds 
363611b30f7SMarcel Holtmann 	struct rfkill		*rfkill;
364611b30f7SMarcel Holtmann 
365eacb44dfSMarcel Holtmann 	DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);
366d23264a8SAndre Guedes 
3677ba8b4beSAndre Guedes 	struct delayed_work	le_scan_disable;
3682d28cfe7SJakub Pawlowski 	struct delayed_work	le_scan_restart;
3697ba8b4beSAndre Guedes 
3708fa19098SJohan Hedberg 	__s8			adv_tx_power;
3713f0f524bSJohan Hedberg 	__u8			adv_data[HCI_MAX_AD_LENGTH];
3723f0f524bSJohan Hedberg 	__u8			adv_data_len;
373f8e808bdSMarcel Holtmann 	__u8			scan_rsp_data[HCI_MAX_AD_LENGTH];
374f8e808bdSMarcel Holtmann 	__u8			scan_rsp_data_len;
3758fa19098SJohan Hedberg 
376203fea01SArman Uguray 	struct adv_info		adv_instance;
377203fea01SArman Uguray 
378863efaf2SJohan Hedberg 	__u8			irk[16];
379d6bfd59cSJohan Hedberg 	__u32			rpa_timeout;
380d6bfd59cSJohan Hedberg 	struct delayed_work	rpa_expired;
3812b5224dcSMarcel Holtmann 	bdaddr_t		rpa;
382863efaf2SJohan Hedberg 
3831da177e4SLinus Torvalds 	int (*open)(struct hci_dev *hdev);
3841da177e4SLinus Torvalds 	int (*close)(struct hci_dev *hdev);
3851da177e4SLinus Torvalds 	int (*flush)(struct hci_dev *hdev);
386f41c70c4SMarcel Holtmann 	int (*setup)(struct hci_dev *hdev);
387a44fecbdSTedd Ho-Jeong An 	int (*shutdown)(struct hci_dev *hdev);
3887bd8f09fSMarcel Holtmann 	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
3891da177e4SLinus Torvalds 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
390c7741d16SMarcel Holtmann 	void (*hw_error)(struct hci_dev *hdev, u8 code);
39124c457e2SMarcel Holtmann 	int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
3921da177e4SLinus Torvalds };
3931da177e4SLinus Torvalds 
39453502d69SAndrei Emeltchenko #define HCI_PHY_HANDLE(handle)	(handle & 0xff)
39553502d69SAndrei Emeltchenko 
3961da177e4SLinus Torvalds struct hci_conn {
3971da177e4SLinus Torvalds 	struct list_head list;
3981da177e4SLinus Torvalds 
3991da177e4SLinus Torvalds 	atomic_t	refcnt;
4001da177e4SLinus Torvalds 
4011da177e4SLinus Torvalds 	bdaddr_t	dst;
40229b7988aSAndre Guedes 	__u8		dst_type;
403662e8820SMarcel Holtmann 	bdaddr_t	src;
404e7c4096eSMarcel Holtmann 	__u8		src_type;
405cb1d68f7SJohan Hedberg 	bdaddr_t	init_addr;
406cb1d68f7SJohan Hedberg 	__u8		init_addr_type;
407cb1d68f7SJohan Hedberg 	bdaddr_t	resp_addr;
408cb1d68f7SJohan Hedberg 	__u8		resp_addr_type;
4091da177e4SLinus Torvalds 	__u16		handle;
4101da177e4SLinus Torvalds 	__u16		state;
41104837f64SMarcel Holtmann 	__u8		mode;
4121da177e4SLinus Torvalds 	__u8		type;
41340bef302SJohan Hedberg 	__u8		role;
414a0c808b3SJohan Hedberg 	bool		out;
4154c67bc74SMarcel Holtmann 	__u8		attempt;
4161da177e4SLinus Torvalds 	__u8		dev_class[3];
417cad718edSJohan Hedberg 	__u8		features[HCI_MAX_PAGES][8];
418a8746417SMarcel Holtmann 	__u16		pkt_type;
41904837f64SMarcel Holtmann 	__u16		link_policy;
42013d39315SWaldemar Rymarkiewicz 	__u8		key_type;
42140be492fSMarcel Holtmann 	__u8		auth_type;
4228c1b2355SMarcel Holtmann 	__u8		sec_level;
423765c2a96SJohan Hedberg 	__u8		pending_sec_level;
424980e1a53SJohan Hedberg 	__u8		pin_length;
425726b4ffcSVinicius Costa Gomes 	__u8		enc_key_size;
42617fa4b9dSJohan Hedberg 	__u8		io_capability;
42792a25256SJohan Hedberg 	__u32		passkey_notify;
42892a25256SJohan Hedberg 	__u8		passkey_entered;
429052b30b0SMarcel Holtmann 	__u16		disc_timeout;
43009ae260bSJohan Hedberg 	__u16		conn_timeout;
43110c62ddcSFrédéric Dalleau 	__u16		setting;
4321e406eefSAndre Guedes 	__u16		le_conn_min_interval;
4331e406eefSAndre Guedes 	__u16		le_conn_max_interval;
434e04fde60SMarcel Holtmann 	__u16		le_conn_interval;
435e04fde60SMarcel Holtmann 	__u16		le_conn_latency;
436e04fde60SMarcel Holtmann 	__u16		le_supv_timeout;
437fd45ada9SAlfonso Acosta 	__u8		le_adv_data[HCI_MAX_AD_LENGTH];
438fd45ada9SAlfonso Acosta 	__u8		le_adv_data_len;
4395ae76a94SAndrzej Kaczmarek 	__s8		rssi;
4405a134faeSAndrzej Kaczmarek 	__s8		tx_power;
441d0455ed9SAndrzej Kaczmarek 	__s8		max_tx_power;
44251a8efd7SJohan Hedberg 	unsigned long	flags;
4431da177e4SLinus Torvalds 
44433f35721SJohan Hedberg 	__u32		clock;
44533f35721SJohan Hedberg 	__u16		clock_accuracy;
44633f35721SJohan Hedberg 
447dd983808SAndrzej Kaczmarek 	unsigned long	conn_info_timestamp;
448dd983808SAndrzej Kaczmarek 
44903b555e1SJohan Hedberg 	__u8		remote_cap;
45003b555e1SJohan Hedberg 	__u8		remote_auth;
4513161ae1cSAndrei Emeltchenko 	__u8		remote_id;
45203b555e1SJohan Hedberg 
4531da177e4SLinus Torvalds 	unsigned int	sent;
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds 	struct sk_buff_head data_q;
4562c33c06aSGustavo F. Padovan 	struct list_head chan_list;
4571da177e4SLinus Torvalds 
45819c40e3bSGustavo F. Padovan 	struct delayed_work disc_work;
4597bc18d9dSJohan Hedberg 	struct delayed_work auto_accept_work;
460a74a84f6SJohan Hedberg 	struct delayed_work idle_work;
4619489eca4SJohan Hedberg 	struct delayed_work le_conn_timeout;
4621da177e4SLinus Torvalds 
463b219e3acSMarcel Holtmann 	struct device	dev;
46423b9ceb7SMarcel Holtmann 	struct dentry	*debugfs;
465b219e3acSMarcel Holtmann 
4661da177e4SLinus Torvalds 	struct hci_dev	*hdev;
4671da177e4SLinus Torvalds 	void		*l2cap_data;
4681da177e4SLinus Torvalds 	void		*sco_data;
4699740e49dSAndrei Emeltchenko 	struct amp_mgr	*amp_mgr;
4701da177e4SLinus Torvalds 
4711da177e4SLinus Torvalds 	struct hci_conn	*link;
472e9a416b5SJohan Hedberg 
473e9a416b5SJohan Hedberg 	void (*connect_cfm_cb)	(struct hci_conn *conn, u8 status);
474e9a416b5SJohan Hedberg 	void (*security_cfm_cb)	(struct hci_conn *conn, u8 status);
475e9a416b5SJohan Hedberg 	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
4761da177e4SLinus Torvalds };
4771da177e4SLinus Torvalds 
47873d80debSLuiz Augusto von Dentz struct hci_chan {
47973d80debSLuiz Augusto von Dentz 	struct list_head list;
48042c4e53eSAndrei Emeltchenko 	__u16 handle;
48173d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
48273d80debSLuiz Augusto von Dentz 	struct sk_buff_head data_q;
48373d80debSLuiz Augusto von Dentz 	unsigned int	sent;
484168df8e5SMat Martineau 	__u8		state;
48573d80debSLuiz Augusto von Dentz };
48673d80debSLuiz Augusto von Dentz 
48715819a70SAndre Guedes struct hci_conn_params {
48815819a70SAndre Guedes 	struct list_head list;
48993450c75SJohan Hedberg 	struct list_head action;
49015819a70SAndre Guedes 
49115819a70SAndre Guedes 	bdaddr_t addr;
49215819a70SAndre Guedes 	u8 addr_type;
49315819a70SAndre Guedes 
49415819a70SAndre Guedes 	u16 conn_min_interval;
49515819a70SAndre Guedes 	u16 conn_max_interval;
496f044eb05SMarcel Holtmann 	u16 conn_latency;
497f044eb05SMarcel Holtmann 	u16 supervision_timeout;
4989fcb18efSAndre Guedes 
4999fcb18efSAndre Guedes 	enum {
5009fcb18efSAndre Guedes 		HCI_AUTO_CONN_DISABLED,
501a3451d27SJohan Hedberg 		HCI_AUTO_CONN_REPORT,
5024b9e7e75SMarcel Holtmann 		HCI_AUTO_CONN_DIRECT,
5039fcb18efSAndre Guedes 		HCI_AUTO_CONN_ALWAYS,
5049fcb18efSAndre Guedes 		HCI_AUTO_CONN_LINK_LOSS,
5059fcb18efSAndre Guedes 	} auto_connect;
506f161dd41SJohan Hedberg 
507f161dd41SJohan Hedberg 	struct hci_conn *conn;
50815819a70SAndre Guedes };
50915819a70SAndre Guedes 
5101da177e4SLinus Torvalds extern struct list_head hci_dev_list;
5111da177e4SLinus Torvalds extern struct list_head hci_cb_list;
5121da177e4SLinus Torvalds extern rwlock_t hci_dev_list_lock;
513fba7ecf0SJohan Hedberg extern struct mutex hci_cb_list_lock;
5141da177e4SLinus Torvalds 
515eacb44dfSMarcel Holtmann #define hci_dev_set_flag(hdev, nr)             set_bit((nr), (hdev)->dev_flags)
516eacb44dfSMarcel Holtmann #define hci_dev_clear_flag(hdev, nr)           clear_bit((nr), (hdev)->dev_flags)
517eacb44dfSMarcel Holtmann #define hci_dev_change_flag(hdev, nr)          change_bit((nr), (hdev)->dev_flags)
518eacb44dfSMarcel Holtmann #define hci_dev_test_flag(hdev, nr)            test_bit((nr), (hdev)->dev_flags)
519eacb44dfSMarcel Holtmann #define hci_dev_test_and_set_flag(hdev, nr)    test_and_set_bit((nr), (hdev)->dev_flags)
520eacb44dfSMarcel Holtmann #define hci_dev_test_and_clear_flag(hdev, nr)  test_and_clear_bit((nr), (hdev)->dev_flags)
521eacb44dfSMarcel Holtmann #define hci_dev_test_and_change_flag(hdev, nr) test_and_change_bit((nr), (hdev)->dev_flags)
522d7a5a11dSMarcel Holtmann 
523eacb44dfSMarcel Holtmann #define hci_dev_clear_volatile_flags(hdev)			\
524eacb44dfSMarcel Holtmann 	do {							\
525eacb44dfSMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_SCAN);		\
526eacb44dfSMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_LE_ADV);		\
527eacb44dfSMarcel Holtmann 		hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ);	\
528eacb44dfSMarcel Holtmann 	} while (0)
529516018a9SMarcel Holtmann 
530686ebf28SUlisses Furquim /* ----- HCI interface to upper protocols ----- */
531e74e58f8SJoe Perches int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
532e74e58f8SJoe Perches int l2cap_disconn_ind(struct hci_conn *hcon);
5339b4c3336SArron Wang void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags);
534686ebf28SUlisses Furquim 
535ff50e8afSArron Wang #if IS_ENABLED(CONFIG_BT_BREDR)
536e74e58f8SJoe Perches int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
5379b4c3336SArron Wang void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
538ff50e8afSArron Wang #else
539ff50e8afSArron Wang static inline int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
540ff50e8afSArron Wang 				  __u8 *flags)
541ff50e8afSArron Wang {
542ff50e8afSArron Wang 	return 0;
543ff50e8afSArron Wang }
544ff50e8afSArron Wang 
545ff50e8afSArron Wang static inline void sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
546ff50e8afSArron Wang {
547ff50e8afSArron Wang }
548ff50e8afSArron Wang #endif
549686ebf28SUlisses Furquim 
5501da177e4SLinus Torvalds /* ----- Inquiry cache ----- */
55170f23020SAndrei Emeltchenko #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */
55270f23020SAndrei Emeltchenko #define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   /* 60 seconds */
5531da177e4SLinus Torvalds 
55430883512SJohan Hedberg static inline void discovery_init(struct hci_dev *hdev)
5551da177e4SLinus Torvalds {
556ff9ef578SJohan Hedberg 	hdev->discovery.state = DISCOVERY_STOPPED;
55730883512SJohan Hedberg 	INIT_LIST_HEAD(&hdev->discovery.all);
55830883512SJohan Hedberg 	INIT_LIST_HEAD(&hdev->discovery.unknown);
55930883512SJohan Hedberg 	INIT_LIST_HEAD(&hdev->discovery.resolve);
560da25cf6aSMarcel Holtmann 	hdev->discovery.report_invalid_rssi = true;
56137eab042SJakub Pawlowski 	hdev->discovery.rssi = HCI_RSSI_INVALID;
5621da177e4SLinus Torvalds }
5631da177e4SLinus Torvalds 
5640256325eSMarcel Holtmann static inline void hci_discovery_filter_clear(struct hci_dev *hdev)
5650256325eSMarcel Holtmann {
56682f8b651SJakub Pawlowski 	hdev->discovery.result_filtering = false;
567da25cf6aSMarcel Holtmann 	hdev->discovery.report_invalid_rssi = true;
5680256325eSMarcel Holtmann 	hdev->discovery.rssi = HCI_RSSI_INVALID;
5690256325eSMarcel Holtmann 	hdev->discovery.uuid_count = 0;
5700256325eSMarcel Holtmann 	kfree(hdev->discovery.uuids);
5710256325eSMarcel Holtmann 	hdev->discovery.uuids = NULL;
5722d28cfe7SJakub Pawlowski 	hdev->discovery.scan_start = 0;
5732d28cfe7SJakub Pawlowski 	hdev->discovery.scan_duration = 0;
5740256325eSMarcel Holtmann }
5750256325eSMarcel Holtmann 
576203fea01SArman Uguray static inline void adv_info_init(struct hci_dev *hdev)
577203fea01SArman Uguray {
578203fea01SArman Uguray 	memset(&hdev->adv_instance, 0, sizeof(struct adv_info));
579203fea01SArman Uguray }
580203fea01SArman Uguray 
58130dc78e1SJohan Hedberg bool hci_discovery_active(struct hci_dev *hdev);
58230dc78e1SJohan Hedberg 
583ff9ef578SJohan Hedberg void hci_discovery_set_state(struct hci_dev *hdev, int state);
584ff9ef578SJohan Hedberg 
5851da177e4SLinus Torvalds static inline int inquiry_cache_empty(struct hci_dev *hdev)
5861da177e4SLinus Torvalds {
58730883512SJohan Hedberg 	return list_empty(&hdev->discovery.all);
5881da177e4SLinus Torvalds }
5891da177e4SLinus Torvalds 
5901da177e4SLinus Torvalds static inline long inquiry_cache_age(struct hci_dev *hdev)
5911da177e4SLinus Torvalds {
59230883512SJohan Hedberg 	struct discovery_state *c = &hdev->discovery;
5931da177e4SLinus Torvalds 	return jiffies - c->timestamp;
5941da177e4SLinus Torvalds }
5951da177e4SLinus Torvalds 
5961da177e4SLinus Torvalds static inline long inquiry_entry_age(struct inquiry_entry *e)
5971da177e4SLinus Torvalds {
5981da177e4SLinus Torvalds 	return jiffies - e->timestamp;
5991da177e4SLinus Torvalds }
6001da177e4SLinus Torvalds 
6015a9d0a3fSWaldemar Rymarkiewicz struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
6025a9d0a3fSWaldemar Rymarkiewicz 					       bdaddr_t *bdaddr);
603561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
604561aafbcSJohan Hedberg 						       bdaddr_t *bdaddr);
60530dc78e1SJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
60630dc78e1SJohan Hedberg 						       bdaddr_t *bdaddr,
60730dc78e1SJohan Hedberg 						       int state);
608a3d4e20aSJohan Hedberg void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
609a3d4e20aSJohan Hedberg 				      struct inquiry_entry *ie);
610af58925cSMarcel Holtmann u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
611af58925cSMarcel Holtmann 			     bool name_known);
6121f9b9a5dSAndre Guedes void hci_inquiry_cache_flush(struct hci_dev *hdev);
6131da177e4SLinus Torvalds 
6141da177e4SLinus Torvalds /* ----- HCI Connections ----- */
6151da177e4SLinus Torvalds enum {
6161da177e4SLinus Torvalds 	HCI_CONN_AUTH_PEND,
61719f8def0SWaldemar Rymarkiewicz 	HCI_CONN_REAUTH_PEND,
6181da177e4SLinus Torvalds 	HCI_CONN_ENCRYPT_PEND,
61904837f64SMarcel Holtmann 	HCI_CONN_RSWITCH_PEND,
62004837f64SMarcel Holtmann 	HCI_CONN_MODE_CHANGE_PEND,
621e73439d8SMarcel Holtmann 	HCI_CONN_SCO_SETUP_PEND,
622b644ba33SJohan Hedberg 	HCI_CONN_MGMT_CONNECTED,
62358a681efSJohan Hedberg 	HCI_CONN_SSP_ENABLED,
624eb9a8f3fSMarcel Holtmann 	HCI_CONN_SC_ENABLED,
625abf76badSMarcel Holtmann 	HCI_CONN_AES_CCM,
62658a681efSJohan Hedberg 	HCI_CONN_POWER_SAVE,
627af6a9c32SJohan Hedberg 	HCI_CONN_FLUSH_KEY,
6284dae2798SJohan Hedberg 	HCI_CONN_ENCRYPT,
6294dae2798SJohan Hedberg 	HCI_CONN_AUTH,
6304dae2798SJohan Hedberg 	HCI_CONN_SECURE,
6314dae2798SJohan Hedberg 	HCI_CONN_FIPS,
632fe59a05fSJohan Hedberg 	HCI_CONN_STK_ENCRYPT,
633977f8fceSJohan Hedberg 	HCI_CONN_AUTH_INITIATOR,
634f94b665dSJohan Hedberg 	HCI_CONN_DROP,
63589cbb063SAlfonso Acosta 	HCI_CONN_PARAM_REMOVAL_PEND,
636fe8bc5acSJohan Hedberg 	HCI_CONN_NEW_LINK_KEY,
6371da177e4SLinus Torvalds };
6381da177e4SLinus Torvalds 
639aa64a8b5SJohan Hedberg static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
640aa64a8b5SJohan Hedberg {
641aa64a8b5SJohan Hedberg 	struct hci_dev *hdev = conn->hdev;
642d7a5a11dSMarcel Holtmann 	return hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
643c3c7ea65SGustavo Padovan 	       test_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
644aa64a8b5SJohan Hedberg }
645aa64a8b5SJohan Hedberg 
646eb9a8f3fSMarcel Holtmann static inline bool hci_conn_sc_enabled(struct hci_conn *conn)
647eb9a8f3fSMarcel Holtmann {
648eb9a8f3fSMarcel Holtmann 	struct hci_dev *hdev = conn->hdev;
649d7a5a11dSMarcel Holtmann 	return hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
650eb9a8f3fSMarcel Holtmann 	       test_bit(HCI_CONN_SC_ENABLED, &conn->flags);
651eb9a8f3fSMarcel Holtmann }
652eb9a8f3fSMarcel Holtmann 
6531da177e4SLinus Torvalds static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
6541da177e4SLinus Torvalds {
6551da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
656bf4c6325SGustavo F. Padovan 	list_add_rcu(&c->list, &h->list);
657fcd89c09SVille Tervo 	switch (c->type) {
658fcd89c09SVille Tervo 	case ACL_LINK:
6591da177e4SLinus Torvalds 		h->acl_num++;
660fcd89c09SVille Tervo 		break;
661bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
662bd1eb66bSAndrei Emeltchenko 		h->amp_num++;
663bd1eb66bSAndrei Emeltchenko 		break;
664fcd89c09SVille Tervo 	case LE_LINK:
665fcd89c09SVille Tervo 		h->le_num++;
666f8218dc6SJohan Hedberg 		if (c->role == HCI_ROLE_SLAVE)
667f8218dc6SJohan Hedberg 			h->le_num_slave++;
668fcd89c09SVille Tervo 		break;
669fcd89c09SVille Tervo 	case SCO_LINK:
670fcd89c09SVille Tervo 	case ESCO_LINK:
6711da177e4SLinus Torvalds 		h->sco_num++;
672fcd89c09SVille Tervo 		break;
673fcd89c09SVille Tervo 	}
6741da177e4SLinus Torvalds }
6751da177e4SLinus Torvalds 
6761da177e4SLinus Torvalds static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
6771da177e4SLinus Torvalds {
6781da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
679bf4c6325SGustavo F. Padovan 
680bf4c6325SGustavo F. Padovan 	list_del_rcu(&c->list);
681bf4c6325SGustavo F. Padovan 	synchronize_rcu();
682bf4c6325SGustavo F. Padovan 
683fcd89c09SVille Tervo 	switch (c->type) {
684fcd89c09SVille Tervo 	case ACL_LINK:
6851da177e4SLinus Torvalds 		h->acl_num--;
686fcd89c09SVille Tervo 		break;
687bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
688bd1eb66bSAndrei Emeltchenko 		h->amp_num--;
689bd1eb66bSAndrei Emeltchenko 		break;
690fcd89c09SVille Tervo 	case LE_LINK:
691fcd89c09SVille Tervo 		h->le_num--;
692f8218dc6SJohan Hedberg 		if (c->role == HCI_ROLE_SLAVE)
693f8218dc6SJohan Hedberg 			h->le_num_slave--;
694fcd89c09SVille Tervo 		break;
695fcd89c09SVille Tervo 	case SCO_LINK:
696fcd89c09SVille Tervo 	case ESCO_LINK:
6971da177e4SLinus Torvalds 		h->sco_num--;
698fcd89c09SVille Tervo 		break;
699fcd89c09SVille Tervo 	}
7001da177e4SLinus Torvalds }
7011da177e4SLinus Torvalds 
70252087a79SLuiz Augusto von Dentz static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
70352087a79SLuiz Augusto von Dentz {
70452087a79SLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
70552087a79SLuiz Augusto von Dentz 	switch (type) {
70652087a79SLuiz Augusto von Dentz 	case ACL_LINK:
70752087a79SLuiz Augusto von Dentz 		return h->acl_num;
708bd1eb66bSAndrei Emeltchenko 	case AMP_LINK:
709bd1eb66bSAndrei Emeltchenko 		return h->amp_num;
71052087a79SLuiz Augusto von Dentz 	case LE_LINK:
71152087a79SLuiz Augusto von Dentz 		return h->le_num;
71252087a79SLuiz Augusto von Dentz 	case SCO_LINK:
71352087a79SLuiz Augusto von Dentz 	case ESCO_LINK:
71452087a79SLuiz Augusto von Dentz 		return h->sco_num;
71552087a79SLuiz Augusto von Dentz 	default:
71652087a79SLuiz Augusto von Dentz 		return 0;
71752087a79SLuiz Augusto von Dentz 	}
71852087a79SLuiz Augusto von Dentz }
71952087a79SLuiz Augusto von Dentz 
720f4f07505SJohan Hedberg static inline unsigned int hci_conn_count(struct hci_dev *hdev)
721f4f07505SJohan Hedberg {
722f4f07505SJohan Hedberg 	struct hci_conn_hash *c = &hdev->conn_hash;
723f4f07505SJohan Hedberg 
724f4f07505SJohan Hedberg 	return c->acl_num + c->amp_num + c->sco_num + c->le_num;
725f4f07505SJohan Hedberg }
726f4f07505SJohan Hedberg 
727845472e8SMarcel Holtmann static inline __u8 hci_conn_lookup_type(struct hci_dev *hdev, __u16 handle)
728845472e8SMarcel Holtmann {
729845472e8SMarcel Holtmann 	struct hci_conn_hash *h = &hdev->conn_hash;
730845472e8SMarcel Holtmann 	struct hci_conn *c;
731845472e8SMarcel Holtmann 	__u8 type = INVALID_LINK;
732845472e8SMarcel Holtmann 
733845472e8SMarcel Holtmann 	rcu_read_lock();
734845472e8SMarcel Holtmann 
735845472e8SMarcel Holtmann 	list_for_each_entry_rcu(c, &h->list, list) {
736845472e8SMarcel Holtmann 		if (c->handle == handle) {
737845472e8SMarcel Holtmann 			type = c->type;
738845472e8SMarcel Holtmann 			break;
739845472e8SMarcel Holtmann 		}
740845472e8SMarcel Holtmann 	}
741845472e8SMarcel Holtmann 
742845472e8SMarcel Holtmann 	rcu_read_unlock();
743845472e8SMarcel Holtmann 
744845472e8SMarcel Holtmann 	return type;
745845472e8SMarcel Holtmann }
746845472e8SMarcel Holtmann 
7471da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
7481da177e4SLinus Torvalds 								__u16 handle)
7491da177e4SLinus Torvalds {
7501da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
7511da177e4SLinus Torvalds 	struct hci_conn  *c;
7521da177e4SLinus Torvalds 
753bf4c6325SGustavo F. Padovan 	rcu_read_lock();
754bf4c6325SGustavo F. Padovan 
755bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
756bf4c6325SGustavo F. Padovan 		if (c->handle == handle) {
757bf4c6325SGustavo F. Padovan 			rcu_read_unlock();
7581da177e4SLinus Torvalds 			return c;
7591da177e4SLinus Torvalds 		}
760bf4c6325SGustavo F. Padovan 	}
761bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
762bf4c6325SGustavo F. Padovan 
7631da177e4SLinus Torvalds 	return NULL;
7641da177e4SLinus Torvalds }
7651da177e4SLinus Torvalds 
7661da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
7671da177e4SLinus Torvalds 							__u8 type, bdaddr_t *ba)
7681da177e4SLinus Torvalds {
7691da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
7701da177e4SLinus Torvalds 	struct hci_conn  *c;
7711da177e4SLinus Torvalds 
772bf4c6325SGustavo F. Padovan 	rcu_read_lock();
773bf4c6325SGustavo F. Padovan 
774bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
775bf4c6325SGustavo F. Padovan 		if (c->type == type && !bacmp(&c->dst, ba)) {
776bf4c6325SGustavo F. Padovan 			rcu_read_unlock();
7771da177e4SLinus Torvalds 			return c;
7781da177e4SLinus Torvalds 		}
779bf4c6325SGustavo F. Padovan 	}
780bf4c6325SGustavo F. Padovan 
781bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
782bf4c6325SGustavo F. Padovan 
7831da177e4SLinus Torvalds 	return NULL;
7841da177e4SLinus Torvalds }
7851da177e4SLinus Torvalds 
7864c67bc74SMarcel Holtmann static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
7874c67bc74SMarcel Holtmann 							__u8 type, __u16 state)
7884c67bc74SMarcel Holtmann {
7894c67bc74SMarcel Holtmann 	struct hci_conn_hash *h = &hdev->conn_hash;
7904c67bc74SMarcel Holtmann 	struct hci_conn  *c;
7914c67bc74SMarcel Holtmann 
792bf4c6325SGustavo F. Padovan 	rcu_read_lock();
793bf4c6325SGustavo F. Padovan 
794bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
795bf4c6325SGustavo F. Padovan 		if (c->type == type && c->state == state) {
796bf4c6325SGustavo F. Padovan 			rcu_read_unlock();
7974c67bc74SMarcel Holtmann 			return c;
7984c67bc74SMarcel Holtmann 		}
799bf4c6325SGustavo F. Padovan 	}
800bf4c6325SGustavo F. Padovan 
801bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
802bf4c6325SGustavo F. Padovan 
8034c67bc74SMarcel Holtmann 	return NULL;
8044c67bc74SMarcel Holtmann }
8054c67bc74SMarcel Holtmann 
806e3b679d5SJohan Hedberg int hci_disconnect(struct hci_conn *conn, __u8 reason);
8072dea632fSFrédéric Dalleau bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
808e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status);
8091da177e4SLinus Torvalds 
810a5c4e309SJohan Hedberg struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
811a5c4e309SJohan Hedberg 			      u8 role);
8121da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn);
8131da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev);
814a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev);
8151da177e4SLinus Torvalds 
81673d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn);
8179472007cSAndrei Emeltchenko void hci_chan_del(struct hci_chan *chan);
8182c33c06aSGustavo F. Padovan void hci_chan_list_flush(struct hci_conn *conn);
81942c4e53eSAndrei Emeltchenko struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
82073d80debSLuiz Augusto von Dentz 
82104a6c589SAndre Guedes struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
822cdd6275eSJohan Hedberg 				u8 dst_type, u8 sec_level, u16 conn_timeout,
823e804d25dSJohan Hedberg 				u8 role);
82404a6c589SAndre Guedes struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
82504a6c589SAndre Guedes 				 u8 sec_level, u8 auth_type);
82610c62ddcSFrédéric Dalleau struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
82710c62ddcSFrédéric Dalleau 				 __u16 setting);
828e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn);
829b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
830e7cafc45SJohan Hedberg int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,
831e7cafc45SJohan Hedberg 		      bool initiator);
8328c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
8331da177e4SLinus Torvalds 
83414b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
8351da177e4SLinus Torvalds 
83606c053fbSAndre Guedes void hci_le_conn_failed(struct hci_conn *conn, u8 status);
83706c053fbSAndre Guedes 
8388d12356fSDavid Herrmann /*
8398d12356fSDavid Herrmann  * hci_conn_get() and hci_conn_put() are used to control the life-time of an
8408d12356fSDavid Herrmann  * "hci_conn" object. They do not guarantee that the hci_conn object is running,
8418d12356fSDavid Herrmann  * working or anything else. They just guarantee that the object is available
8428d12356fSDavid Herrmann  * and can be dereferenced. So you can use its locks, local variables and any
8438d12356fSDavid Herrmann  * other constant data.
8448d12356fSDavid Herrmann  * Before accessing runtime data, you _must_ lock the object and then check that
8458d12356fSDavid Herrmann  * it is still running. As soon as you release the locks, the connection might
8468d12356fSDavid Herrmann  * get dropped, though.
8478d12356fSDavid Herrmann  *
8488d12356fSDavid Herrmann  * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control
8498d12356fSDavid Herrmann  * how long the underlying connection is held. So every channel that runs on the
8508d12356fSDavid Herrmann  * hci_conn object calls this to prevent the connection from disappearing. As
8518d12356fSDavid Herrmann  * long as you hold a device, you must also guarantee that you have a valid
8528d12356fSDavid Herrmann  * reference to the device via hci_conn_get() (or the initial reference from
8538d12356fSDavid Herrmann  * hci_conn_add()).
8548d12356fSDavid Herrmann  * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't
8558d12356fSDavid Herrmann  * break because nobody cares for that. But this means, we cannot use
8568d12356fSDavid Herrmann  * _get()/_drop() in it, but require the caller to have a valid ref (FIXME).
8578d12356fSDavid Herrmann  */
8588d12356fSDavid Herrmann 
85951bb8457SJohan Hedberg static inline struct hci_conn *hci_conn_get(struct hci_conn *conn)
8608d12356fSDavid Herrmann {
8618d12356fSDavid Herrmann 	get_device(&conn->dev);
86251bb8457SJohan Hedberg 	return conn;
8638d12356fSDavid Herrmann }
8648d12356fSDavid Herrmann 
8658d12356fSDavid Herrmann static inline void hci_conn_put(struct hci_conn *conn)
8668d12356fSDavid Herrmann {
8678d12356fSDavid Herrmann 	put_device(&conn->dev);
8688d12356fSDavid Herrmann }
8698d12356fSDavid Herrmann 
8701da177e4SLinus Torvalds static inline void hci_conn_hold(struct hci_conn *conn)
8711da177e4SLinus Torvalds {
87271becf0cSAndrei Emeltchenko 	BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt));
87338b3fef1SAndrei Emeltchenko 
8741da177e4SLinus Torvalds 	atomic_inc(&conn->refcnt);
8752f304d1eSAndre Guedes 	cancel_delayed_work(&conn->disc_work);
8761da177e4SLinus Torvalds }
8771da177e4SLinus Torvalds 
87876a68ba0SDavid Herrmann static inline void hci_conn_drop(struct hci_conn *conn)
8791da177e4SLinus Torvalds {
88071becf0cSAndrei Emeltchenko 	BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt));
88138b3fef1SAndrei Emeltchenko 
8821da177e4SLinus Torvalds 	if (atomic_dec_and_test(&conn->refcnt)) {
88304837f64SMarcel Holtmann 		unsigned long timeo;
884716e4ab5SAndrei Emeltchenko 
885716e4ab5SAndrei Emeltchenko 		switch (conn->type) {
886716e4ab5SAndrei Emeltchenko 		case ACL_LINK:
887716e4ab5SAndrei Emeltchenko 		case LE_LINK:
888a74a84f6SJohan Hedberg 			cancel_delayed_work(&conn->idle_work);
8896ac59344SMarcel Holtmann 			if (conn->state == BT_CONNECTED) {
8905f246e89SAndrei Emeltchenko 				timeo = conn->disc_timeout;
89104837f64SMarcel Holtmann 				if (!conn->out)
892052b30b0SMarcel Holtmann 					timeo *= 2;
8935a9d0a3fSWaldemar Rymarkiewicz 			} else {
894eb78d7e5SJohan Hedberg 				timeo = 0;
8955a9d0a3fSWaldemar Rymarkiewicz 			}
896716e4ab5SAndrei Emeltchenko 			break;
897716e4ab5SAndrei Emeltchenko 
898716e4ab5SAndrei Emeltchenko 		case AMP_LINK:
899716e4ab5SAndrei Emeltchenko 			timeo = conn->disc_timeout;
900716e4ab5SAndrei Emeltchenko 			break;
901716e4ab5SAndrei Emeltchenko 
902716e4ab5SAndrei Emeltchenko 		default:
903eb78d7e5SJohan Hedberg 			timeo = 0;
904716e4ab5SAndrei Emeltchenko 			break;
9055a9d0a3fSWaldemar Rymarkiewicz 		}
906716e4ab5SAndrei Emeltchenko 
9072f304d1eSAndre Guedes 		cancel_delayed_work(&conn->disc_work);
90819c40e3bSGustavo F. Padovan 		queue_delayed_work(conn->hdev->workqueue,
9091931782bSVinicius Costa Gomes 				   &conn->disc_work, timeo);
9101da177e4SLinus Torvalds 	}
9111da177e4SLinus Torvalds }
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds /* ----- HCI Devices ----- */
914dc946bd8SDavid Herrmann static inline void hci_dev_put(struct hci_dev *d)
9151da177e4SLinus Torvalds {
916376261aeSAndrei Emeltchenko 	BT_DBG("%s orig refcnt %d", d->name,
917376261aeSAndrei Emeltchenko 	       atomic_read(&d->dev.kobj.kref.refcount));
918376261aeSAndrei Emeltchenko 
9194c724c71SDavid Herrmann 	put_device(&d->dev);
920010666a1SDavid Herrmann }
9211da177e4SLinus Torvalds 
922dc946bd8SDavid Herrmann static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
9231da177e4SLinus Torvalds {
924376261aeSAndrei Emeltchenko 	BT_DBG("%s orig refcnt %d", d->name,
925376261aeSAndrei Emeltchenko 	       atomic_read(&d->dev.kobj.kref.refcount));
926376261aeSAndrei Emeltchenko 
9274c724c71SDavid Herrmann 	get_device(&d->dev);
9281da177e4SLinus Torvalds 	return d;
9291da177e4SLinus Torvalds }
9301da177e4SLinus Torvalds 
93109fd0de5SGustavo F. Padovan #define hci_dev_lock(d)		mutex_lock(&d->lock)
93209fd0de5SGustavo F. Padovan #define hci_dev_unlock(d)	mutex_unlock(&d->lock)
9331da177e4SLinus Torvalds 
934aa2b86d7SDavid Herrmann #define to_hci_dev(d) container_of(d, struct hci_dev, dev)
9353dc07322SDavid Herrmann #define to_hci_conn(c) container_of(c, struct hci_conn, dev)
936aa2b86d7SDavid Herrmann 
937155961e8SDavid Herrmann static inline void *hci_get_drvdata(struct hci_dev *hdev)
938155961e8SDavid Herrmann {
939155961e8SDavid Herrmann 	return dev_get_drvdata(&hdev->dev);
940155961e8SDavid Herrmann }
941155961e8SDavid Herrmann 
942155961e8SDavid Herrmann static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
943155961e8SDavid Herrmann {
944155961e8SDavid Herrmann 	dev_set_drvdata(&hdev->dev, data);
945155961e8SDavid Herrmann }
946155961e8SDavid Herrmann 
9471da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index);
9480c0afedfSJohan Hedberg struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void);
9511da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev);
9521da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev);
95359735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev);
9541da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev);
9551da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev);
95675e0569fSMarcel Holtmann int hci_reset_dev(struct hci_dev *hdev);
9571da177e4SLinus Torvalds int hci_dev_open(__u16 dev);
9581da177e4SLinus Torvalds int hci_dev_close(__u16 dev);
9591da177e4SLinus Torvalds int hci_dev_reset(__u16 dev);
9601da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev);
9611da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg);
9621da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg);
9631da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg);
9641da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg);
9651da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
96640be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
9671da177e4SLinus Torvalds int hci_inquiry(void __user *arg);
9681da177e4SLinus Torvalds 
969dcc36c16SJohan Hedberg struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
970b9ee0a78SMarcel Holtmann 					   bdaddr_t *bdaddr, u8 type);
971dcc36c16SJohan Hedberg int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
972dcc36c16SJohan Hedberg int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
973dcc36c16SJohan Hedberg void hci_bdaddr_list_clear(struct list_head *list);
974d2ab0ac1SMarcel Holtmann 
97515819a70SAndre Guedes struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
97615819a70SAndre Guedes 					       bdaddr_t *addr, u8 addr_type);
97751d167c0SMarcel Holtmann struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
97851d167c0SMarcel Holtmann 					    bdaddr_t *addr, u8 addr_type);
97915819a70SAndre Guedes void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
980373110c5SJohan Hedberg void hci_conn_params_clear_all(struct hci_dev *hdev);
98155af49a8SJohan Hedberg void hci_conn_params_clear_disabled(struct hci_dev *hdev);
98215819a70SAndre Guedes 
983501f8827SJohan Hedberg struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
984501f8827SJohan Hedberg 						  bdaddr_t *addr,
985501f8827SJohan Hedberg 						  u8 addr_type);
98677a77a30SAndre Guedes 
98735f7498aSJohan Hedberg void hci_uuids_clear(struct hci_dev *hdev);
9882aeb9a1aSJohan Hedberg 
98935f7498aSJohan Hedberg void hci_link_keys_clear(struct hci_dev *hdev);
99055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
991567fa2aaSJohan Hedberg struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
9927652ff6aSJohan Hedberg 				  bdaddr_t *bdaddr, u8 *val, u8 type,
9937652ff6aSJohan Hedberg 				  u8 pin_len, bool *persistent);
994ca9142b8SJohan Hedberg struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
99535d70271SJohan Hedberg 			    u8 addr_type, u8 type, u8 authenticated,
996fe39c7b2SMarcel Holtmann 			    u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand);
997f3a73d97SJohan Hedberg struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
998e804d25dSJohan Hedberg 			     u8 addr_type, u8 role);
999e0b2b27eSJohan Hedberg int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type);
100035f7498aSJohan Hedberg void hci_smp_ltks_clear(struct hci_dev *hdev);
100155ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
100255ed8ca1SJohan Hedberg 
1003970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa);
1004970c4e46SJohan Hedberg struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
1005970c4e46SJohan Hedberg 				     u8 addr_type);
1006ca9142b8SJohan Hedberg struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
1007ca9142b8SJohan Hedberg 			    u8 addr_type, u8 val[16], bdaddr_t *rpa);
1008a7ec7338SJohan Hedberg void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type);
1009970c4e46SJohan Hedberg void hci_smp_irks_clear(struct hci_dev *hdev);
1010970c4e46SJohan Hedberg 
101155e76b38SJohan Hedberg bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
101255e76b38SJohan Hedberg 
101335f7498aSJohan Hedberg void hci_remote_oob_data_clear(struct hci_dev *hdev);
10142763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
10156928a924SJohan Hedberg 					  bdaddr_t *bdaddr, u8 bdaddr_type);
10160798872eSMarcel Holtmann int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
10176928a924SJohan Hedberg 			    u8 bdaddr_type, u8 *hash192, u8 *rand192,
101838da1703SJohan Hedberg 			    u8 *hash256, u8 *rand256);
10196928a924SJohan Hedberg int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr,
10206928a924SJohan Hedberg 			       u8 bdaddr_type);
10212763eda6SSzymon Janc 
10221da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
10231da177e4SLinus Torvalds 
1024e1a26170SMarcel Holtmann int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
1025ef222013SMarcel Holtmann 
10260ac7e700SDavid Herrmann void hci_init_sysfs(struct hci_dev *hdev);
1027a67e899cSMarcel Holtmann void hci_conn_init_sysfs(struct hci_conn *conn);
1028b219e3acSMarcel Holtmann void hci_conn_add_sysfs(struct hci_conn *conn);
1029b219e3acSMarcel Holtmann void hci_conn_del_sysfs(struct hci_conn *conn);
10301da177e4SLinus Torvalds 
10316935e0f5SDavid Herrmann #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev))
10321da177e4SLinus Torvalds 
10331da177e4SLinus Torvalds /* ----- LMP capabilities ----- */
1034cad718edSJohan Hedberg #define lmp_encrypt_capable(dev)   ((dev)->features[0][0] & LMP_ENCRYPT)
1035cad718edSJohan Hedberg #define lmp_rswitch_capable(dev)   ((dev)->features[0][0] & LMP_RSWITCH)
1036cad718edSJohan Hedberg #define lmp_hold_capable(dev)      ((dev)->features[0][0] & LMP_HOLD)
1037cad718edSJohan Hedberg #define lmp_sniff_capable(dev)     ((dev)->features[0][0] & LMP_SNIFF)
1038cad718edSJohan Hedberg #define lmp_park_capable(dev)      ((dev)->features[0][1] & LMP_PARK)
1039cad718edSJohan Hedberg #define lmp_inq_rssi_capable(dev)  ((dev)->features[0][3] & LMP_RSSI_INQ)
1040cad718edSJohan Hedberg #define lmp_esco_capable(dev)      ((dev)->features[0][3] & LMP_ESCO)
1041cad718edSJohan Hedberg #define lmp_bredr_capable(dev)     (!((dev)->features[0][4] & LMP_NO_BREDR))
1042cad718edSJohan Hedberg #define lmp_le_capable(dev)        ((dev)->features[0][4] & LMP_LE)
1043cad718edSJohan Hedberg #define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR)
1044cad718edSJohan Hedberg #define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC)
1045cad718edSJohan Hedberg #define lmp_ext_inq_capable(dev)   ((dev)->features[0][6] & LMP_EXT_INQ)
1046cad718edSJohan Hedberg #define lmp_le_br_capable(dev)     (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR))
1047cad718edSJohan Hedberg #define lmp_ssp_capable(dev)       ((dev)->features[0][6] & LMP_SIMPLE_PAIR)
1048cad718edSJohan Hedberg #define lmp_no_flush_capable(dev)  ((dev)->features[0][6] & LMP_NO_FLUSH)
1049cad718edSJohan Hedberg #define lmp_lsto_capable(dev)      ((dev)->features[0][7] & LMP_LSTO)
1050cad718edSJohan Hedberg #define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR)
1051cad718edSJohan Hedberg #define lmp_ext_feat_capable(dev)  ((dev)->features[0][7] & LMP_EXTFEATURES)
105207a5c61eSFrédéric Dalleau #define lmp_transp_capable(dev)    ((dev)->features[0][2] & LMP_TRANSPARENT)
10531da177e4SLinus Torvalds 
1054eead27daSAndre Guedes /* ----- Extended LMP capabilities ----- */
105553b834d2SMarcel Holtmann #define lmp_csb_master_capable(dev) ((dev)->features[2][0] & LMP_CSB_MASTER)
105653b834d2SMarcel Holtmann #define lmp_csb_slave_capable(dev)  ((dev)->features[2][0] & LMP_CSB_SLAVE)
105753b834d2SMarcel Holtmann #define lmp_sync_train_capable(dev) ((dev)->features[2][0] & LMP_SYNC_TRAIN)
105853b834d2SMarcel Holtmann #define lmp_sync_scan_capable(dev)  ((dev)->features[2][0] & LMP_SYNC_SCAN)
1059d5991585SMarcel Holtmann #define lmp_sc_capable(dev)         ((dev)->features[2][1] & LMP_SC)
1060d5991585SMarcel Holtmann #define lmp_ping_capable(dev)       ((dev)->features[2][1] & LMP_PING)
106153b834d2SMarcel Holtmann 
106253b834d2SMarcel Holtmann /* ----- Host capabilities ----- */
1063cad718edSJohan Hedberg #define lmp_host_ssp_capable(dev)  ((dev)->features[1][0] & LMP_HOST_SSP)
1064d5991585SMarcel Holtmann #define lmp_host_sc_capable(dev)   ((dev)->features[1][0] & LMP_HOST_SC)
1065cad718edSJohan Hedberg #define lmp_host_le_capable(dev)   (!!((dev)->features[1][0] & LMP_HOST_LE))
1066cad718edSJohan Hedberg #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))
1067eead27daSAndre Guedes 
1068d7a5a11dSMarcel Holtmann #define hdev_is_powered(dev)   (test_bit(HCI_UP, &(dev)->flags) && \
1069d7a5a11dSMarcel Holtmann 				!hci_dev_test_flag(dev, HCI_AUTO_OFF))
107005b3c3e7SMarcel Holtmann #define bredr_sc_enabled(dev)  (lmp_sc_capable(dev) && \
1071d7a5a11dSMarcel Holtmann 				hci_dev_test_flag(dev, HCI_SC_ENABLED))
1072432df05eSJohan Hedberg 
10731da177e4SLinus Torvalds /* ----- HCI protocols ----- */
107420714bfeSFrédéric Dalleau #define HCI_PROTO_DEFER             0x01
107520714bfeSFrédéric Dalleau 
10765a9d0a3fSWaldemar Rymarkiewicz static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
107720714bfeSFrédéric Dalleau 					__u8 type, __u8 *flags)
10781da177e4SLinus Torvalds {
1079686ebf28SUlisses Furquim 	switch (type) {
1080686ebf28SUlisses Furquim 	case ACL_LINK:
1081686ebf28SUlisses Furquim 		return l2cap_connect_ind(hdev, bdaddr);
10821da177e4SLinus Torvalds 
1083686ebf28SUlisses Furquim 	case SCO_LINK:
1084686ebf28SUlisses Furquim 	case ESCO_LINK:
108520714bfeSFrédéric Dalleau 		return sco_connect_ind(hdev, bdaddr, flags);
10861da177e4SLinus Torvalds 
1087686ebf28SUlisses Furquim 	default:
1088686ebf28SUlisses Furquim 		BT_ERR("unknown link type %d", type);
1089686ebf28SUlisses Furquim 		return -EINVAL;
1090686ebf28SUlisses Furquim 	}
10911da177e4SLinus Torvalds }
10921da177e4SLinus Torvalds 
10932950f21aSMarcel Holtmann static inline int hci_proto_disconn_ind(struct hci_conn *conn)
10942950f21aSMarcel Holtmann {
1095686ebf28SUlisses Furquim 	if (conn->type != ACL_LINK && conn->type != LE_LINK)
1096686ebf28SUlisses Furquim 		return HCI_ERROR_REMOTE_USER_TERM;
10972950f21aSMarcel Holtmann 
1098686ebf28SUlisses Furquim 	return l2cap_disconn_ind(conn);
10992950f21aSMarcel Holtmann }
11002950f21aSMarcel Holtmann 
11011da177e4SLinus Torvalds /* ----- HCI callbacks ----- */
11021da177e4SLinus Torvalds struct hci_cb {
11031da177e4SLinus Torvalds 	struct list_head list;
11041da177e4SLinus Torvalds 
11051da177e4SLinus Torvalds 	char *name;
11061da177e4SLinus Torvalds 
1107539c496dSJohan Hedberg 	void (*connect_cfm)	(struct hci_conn *conn, __u8 status);
11083a6d576bSJohan Hedberg 	void (*disconn_cfm)	(struct hci_conn *conn, __u8 status);
11095a9d0a3fSWaldemar Rymarkiewicz 	void (*security_cfm)	(struct hci_conn *conn, __u8 status,
11105a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt);
11111da177e4SLinus Torvalds 	void (*key_change_cfm)	(struct hci_conn *conn, __u8 status);
11121da177e4SLinus Torvalds 	void (*role_switch_cfm)	(struct hci_conn *conn, __u8 status, __u8 role);
11131da177e4SLinus Torvalds };
11141da177e4SLinus Torvalds 
1115539c496dSJohan Hedberg static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status)
1116539c496dSJohan Hedberg {
1117539c496dSJohan Hedberg 	struct hci_cb *cb;
1118539c496dSJohan Hedberg 
1119539c496dSJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
1120539c496dSJohan Hedberg 	list_for_each_entry(cb, &hci_cb_list, list) {
1121539c496dSJohan Hedberg 		if (cb->connect_cfm)
1122539c496dSJohan Hedberg 			cb->connect_cfm(conn, status);
1123539c496dSJohan Hedberg 	}
1124539c496dSJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
1125539c496dSJohan Hedberg 
1126539c496dSJohan Hedberg 	if (conn->connect_cfm_cb)
1127539c496dSJohan Hedberg 		conn->connect_cfm_cb(conn, status);
1128539c496dSJohan Hedberg }
1129539c496dSJohan Hedberg 
11303a6d576bSJohan Hedberg static inline void hci_disconn_cfm(struct hci_conn *conn, __u8 reason)
11313a6d576bSJohan Hedberg {
11323a6d576bSJohan Hedberg 	struct hci_cb *cb;
11333a6d576bSJohan Hedberg 
11343a6d576bSJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
11353a6d576bSJohan Hedberg 	list_for_each_entry(cb, &hci_cb_list, list) {
11363a6d576bSJohan Hedberg 		if (cb->disconn_cfm)
11373a6d576bSJohan Hedberg 			cb->disconn_cfm(conn, reason);
11383a6d576bSJohan Hedberg 	}
11393a6d576bSJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
11403a6d576bSJohan Hedberg 
11413a6d576bSJohan Hedberg 	if (conn->disconn_cfm_cb)
11423a6d576bSJohan Hedberg 		conn->disconn_cfm_cb(conn, reason);
11433a6d576bSJohan Hedberg }
11443a6d576bSJohan Hedberg 
11451da177e4SLinus Torvalds static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
11461da177e4SLinus Torvalds {
1147711584eaSDenis Kirjanov 	struct hci_cb *cb;
11488c1b2355SMarcel Holtmann 	__u8 encrypt;
11491da177e4SLinus Torvalds 
115051a8efd7SJohan Hedberg 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
11518c1b2355SMarcel Holtmann 		return;
11528c1b2355SMarcel Holtmann 
11534dae2798SJohan Hedberg 	encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
11548c1b2355SMarcel Holtmann 
1155fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
1156711584eaSDenis Kirjanov 	list_for_each_entry(cb, &hci_cb_list, list) {
11578c1b2355SMarcel Holtmann 		if (cb->security_cfm)
11588c1b2355SMarcel Holtmann 			cb->security_cfm(conn, status, encrypt);
11591da177e4SLinus Torvalds 	}
1160fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
1161354fe804SJohan Hedberg 
1162354fe804SJohan Hedberg 	if (conn->security_cfm_cb)
1163354fe804SJohan Hedberg 		conn->security_cfm_cb(conn, status);
11641da177e4SLinus Torvalds }
11651da177e4SLinus Torvalds 
11665a9d0a3fSWaldemar Rymarkiewicz static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
11675a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt)
11681da177e4SLinus Torvalds {
1169711584eaSDenis Kirjanov 	struct hci_cb *cb;
11701da177e4SLinus Torvalds 
1171435fef20SMarcel Holtmann 	if (conn->sec_level == BT_SECURITY_SDP)
1172435fef20SMarcel Holtmann 		conn->sec_level = BT_SECURITY_LOW;
1173435fef20SMarcel Holtmann 
117488167aedSVinicius Costa Gomes 	if (conn->pending_sec_level > conn->sec_level)
117588167aedSVinicius Costa Gomes 		conn->sec_level = conn->pending_sec_level;
117688167aedSVinicius Costa Gomes 
1177fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
1178711584eaSDenis Kirjanov 	list_for_each_entry(cb, &hci_cb_list, list) {
11798c1b2355SMarcel Holtmann 		if (cb->security_cfm)
11808c1b2355SMarcel Holtmann 			cb->security_cfm(conn, status, encrypt);
11811da177e4SLinus Torvalds 	}
1182fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
1183354fe804SJohan Hedberg 
1184354fe804SJohan Hedberg 	if (conn->security_cfm_cb)
1185354fe804SJohan Hedberg 		conn->security_cfm_cb(conn, status);
11861da177e4SLinus Torvalds }
11871da177e4SLinus Torvalds 
11881da177e4SLinus Torvalds static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
11891da177e4SLinus Torvalds {
1190711584eaSDenis Kirjanov 	struct hci_cb *cb;
11911da177e4SLinus Torvalds 
1192fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
1193711584eaSDenis Kirjanov 	list_for_each_entry(cb, &hci_cb_list, list) {
11941da177e4SLinus Torvalds 		if (cb->key_change_cfm)
11951da177e4SLinus Torvalds 			cb->key_change_cfm(conn, status);
11961da177e4SLinus Torvalds 	}
1197fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
11981da177e4SLinus Torvalds }
11991da177e4SLinus Torvalds 
12005a9d0a3fSWaldemar Rymarkiewicz static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
12015a9d0a3fSWaldemar Rymarkiewicz 								__u8 role)
12021da177e4SLinus Torvalds {
1203711584eaSDenis Kirjanov 	struct hci_cb *cb;
12041da177e4SLinus Torvalds 
1205fba7ecf0SJohan Hedberg 	mutex_lock(&hci_cb_list_lock);
1206711584eaSDenis Kirjanov 	list_for_each_entry(cb, &hci_cb_list, list) {
12071da177e4SLinus Torvalds 		if (cb->role_switch_cfm)
12081da177e4SLinus Torvalds 			cb->role_switch_cfm(conn, status, role);
12091da177e4SLinus Torvalds 	}
1210fba7ecf0SJohan Hedberg 	mutex_unlock(&hci_cb_list_lock);
12111da177e4SLinus Torvalds }
12121da177e4SLinus Torvalds 
12136759a675SJohan Hedberg static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
12146759a675SJohan Hedberg {
121584d9d071SJohan Hedberg 	size_t parsed = 0;
12166759a675SJohan Hedberg 
12176c0c331eSJohan Hedberg 	if (data_len < 2)
12186c0c331eSJohan Hedberg 		return false;
12196c0c331eSJohan Hedberg 
122084d9d071SJohan Hedberg 	while (parsed < data_len - 1) {
122184d9d071SJohan Hedberg 		u8 field_len = data[0];
12226759a675SJohan Hedberg 
12236759a675SJohan Hedberg 		if (field_len == 0)
12246759a675SJohan Hedberg 			break;
12256759a675SJohan Hedberg 
12266759a675SJohan Hedberg 		parsed += field_len + 1;
12276759a675SJohan Hedberg 
12286759a675SJohan Hedberg 		if (parsed > data_len)
12296759a675SJohan Hedberg 			break;
12306759a675SJohan Hedberg 
12316759a675SJohan Hedberg 		if (data[1] == type)
12326759a675SJohan Hedberg 			return true;
12336759a675SJohan Hedberg 
12346759a675SJohan Hedberg 		data += field_len + 1;
12356759a675SJohan Hedberg 	}
12366759a675SJohan Hedberg 
12376759a675SJohan Hedberg 	return false;
12386759a675SJohan Hedberg }
12396759a675SJohan Hedberg 
1240301cb2d8SJohan Hedberg static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
1241301cb2d8SJohan Hedberg {
1242dbbfa2abSAndre Guedes 	if (addr_type != ADDR_LE_DEV_RANDOM)
1243301cb2d8SJohan Hedberg 		return false;
1244301cb2d8SJohan Hedberg 
1245301cb2d8SJohan Hedberg 	if ((bdaddr->b[5] & 0xc0) == 0x40)
1246301cb2d8SJohan Hedberg 	       return true;
1247301cb2d8SJohan Hedberg 
1248301cb2d8SJohan Hedberg 	return false;
1249301cb2d8SJohan Hedberg }
1250301cb2d8SJohan Hedberg 
1251c46245b3SJohan Hedberg static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type)
1252c46245b3SJohan Hedberg {
1253c46245b3SJohan Hedberg 	if (addr_type == ADDR_LE_DEV_PUBLIC)
1254c46245b3SJohan Hedberg 		return true;
1255c46245b3SJohan Hedberg 
1256c46245b3SJohan Hedberg 	/* Check for Random Static address type */
1257c46245b3SJohan Hedberg 	if ((addr->b[5] & 0xc0) == 0xc0)
1258c46245b3SJohan Hedberg 		return true;
1259c46245b3SJohan Hedberg 
1260c46245b3SJohan Hedberg 	return false;
1261c46245b3SJohan Hedberg }
1262c46245b3SJohan Hedberg 
12632426f3a5SJohan Hedberg static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
12642426f3a5SJohan Hedberg 					  bdaddr_t *bdaddr, u8 addr_type)
12652426f3a5SJohan Hedberg {
12662426f3a5SJohan Hedberg 	if (!hci_bdaddr_is_rpa(bdaddr, addr_type))
12672426f3a5SJohan Hedberg 		return NULL;
12682426f3a5SJohan Hedberg 
12692426f3a5SJohan Hedberg 	return hci_find_irk_by_rpa(hdev, bdaddr);
12702426f3a5SJohan Hedberg }
12712426f3a5SJohan Hedberg 
1272d4905f24SAndre Guedes static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
1273d4905f24SAndre Guedes 					u16 to_multiplier)
1274d4905f24SAndre Guedes {
1275d4905f24SAndre Guedes 	u16 max_latency;
1276d4905f24SAndre Guedes 
1277d4905f24SAndre Guedes 	if (min > max || min < 6 || max > 3200)
1278d4905f24SAndre Guedes 		return -EINVAL;
1279d4905f24SAndre Guedes 
1280d4905f24SAndre Guedes 	if (to_multiplier < 10 || to_multiplier > 3200)
1281d4905f24SAndre Guedes 		return -EINVAL;
1282d4905f24SAndre Guedes 
1283d4905f24SAndre Guedes 	if (max >= to_multiplier * 8)
1284d4905f24SAndre Guedes 		return -EINVAL;
1285d4905f24SAndre Guedes 
1286d4905f24SAndre Guedes 	max_latency = (to_multiplier * 8 / max) - 1;
1287d4905f24SAndre Guedes 	if (latency > 499 || latency > max_latency)
1288d4905f24SAndre Guedes 		return -EINVAL;
1289d4905f24SAndre Guedes 
1290d4905f24SAndre Guedes 	return 0;
1291d4905f24SAndre Guedes }
1292d4905f24SAndre Guedes 
12931da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *hcb);
12941da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *hcb);
12951da177e4SLinus Torvalds 
129675e84b7cSJohan Hedberg struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
129707dc93ddSJohan Hedberg 			       const void *param, u32 timeout);
12987b1abbbeSJohan Hedberg struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
129907dc93ddSJohan Hedberg 				  const void *param, u8 event, u32 timeout);
130075e84b7cSJohan Hedberg 
130107dc93ddSJohan Hedberg int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen,
130207dc93ddSJohan Hedberg 		 const void *param);
130373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
13040d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
13051da177e4SLinus Torvalds 
1306a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
13071da177e4SLinus Torvalds 
13081da177e4SLinus Torvalds /* ----- HCI Sockets ----- */
1309470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
13107129069eSJohan Hedberg void hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
1311c08b1a1dSMarcel Holtmann 			 int flag, struct sock *skip_sk);
1312cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb);
13131da177e4SLinus Torvalds 
1314040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event);
1315040030efSMarcel Holtmann 
1316a958452aSMarcel Holtmann #define HCI_MGMT_VAR_LEN	BIT(0)
1317a958452aSMarcel Holtmann #define HCI_MGMT_NO_HDEV	BIT(1)
1318a958452aSMarcel Holtmann #define HCI_MGMT_UNTRUSTED	BIT(2)
1319a958452aSMarcel Holtmann #define HCI_MGMT_UNCONFIGURED	BIT(3)
1320b9a245fbSJohan Hedberg 
1321801c1e8dSJohan Hedberg struct hci_mgmt_handler {
1322801c1e8dSJohan Hedberg 	int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
1323801c1e8dSJohan Hedberg 		     u16 data_len);
1324801c1e8dSJohan Hedberg 	size_t data_len;
1325b9a245fbSJohan Hedberg 	unsigned long flags;
1326801c1e8dSJohan Hedberg };
1327801c1e8dSJohan Hedberg 
1328801c1e8dSJohan Hedberg struct hci_mgmt_chan {
1329801c1e8dSJohan Hedberg 	struct list_head list;
1330801c1e8dSJohan Hedberg 	unsigned short channel;
1331801c1e8dSJohan Hedberg 	size_t handler_count;
1332801c1e8dSJohan Hedberg 	const struct hci_mgmt_handler *handlers;
133388b94ce9SJohan Hedberg 	void (*hdev_init) (struct sock *sk, struct hci_dev *hdev);
1334801c1e8dSJohan Hedberg };
1335801c1e8dSJohan Hedberg 
1336801c1e8dSJohan Hedberg int hci_mgmt_chan_register(struct hci_mgmt_chan *c);
1337801c1e8dSJohan Hedberg void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);
1338801c1e8dSJohan Hedberg 
13390381101fSJohan Hedberg /* Management interface */
1340591f47f3SAndre Guedes #define DISCOV_TYPE_BREDR		(BIT(BDADDR_BREDR))
1341591f47f3SAndre Guedes #define DISCOV_TYPE_LE			(BIT(BDADDR_LE_PUBLIC) | \
1342591f47f3SAndre Guedes 					 BIT(BDADDR_LE_RANDOM))
1343591f47f3SAndre Guedes #define DISCOV_TYPE_INTERLEAVED		(BIT(BDADDR_BREDR) | \
1344591f47f3SAndre Guedes 					 BIT(BDADDR_LE_PUBLIC) | \
1345591f47f3SAndre Guedes 					 BIT(BDADDR_LE_RANDOM))
1346f39799f5SAndre Guedes 
13470d8cc935SAndre Guedes /* These LE scan and inquiry parameters were chosen according to LE General
13480d8cc935SAndre Guedes  * Discovery Procedure specification.
13490d8cc935SAndre Guedes  */
13500d8cc935SAndre Guedes #define DISCOV_LE_SCAN_WIN		0x12
13510d8cc935SAndre Guedes #define DISCOV_LE_SCAN_INT		0x12
13523d5a76f0SLukasz Rymanowski #define DISCOV_LE_TIMEOUT		10240	/* msec */
1353ae55f598SLukasz Rymanowski #define DISCOV_INTERLEAVED_TIMEOUT	5120	/* msec */
13540d8cc935SAndre Guedes #define DISCOV_INTERLEAVED_INQUIRY_LEN	0x04
13550d8cc935SAndre Guedes #define DISCOV_BREDR_INQUIRY_LEN	0x08
13564b0e0cedSJakub Pawlowski #define DISCOV_LE_RESTART_DELAY		msecs_to_jiffies(200)	/* msec */
13570d8cc935SAndre Guedes 
135891a668b0SJohan Hedberg int mgmt_new_settings(struct hci_dev *hdev);
1359bf6b56dbSMarcel Holtmann void mgmt_index_added(struct hci_dev *hdev);
1360bf6b56dbSMarcel Holtmann void mgmt_index_removed(struct hci_dev *hdev);
13613eec705eSMarcel Holtmann void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
1362744cf19eSJohan Hedberg int mgmt_powered(struct hci_dev *hdev, u8 powered);
1363bc6d2d04SJohan Hedberg int mgmt_update_adv_data(struct hci_dev *hdev);
1364d1967ff8SMarcel Holtmann void mgmt_discoverable_timeout(struct hci_dev *hdev);
1365dc4a5ee2SMarcel Holtmann void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
1366745c0ce3SVishal Agarwal 		       bool persistent);
136748ec92faSAlfonso Acosta void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn,
136848ec92faSAlfonso Acosta 			   u32 flags, u8 *name, u8 name_len);
13699b80ec5eSMarcel Holtmann void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
137012d4a3b2SJohan Hedberg 			      u8 link_type, u8 addr_type, u8 reason,
137112d4a3b2SJohan Hedberg 			      bool mgmt_connected);
13727892924cSMarcel Holtmann void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
137388c3df13SJohan Hedberg 			    u8 link_type, u8 addr_type, u8 status);
1374445608d0SMarcel Holtmann void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
137548264f06SJohan Hedberg 			 u8 addr_type, u8 status);
1376ce0e4a0dSMarcel Holtmann void mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
1377e669cf80SMarcel Holtmann void mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
1378c35938b2SSzymon Janc 				  u8 status);
13793eb38528SMarcel Holtmann void mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
1380744cf19eSJohan Hedberg 				      u8 status);
1381744cf19eSJohan Hedberg int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
138239adbffeSJohan Hedberg 			      u8 link_type, u8 addr_type, u32 value,
1383272d90dfSJohan Hedberg 			      u8 confirm_hint);
1384744cf19eSJohan Hedberg int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
1385272d90dfSJohan Hedberg 				     u8 link_type, u8 addr_type, u8 status);
1386272d90dfSJohan Hedberg int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
1387272d90dfSJohan Hedberg 					 u8 link_type, u8 addr_type, u8 status);
1388272d90dfSJohan Hedberg int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
1389272d90dfSJohan Hedberg 			      u8 link_type, u8 addr_type);
1390604086b7SBrian Gix int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
1391272d90dfSJohan Hedberg 				     u8 link_type, u8 addr_type, u8 status);
1392272d90dfSJohan Hedberg int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
1393272d90dfSJohan Hedberg 					 u8 link_type, u8 addr_type, u8 status);
139492a25256SJohan Hedberg int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr,
139592a25256SJohan Hedberg 			     u8 link_type, u8 addr_type, u32 passkey,
139692a25256SJohan Hedberg 			     u8 entered);
1397e1e930f5SJohan Hedberg void mgmt_auth_failed(struct hci_conn *conn, u8 status);
1398464996aeSMarcel Holtmann void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status);
13993e248560SMarcel Holtmann void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status);
14004e1b0245SMarcel Holtmann void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
14017f9a903cSMarcel Holtmann 				    u8 status);
14027667da34SMarcel Holtmann void mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
1403901801b9SMarcel Holtmann void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1404af58925cSMarcel Holtmann 		       u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
1405af58925cSMarcel Holtmann 		       u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len);
14069cf12aeeSMarcel Holtmann void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
1407b644ba33SJohan Hedberg 		      u8 addr_type, s8 rssi, u8 *name, u8 name_len);
14082f1e063bSMarcel Holtmann void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
140984c61d92SJohan Hedberg bool mgmt_powering_down(struct hci_dev *hdev);
141053ac6ab6SMarcel Holtmann void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
141195fbac8aSJohan Hedberg void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
141253ac6ab6SMarcel Holtmann void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
141353ac6ab6SMarcel Holtmann 		   bool persistent);
1414ffb5a827SAndre Guedes void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
1415f4869e2aSJohan Hedberg 			 u8 bdaddr_type, u8 store_hint, u16 min_interval,
1416f4869e2aSJohan Hedberg 			 u16 max_interval, u16 latency, u16 timeout);
14175976e608SMarcel Holtmann void mgmt_reenable_advertising(struct hci_dev *hdev);
1418f4a407beSJohan Hedberg void mgmt_smp_complete(struct hci_conn *conn, bool complete);
1419346af67bSVinicius Costa Gomes 
14207d6ca693SJohan Hedberg u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
14217d6ca693SJohan Hedberg 		      u16 to_multiplier);
1422fe39c7b2SMarcel Holtmann void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
14238b76ce34SJohan Hedberg 		      __u8 ltk[16], __u8 key_size);
14242519a1fcSAndre Guedes 
1425a1f4c318SJohan Hedberg void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
1426a1f4c318SJohan Hedberg 			       u8 *bdaddr_type);
1427ebd3a747SJohan Hedberg 
14285d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_MASK       0x0003
14295d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_CVSD       0x0000
14305d4d62f6SFrédéric Dalleau #define SCO_AIRMODE_TRANSP     0x0003
14315d4d62f6SFrédéric Dalleau 
14321da177e4SLinus Torvalds #endif /* __HCI_CORE_H */
1433