xref: /openbmc/linux/include/net/bluetooth/hci_core.h (revision 30883512)
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 
28a6b7a407SAlexey Dobriyan #include <linux/interrupt.h>
291da177e4SLinus Torvalds #include <net/bluetooth/hci.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 {
60561aafbcSJohan Hedberg 	struct list_head all;		/* All devices found during inquiry */
61561aafbcSJohan Hedberg 	struct list_head unknown;	/* Name state not known */
62561aafbcSJohan Hedberg 	struct list_head resolve;	/* Name needs to be resolved */
631da177e4SLinus Torvalds 	__u32		timestamp;
641da177e4SLinus Torvalds };
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds struct hci_conn_hash {
671da177e4SLinus Torvalds 	struct list_head list;
681da177e4SLinus Torvalds 	unsigned int     acl_num;
691da177e4SLinus Torvalds 	unsigned int     sco_num;
70fcd89c09SVille Tervo 	unsigned int     le_num;
711da177e4SLinus Torvalds };
721da177e4SLinus Torvalds 
73f0358568SJohan Hedberg struct bdaddr_list {
74f0358568SJohan Hedberg 	struct list_head list;
75f0358568SJohan Hedberg 	bdaddr_t bdaddr;
76f0358568SJohan Hedberg };
772aeb9a1aSJohan Hedberg 
782aeb9a1aSJohan Hedberg struct bt_uuid {
792aeb9a1aSJohan Hedberg 	struct list_head list;
802aeb9a1aSJohan Hedberg 	u8 uuid[16];
811aff6f09SJohan Hedberg 	u8 svc_hint;
822aeb9a1aSJohan Hedberg };
832aeb9a1aSJohan Hedberg 
8434918cd7SVinicius Costa Gomes struct key_master_id {
8534918cd7SVinicius Costa Gomes 	__le16 ediv;
8634918cd7SVinicius Costa Gomes 	u8 rand[8];
8734918cd7SVinicius Costa Gomes } __packed;
8834918cd7SVinicius Costa Gomes 
8934918cd7SVinicius Costa Gomes struct link_key_data {
9034918cd7SVinicius Costa Gomes 	bdaddr_t bdaddr;
9134918cd7SVinicius Costa Gomes 	u8 type;
9234918cd7SVinicius Costa Gomes 	u8 val[16];
9334918cd7SVinicius Costa Gomes 	u8 pin_len;
9434918cd7SVinicius Costa Gomes 	u8 dlen;
9534918cd7SVinicius Costa Gomes 	u8 data[0];
9634918cd7SVinicius Costa Gomes } __packed;
9734918cd7SVinicius Costa Gomes 
9855ed8ca1SJohan Hedberg struct link_key {
9955ed8ca1SJohan Hedberg 	struct list_head list;
10055ed8ca1SJohan Hedberg 	bdaddr_t bdaddr;
10155ed8ca1SJohan Hedberg 	u8 type;
10255ed8ca1SJohan Hedberg 	u8 val[16];
10355ed8ca1SJohan Hedberg 	u8 pin_len;
10434918cd7SVinicius Costa Gomes 	u8 dlen;
10534918cd7SVinicius Costa Gomes 	u8 data[0];
10655ed8ca1SJohan Hedberg };
10755ed8ca1SJohan Hedberg 
1082763eda6SSzymon Janc struct oob_data {
1092763eda6SSzymon Janc 	struct list_head list;
1102763eda6SSzymon Janc 	bdaddr_t bdaddr;
1112763eda6SSzymon Janc 	u8 hash[16];
1122763eda6SSzymon Janc 	u8 randomizer[16];
1132763eda6SSzymon Janc };
1142763eda6SSzymon Janc 
11576c8686fSAndre Guedes struct adv_entry {
11676c8686fSAndre Guedes 	struct list_head list;
11776c8686fSAndre Guedes 	bdaddr_t bdaddr;
11876c8686fSAndre Guedes 	u8 bdaddr_type;
11976c8686fSAndre Guedes };
12076c8686fSAndre Guedes 
121cd4c5391SSuraj Sumangala #define NUM_REASSEMBLY 4
1221da177e4SLinus Torvalds struct hci_dev {
1231da177e4SLinus Torvalds 	struct list_head list;
12409fd0de5SGustavo F. Padovan 	struct mutex	lock;
1251da177e4SLinus Torvalds 	atomic_t	refcnt;
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 	char		name[8];
1281da177e4SLinus Torvalds 	unsigned long	flags;
1291da177e4SLinus Torvalds 	__u16		id;
130c13854ceSMarcel Holtmann 	__u8		bus;
131943da25dSMarcel Holtmann 	__u8		dev_type;
1321da177e4SLinus Torvalds 	bdaddr_t	bdaddr;
1331f6c6378SJohan Hedberg 	__u8		dev_name[HCI_MAX_NAME_LENGTH];
13480a1e1dbSJohan Hedberg 	__u8		eir[HCI_MAX_EIR_LENGTH];
135a9de9248SMarcel Holtmann 	__u8		dev_class[3];
1361aff6f09SJohan Hedberg 	__u8		major_class;
1371aff6f09SJohan Hedberg 	__u8		minor_class;
1381da177e4SLinus Torvalds 	__u8		features[8];
13959e29406SAndre Guedes 	__u8		host_features[8];
140a9de9248SMarcel Holtmann 	__u8		commands[64];
141333140b5SMarcel Holtmann 	__u8		ssp_mode;
1421143e5a6SMarcel Holtmann 	__u8		hci_ver;
1431143e5a6SMarcel Holtmann 	__u16		hci_rev;
144d5859e22SJohan Hedberg 	__u8		lmp_ver;
1451143e5a6SMarcel Holtmann 	__u16		manufacturer;
146d5859e22SJohan Hedberg 	__le16		lmp_subver;
1471da177e4SLinus Torvalds 	__u16		voice_setting;
14817fa4b9dSJohan Hedberg 	__u8		io_capability;
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	__u16		pkt_type;
1515b7f9909SMarcel Holtmann 	__u16		esco_type;
1521da177e4SLinus Torvalds 	__u16		link_policy;
1531da177e4SLinus Torvalds 	__u16		link_mode;
1541da177e4SLinus Torvalds 
15504837f64SMarcel Holtmann 	__u32		idle_timeout;
15604837f64SMarcel Holtmann 	__u16		sniff_min_interval;
15704837f64SMarcel Holtmann 	__u16		sniff_max_interval;
15804837f64SMarcel Holtmann 
159928abaa7SAndrei Emeltchenko 	__u8		amp_status;
160928abaa7SAndrei Emeltchenko 	__u32		amp_total_bw;
161928abaa7SAndrei Emeltchenko 	__u32		amp_max_bw;
162928abaa7SAndrei Emeltchenko 	__u32		amp_min_latency;
163928abaa7SAndrei Emeltchenko 	__u32		amp_max_pdu;
164928abaa7SAndrei Emeltchenko 	__u8		amp_type;
165928abaa7SAndrei Emeltchenko 	__u16		amp_pal_cap;
166928abaa7SAndrei Emeltchenko 	__u16		amp_assoc_size;
167928abaa7SAndrei Emeltchenko 	__u32		amp_max_flush_to;
168928abaa7SAndrei Emeltchenko 	__u32		amp_be_flush_to;
169928abaa7SAndrei Emeltchenko 
1701e89cffbSAndrei Emeltchenko 	__u8		flow_ctl_mode;
1711e89cffbSAndrei Emeltchenko 
1729f61656aSJohan Hedberg 	unsigned int	auto_accept_delay;
1739f61656aSJohan Hedberg 
1741da177e4SLinus Torvalds 	unsigned long	quirks;
1751da177e4SLinus Torvalds 
1761da177e4SLinus Torvalds 	atomic_t	cmd_cnt;
1771da177e4SLinus Torvalds 	unsigned int	acl_cnt;
1781da177e4SLinus Torvalds 	unsigned int	sco_cnt;
1796ed58ec5SVille Tervo 	unsigned int	le_cnt;
1801da177e4SLinus Torvalds 
1811da177e4SLinus Torvalds 	unsigned int	acl_mtu;
1821da177e4SLinus Torvalds 	unsigned int	sco_mtu;
1836ed58ec5SVille Tervo 	unsigned int	le_mtu;
1841da177e4SLinus Torvalds 	unsigned int	acl_pkts;
1851da177e4SLinus Torvalds 	unsigned int	sco_pkts;
1866ed58ec5SVille Tervo 	unsigned int	le_pkts;
1871da177e4SLinus Torvalds 
188350ee4cfSAndrei Emeltchenko 	__u16		block_len;
189350ee4cfSAndrei Emeltchenko 	__u16		block_mtu;
190350ee4cfSAndrei Emeltchenko 	__u16		num_blocks;
191350ee4cfSAndrei Emeltchenko 	__u16		block_cnt;
192350ee4cfSAndrei Emeltchenko 
1931da177e4SLinus Torvalds 	unsigned long	acl_last_tx;
1941da177e4SLinus Torvalds 	unsigned long	sco_last_tx;
1956ed58ec5SVille Tervo 	unsigned long	le_last_tx;
1961da177e4SLinus Torvalds 
197f48fd9c8SMarcel Holtmann 	struct workqueue_struct	*workqueue;
198f48fd9c8SMarcel Holtmann 
199ab81cbf9SJohan Hedberg 	struct work_struct	power_on;
2003243553fSJohan Hedberg 	struct delayed_work	power_off;
201ab81cbf9SJohan Hedberg 
20216ab91abSJohan Hedberg 	__u16			discov_timeout;
20316ab91abSJohan Hedberg 	struct delayed_work	discov_off;
20416ab91abSJohan Hedberg 
2057d78525dSJohan Hedberg 	struct delayed_work	service_cache;
2067d78525dSJohan Hedberg 
2076bd32326SVille Tervo 	struct timer_list	cmd_timer;
208b78752ccSMarcel Holtmann 
209b78752ccSMarcel Holtmann 	struct work_struct	rx_work;
210c347b765SGustavo F. Padovan 	struct work_struct	cmd_work;
2113eff45eaSGustavo F. Padovan 	struct work_struct	tx_work;
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds 	struct sk_buff_head	rx_q;
2141da177e4SLinus Torvalds 	struct sk_buff_head	raw_q;
2151da177e4SLinus Torvalds 	struct sk_buff_head	cmd_q;
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds 	struct sk_buff		*sent_cmd;
218cd4c5391SSuraj Sumangala 	struct sk_buff		*reassembly[NUM_REASSEMBLY];
2191da177e4SLinus Torvalds 
220a6a67efdSThomas Gleixner 	struct mutex		req_lock;
2211da177e4SLinus Torvalds 	wait_queue_head_t	req_wait_q;
2221da177e4SLinus Torvalds 	__u32			req_status;
2231da177e4SLinus Torvalds 	__u32			req_result;
224a5040efaSJohan Hedberg 
225a5040efaSJohan Hedberg 	__u16			init_last_cmd;
2261da177e4SLinus Torvalds 
2272e58ef3eSJohan Hedberg 	struct list_head	mgmt_pending;
2282e58ef3eSJohan Hedberg 
22930883512SJohan Hedberg 	struct discovery_state	discovery;
2301da177e4SLinus Torvalds 	struct hci_conn_hash	conn_hash;
231ea4bd8baSDavid Miller 	struct list_head	blacklist;
2321da177e4SLinus Torvalds 
2332aeb9a1aSJohan Hedberg 	struct list_head	uuids;
2342aeb9a1aSJohan Hedberg 
23555ed8ca1SJohan Hedberg 	struct list_head	link_keys;
23655ed8ca1SJohan Hedberg 
2372763eda6SSzymon Janc 	struct list_head	remote_oob_data;
2382763eda6SSzymon Janc 
23976c8686fSAndre Guedes 	struct list_head	adv_entries;
240db323f2fSGustavo F. Padovan 	struct delayed_work	adv_work;
24176c8686fSAndre Guedes 
2421da177e4SLinus Torvalds 	struct hci_dev_stats	stat;
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds 	struct sk_buff_head	driver_init;
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds 	void			*driver_data;
2471da177e4SLinus Torvalds 	void			*core_data;
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds 	atomic_t		promisc;
2501da177e4SLinus Torvalds 
251ca325f69SMarcel Holtmann 	struct dentry		*debugfs;
252ca325f69SMarcel Holtmann 
253a91f2e39SMarcel Holtmann 	struct device		*parent;
254a91f2e39SMarcel Holtmann 	struct device		dev;
2551da177e4SLinus Torvalds 
256611b30f7SMarcel Holtmann 	struct rfkill		*rfkill;
257611b30f7SMarcel Holtmann 
2581da177e4SLinus Torvalds 	struct module		*owner;
2591da177e4SLinus Torvalds 
260d23264a8SAndre Guedes 	unsigned long		dev_flags;
261d23264a8SAndre Guedes 
2621da177e4SLinus Torvalds 	int (*open)(struct hci_dev *hdev);
2631da177e4SLinus Torvalds 	int (*close)(struct hci_dev *hdev);
2641da177e4SLinus Torvalds 	int (*flush)(struct hci_dev *hdev);
2651da177e4SLinus Torvalds 	int (*send)(struct sk_buff *skb);
2661da177e4SLinus Torvalds 	void (*destruct)(struct hci_dev *hdev);
2671da177e4SLinus Torvalds 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
2681da177e4SLinus Torvalds 	int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
2691da177e4SLinus Torvalds };
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds struct hci_conn {
2721da177e4SLinus Torvalds 	struct list_head list;
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds 	atomic_t	refcnt;
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds 	bdaddr_t	dst;
27729b7988aSAndre Guedes 	__u8		dst_type;
2781da177e4SLinus Torvalds 	__u16		handle;
2791da177e4SLinus Torvalds 	__u16		state;
28004837f64SMarcel Holtmann 	__u8		mode;
2811da177e4SLinus Torvalds 	__u8		type;
2821da177e4SLinus Torvalds 	__u8		out;
2834c67bc74SMarcel Holtmann 	__u8		attempt;
2841da177e4SLinus Torvalds 	__u8		dev_class[3];
28504837f64SMarcel Holtmann 	__u8		features[8];
28641a96212SMarcel Holtmann 	__u8		ssp_mode;
28704837f64SMarcel Holtmann 	__u16		interval;
288a8746417SMarcel Holtmann 	__u16		pkt_type;
28904837f64SMarcel Holtmann 	__u16		link_policy;
2901da177e4SLinus Torvalds 	__u32		link_mode;
29113d39315SWaldemar Rymarkiewicz 	__u8		key_type;
29240be492fSMarcel Holtmann 	__u8		auth_type;
2938c1b2355SMarcel Holtmann 	__u8		sec_level;
294765c2a96SJohan Hedberg 	__u8		pending_sec_level;
295980e1a53SJohan Hedberg 	__u8		pin_length;
296726b4ffcSVinicius Costa Gomes 	__u8		enc_key_size;
29717fa4b9dSJohan Hedberg 	__u8		io_capability;
29804837f64SMarcel Holtmann 	__u8		power_save;
299052b30b0SMarcel Holtmann 	__u16		disc_timeout;
3001da177e4SLinus Torvalds 	unsigned long	pend;
3011da177e4SLinus Torvalds 
30203b555e1SJohan Hedberg 	__u8		remote_cap;
30303b555e1SJohan Hedberg 	__u8		remote_oob;
30403b555e1SJohan Hedberg 	__u8		remote_auth;
30503b555e1SJohan Hedberg 
3061da177e4SLinus Torvalds 	unsigned int	sent;
3071da177e4SLinus Torvalds 
3081da177e4SLinus Torvalds 	struct sk_buff_head data_q;
3092c33c06aSGustavo F. Padovan 	struct list_head chan_list;
3101da177e4SLinus Torvalds 
31119c40e3bSGustavo F. Padovan 	struct delayed_work disc_work;
31204837f64SMarcel Holtmann 	struct timer_list idle_timer;
3139f61656aSJohan Hedberg 	struct timer_list auto_accept_timer;
3141da177e4SLinus Torvalds 
315b219e3acSMarcel Holtmann 	struct device	dev;
3169eba32b8SMarcel Holtmann 	atomic_t	devref;
317b219e3acSMarcel Holtmann 
3181da177e4SLinus Torvalds 	struct hci_dev	*hdev;
3191da177e4SLinus Torvalds 	void		*l2cap_data;
3201da177e4SLinus Torvalds 	void		*sco_data;
3212b64d153SBrian Gix 	void		*smp_conn;
3221da177e4SLinus Torvalds 
3231da177e4SLinus Torvalds 	struct hci_conn	*link;
324e9a416b5SJohan Hedberg 
325e9a416b5SJohan Hedberg 	void (*connect_cfm_cb)	(struct hci_conn *conn, u8 status);
326e9a416b5SJohan Hedberg 	void (*security_cfm_cb)	(struct hci_conn *conn, u8 status);
327e9a416b5SJohan Hedberg 	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
3281da177e4SLinus Torvalds };
3291da177e4SLinus Torvalds 
33073d80debSLuiz Augusto von Dentz struct hci_chan {
33173d80debSLuiz Augusto von Dentz 	struct list_head list;
33273d80debSLuiz Augusto von Dentz 
33373d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
33473d80debSLuiz Augusto von Dentz 	struct sk_buff_head data_q;
33573d80debSLuiz Augusto von Dentz 	unsigned int	sent;
33673d80debSLuiz Augusto von Dentz };
33773d80debSLuiz Augusto von Dentz 
3381da177e4SLinus Torvalds extern struct list_head hci_dev_list;
3391da177e4SLinus Torvalds extern struct list_head hci_cb_list;
3401da177e4SLinus Torvalds extern rwlock_t hci_dev_list_lock;
3411da177e4SLinus Torvalds extern rwlock_t hci_cb_list_lock;
3421da177e4SLinus Torvalds 
343686ebf28SUlisses Furquim /* ----- HCI interface to upper protocols ----- */
344686ebf28SUlisses Furquim extern int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
345686ebf28SUlisses Furquim extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status);
346686ebf28SUlisses Furquim extern int l2cap_disconn_ind(struct hci_conn *hcon);
347686ebf28SUlisses Furquim extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason);
348686ebf28SUlisses Furquim extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
349686ebf28SUlisses Furquim extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags);
350686ebf28SUlisses Furquim 
351686ebf28SUlisses Furquim extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
352686ebf28SUlisses Furquim extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status);
353686ebf28SUlisses Furquim extern int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
354686ebf28SUlisses Furquim extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
355686ebf28SUlisses Furquim 
3561da177e4SLinus Torvalds /* ----- Inquiry cache ----- */
35770f23020SAndrei Emeltchenko #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */
35870f23020SAndrei Emeltchenko #define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   /* 60 seconds */
3591da177e4SLinus Torvalds 
36030883512SJohan Hedberg static inline void discovery_init(struct hci_dev *hdev)
3611da177e4SLinus Torvalds {
36230883512SJohan Hedberg 	INIT_LIST_HEAD(&hdev->discovery.all);
36330883512SJohan Hedberg 	INIT_LIST_HEAD(&hdev->discovery.unknown);
36430883512SJohan Hedberg 	INIT_LIST_HEAD(&hdev->discovery.resolve);
3651da177e4SLinus Torvalds }
3661da177e4SLinus Torvalds 
3671da177e4SLinus Torvalds static inline int inquiry_cache_empty(struct hci_dev *hdev)
3681da177e4SLinus Torvalds {
36930883512SJohan Hedberg 	return list_empty(&hdev->discovery.all);
3701da177e4SLinus Torvalds }
3711da177e4SLinus Torvalds 
3721da177e4SLinus Torvalds static inline long inquiry_cache_age(struct hci_dev *hdev)
3731da177e4SLinus Torvalds {
37430883512SJohan Hedberg 	struct discovery_state *c = &hdev->discovery;
3751da177e4SLinus Torvalds 	return jiffies - c->timestamp;
3761da177e4SLinus Torvalds }
3771da177e4SLinus Torvalds 
3781da177e4SLinus Torvalds static inline long inquiry_entry_age(struct inquiry_entry *e)
3791da177e4SLinus Torvalds {
3801da177e4SLinus Torvalds 	return jiffies - e->timestamp;
3811da177e4SLinus Torvalds }
3821da177e4SLinus Torvalds 
3835a9d0a3fSWaldemar Rymarkiewicz struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
3845a9d0a3fSWaldemar Rymarkiewicz 							bdaddr_t *bdaddr);
385561aafbcSJohan Hedberg struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
386561aafbcSJohan Hedberg 							bdaddr_t *bdaddr);
3873175405bSJohan Hedberg bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
388561aafbcSJohan Hedberg 							bool name_known);
3891da177e4SLinus Torvalds 
3901da177e4SLinus Torvalds /* ----- HCI Connections ----- */
3911da177e4SLinus Torvalds enum {
3921da177e4SLinus Torvalds 	HCI_CONN_AUTH_PEND,
39319f8def0SWaldemar Rymarkiewicz 	HCI_CONN_REAUTH_PEND,
3941da177e4SLinus Torvalds 	HCI_CONN_ENCRYPT_PEND,
39504837f64SMarcel Holtmann 	HCI_CONN_RSWITCH_PEND,
39604837f64SMarcel Holtmann 	HCI_CONN_MODE_CHANGE_PEND,
397e73439d8SMarcel Holtmann 	HCI_CONN_SCO_SETUP_PEND,
398d26a2345SVinicius Costa Gomes 	HCI_CONN_LE_SMP_PEND,
3991da177e4SLinus Torvalds };
4001da177e4SLinus Torvalds 
4011da177e4SLinus Torvalds static inline void hci_conn_hash_init(struct hci_dev *hdev)
4021da177e4SLinus Torvalds {
4031da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
4041da177e4SLinus Torvalds 	INIT_LIST_HEAD(&h->list);
4051da177e4SLinus Torvalds 	h->acl_num = 0;
4061da177e4SLinus Torvalds 	h->sco_num = 0;
407dc8ed672SGustavo F. Padovan 	h->le_num = 0;
4081da177e4SLinus Torvalds }
4091da177e4SLinus Torvalds 
4101da177e4SLinus Torvalds static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
4111da177e4SLinus Torvalds {
4121da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
413bf4c6325SGustavo F. Padovan 	list_add_rcu(&c->list, &h->list);
414fcd89c09SVille Tervo 	switch (c->type) {
415fcd89c09SVille Tervo 	case ACL_LINK:
4161da177e4SLinus Torvalds 		h->acl_num++;
417fcd89c09SVille Tervo 		break;
418fcd89c09SVille Tervo 	case LE_LINK:
419fcd89c09SVille Tervo 		h->le_num++;
420fcd89c09SVille Tervo 		break;
421fcd89c09SVille Tervo 	case SCO_LINK:
422fcd89c09SVille Tervo 	case ESCO_LINK:
4231da177e4SLinus Torvalds 		h->sco_num++;
424fcd89c09SVille Tervo 		break;
425fcd89c09SVille Tervo 	}
4261da177e4SLinus Torvalds }
4271da177e4SLinus Torvalds 
4281da177e4SLinus Torvalds static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
4291da177e4SLinus Torvalds {
4301da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
431bf4c6325SGustavo F. Padovan 
432bf4c6325SGustavo F. Padovan 	list_del_rcu(&c->list);
433bf4c6325SGustavo F. Padovan 	synchronize_rcu();
434bf4c6325SGustavo F. Padovan 
435fcd89c09SVille Tervo 	switch (c->type) {
436fcd89c09SVille Tervo 	case ACL_LINK:
4371da177e4SLinus Torvalds 		h->acl_num--;
438fcd89c09SVille Tervo 		break;
439fcd89c09SVille Tervo 	case LE_LINK:
440fcd89c09SVille Tervo 		h->le_num--;
441fcd89c09SVille Tervo 		break;
442fcd89c09SVille Tervo 	case SCO_LINK:
443fcd89c09SVille Tervo 	case ESCO_LINK:
4441da177e4SLinus Torvalds 		h->sco_num--;
445fcd89c09SVille Tervo 		break;
446fcd89c09SVille Tervo 	}
4471da177e4SLinus Torvalds }
4481da177e4SLinus Torvalds 
44952087a79SLuiz Augusto von Dentz static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
45052087a79SLuiz Augusto von Dentz {
45152087a79SLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
45252087a79SLuiz Augusto von Dentz 	switch (type) {
45352087a79SLuiz Augusto von Dentz 	case ACL_LINK:
45452087a79SLuiz Augusto von Dentz 		return h->acl_num;
45552087a79SLuiz Augusto von Dentz 	case LE_LINK:
45652087a79SLuiz Augusto von Dentz 		return h->le_num;
45752087a79SLuiz Augusto von Dentz 	case SCO_LINK:
45852087a79SLuiz Augusto von Dentz 	case ESCO_LINK:
45952087a79SLuiz Augusto von Dentz 		return h->sco_num;
46052087a79SLuiz Augusto von Dentz 	default:
46152087a79SLuiz Augusto von Dentz 		return 0;
46252087a79SLuiz Augusto von Dentz 	}
46352087a79SLuiz Augusto von Dentz }
46452087a79SLuiz Augusto von Dentz 
4651da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
4661da177e4SLinus Torvalds 								__u16 handle)
4671da177e4SLinus Torvalds {
4681da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
4691da177e4SLinus Torvalds 	struct hci_conn  *c;
4701da177e4SLinus Torvalds 
471bf4c6325SGustavo F. Padovan 	rcu_read_lock();
472bf4c6325SGustavo F. Padovan 
473bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
474bf4c6325SGustavo F. Padovan 		if (c->handle == handle) {
475bf4c6325SGustavo F. Padovan 			rcu_read_unlock();
4761da177e4SLinus Torvalds 			return c;
4771da177e4SLinus Torvalds 		}
478bf4c6325SGustavo F. Padovan 	}
479bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
480bf4c6325SGustavo F. Padovan 
4811da177e4SLinus Torvalds 	return NULL;
4821da177e4SLinus Torvalds }
4831da177e4SLinus Torvalds 
4841da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
4851da177e4SLinus Torvalds 							__u8 type, bdaddr_t *ba)
4861da177e4SLinus Torvalds {
4871da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
4881da177e4SLinus Torvalds 	struct hci_conn  *c;
4891da177e4SLinus Torvalds 
490bf4c6325SGustavo F. Padovan 	rcu_read_lock();
491bf4c6325SGustavo F. Padovan 
492bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
493bf4c6325SGustavo F. Padovan 		if (c->type == type && !bacmp(&c->dst, ba)) {
494bf4c6325SGustavo F. Padovan 			rcu_read_unlock();
4951da177e4SLinus Torvalds 			return c;
4961da177e4SLinus Torvalds 		}
497bf4c6325SGustavo F. Padovan 	}
498bf4c6325SGustavo F. Padovan 
499bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
500bf4c6325SGustavo F. Padovan 
5011da177e4SLinus Torvalds 	return NULL;
5021da177e4SLinus Torvalds }
5031da177e4SLinus Torvalds 
5044c67bc74SMarcel Holtmann static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
5054c67bc74SMarcel Holtmann 							__u8 type, __u16 state)
5064c67bc74SMarcel Holtmann {
5074c67bc74SMarcel Holtmann 	struct hci_conn_hash *h = &hdev->conn_hash;
5084c67bc74SMarcel Holtmann 	struct hci_conn  *c;
5094c67bc74SMarcel Holtmann 
510bf4c6325SGustavo F. Padovan 	rcu_read_lock();
511bf4c6325SGustavo F. Padovan 
512bf4c6325SGustavo F. Padovan 	list_for_each_entry_rcu(c, &h->list, list) {
513bf4c6325SGustavo F. Padovan 		if (c->type == type && c->state == state) {
514bf4c6325SGustavo F. Padovan 			rcu_read_unlock();
5154c67bc74SMarcel Holtmann 			return c;
5164c67bc74SMarcel Holtmann 		}
517bf4c6325SGustavo F. Padovan 	}
518bf4c6325SGustavo F. Padovan 
519bf4c6325SGustavo F. Padovan 	rcu_read_unlock();
520bf4c6325SGustavo F. Padovan 
5214c67bc74SMarcel Holtmann 	return NULL;
5224c67bc74SMarcel Holtmann }
5234c67bc74SMarcel Holtmann 
5244c67bc74SMarcel Holtmann void hci_acl_connect(struct hci_conn *conn);
5251da177e4SLinus Torvalds void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
5261da177e4SLinus Torvalds void hci_add_sco(struct hci_conn *conn, __u16 handle);
527b6a0dc82SMarcel Holtmann void hci_setup_sync(struct hci_conn *conn, __u16 handle);
528e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status);
5291da177e4SLinus Torvalds 
5301da177e4SLinus Torvalds struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
5311da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn);
5321da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev);
533a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev);
5341da177e4SLinus Torvalds 
53573d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn);
53673d80debSLuiz Augusto von Dentz int hci_chan_del(struct hci_chan *chan);
5372c33c06aSGustavo F. Padovan void hci_chan_list_flush(struct hci_conn *conn);
53873d80debSLuiz Augusto von Dentz 
5395a9d0a3fSWaldemar Rymarkiewicz struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
5405a9d0a3fSWaldemar Rymarkiewicz 						__u8 sec_level, __u8 auth_type);
541e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn);
542b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
5430684e5f9SMarcel Holtmann int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
5441da177e4SLinus Torvalds int hci_conn_change_link_key(struct hci_conn *conn);
5458c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
5461da177e4SLinus Torvalds 
54714b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
5481da177e4SLinus Torvalds 
5499eba32b8SMarcel Holtmann void hci_conn_hold_device(struct hci_conn *conn);
5509eba32b8SMarcel Holtmann void hci_conn_put_device(struct hci_conn *conn);
5519eba32b8SMarcel Holtmann 
5521da177e4SLinus Torvalds static inline void hci_conn_hold(struct hci_conn *conn)
5531da177e4SLinus Torvalds {
5541da177e4SLinus Torvalds 	atomic_inc(&conn->refcnt);
55519c40e3bSGustavo F. Padovan 	cancel_delayed_work_sync(&conn->disc_work);
5561da177e4SLinus Torvalds }
5571da177e4SLinus Torvalds 
5581da177e4SLinus Torvalds static inline void hci_conn_put(struct hci_conn *conn)
5591da177e4SLinus Torvalds {
5601da177e4SLinus Torvalds 	if (atomic_dec_and_test(&conn->refcnt)) {
56104837f64SMarcel Holtmann 		unsigned long timeo;
562454d48ffSVinicius Costa Gomes 		if (conn->type == ACL_LINK || conn->type == LE_LINK) {
5636ac59344SMarcel Holtmann 			del_timer(&conn->idle_timer);
5646ac59344SMarcel Holtmann 			if (conn->state == BT_CONNECTED) {
565052b30b0SMarcel Holtmann 				timeo = msecs_to_jiffies(conn->disc_timeout);
56604837f64SMarcel Holtmann 				if (!conn->out)
567052b30b0SMarcel Holtmann 					timeo *= 2;
5685a9d0a3fSWaldemar Rymarkiewicz 			} else {
5696ac59344SMarcel Holtmann 				timeo = msecs_to_jiffies(10);
5705a9d0a3fSWaldemar Rymarkiewicz 			}
5715a9d0a3fSWaldemar Rymarkiewicz 		} else {
57204837f64SMarcel Holtmann 			timeo = msecs_to_jiffies(10);
5735a9d0a3fSWaldemar Rymarkiewicz 		}
57419c40e3bSGustavo F. Padovan 		cancel_delayed_work_sync(&conn->disc_work);
57519c40e3bSGustavo F. Padovan 		queue_delayed_work(conn->hdev->workqueue,
57619c40e3bSGustavo F. Padovan 					&conn->disc_work, jiffies + timeo);
5771da177e4SLinus Torvalds 	}
5781da177e4SLinus Torvalds }
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds /* ----- HCI Devices ----- */
5811da177e4SLinus Torvalds static inline void __hci_dev_put(struct hci_dev *d)
5821da177e4SLinus Torvalds {
5831da177e4SLinus Torvalds 	if (atomic_dec_and_test(&d->refcnt))
5841da177e4SLinus Torvalds 		d->destruct(d);
5851da177e4SLinus Torvalds }
5861da177e4SLinus Torvalds 
5871d58996dSPaul Gortmaker /*
5881d58996dSPaul Gortmaker  * hci_dev_put and hci_dev_hold are macros to avoid dragging all the
5891d58996dSPaul Gortmaker  * overhead of all the modular infrastructure into this header.
5901d58996dSPaul Gortmaker  */
5911d58996dSPaul Gortmaker #define hci_dev_put(d)		\
5921d58996dSPaul Gortmaker do {				\
5931d58996dSPaul Gortmaker 	__hci_dev_put(d);	\
5941d58996dSPaul Gortmaker 	module_put(d->owner);	\
5951d58996dSPaul Gortmaker } while (0)
5961da177e4SLinus Torvalds 
5971da177e4SLinus Torvalds static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
5981da177e4SLinus Torvalds {
5991da177e4SLinus Torvalds 	atomic_inc(&d->refcnt);
6001da177e4SLinus Torvalds 	return d;
6011da177e4SLinus Torvalds }
6021da177e4SLinus Torvalds 
6031d58996dSPaul Gortmaker #define hci_dev_hold(d)						\
6041d58996dSPaul Gortmaker ({								\
6051d58996dSPaul Gortmaker 	try_module_get(d->owner) ? __hci_dev_hold(d) : NULL;	\
6061d58996dSPaul Gortmaker })
6071da177e4SLinus Torvalds 
60809fd0de5SGustavo F. Padovan #define hci_dev_lock(d)		mutex_lock(&d->lock)
60909fd0de5SGustavo F. Padovan #define hci_dev_unlock(d)	mutex_unlock(&d->lock)
6101da177e4SLinus Torvalds 
6111da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index);
6121da177e4SLinus Torvalds struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
6131da177e4SLinus Torvalds 
6141da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void);
6151da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev);
6161da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev);
61759735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev);
6181da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev);
6191da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev);
6201da177e4SLinus Torvalds int hci_dev_open(__u16 dev);
6211da177e4SLinus Torvalds int hci_dev_close(__u16 dev);
6221da177e4SLinus Torvalds int hci_dev_reset(__u16 dev);
6231da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev);
6241da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg);
6251da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg);
6261da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg);
6271da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg);
6281da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
62940be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
6301da177e4SLinus Torvalds int hci_inquiry(void __user *arg);
6311da177e4SLinus Torvalds 
632f0358568SJohan Hedberg struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
633f0358568SJohan Hedberg int hci_blacklist_clear(struct hci_dev *hdev);
634b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr);
635b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr);
636f0358568SJohan Hedberg 
6372aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev);
6382aeb9a1aSJohan Hedberg 
63955ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev);
64055ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
641d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
642d25e28abSJohan Hedberg 			bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
64375d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
64475d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
64575d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type);
64675d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
647726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
64855ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
64955ed8ca1SJohan Hedberg 
6502763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev);
6512763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
6522763eda6SSzymon Janc 							bdaddr_t *bdaddr);
6532763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
6542763eda6SSzymon Janc 								u8 *randomizer);
6552763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
6562763eda6SSzymon Janc 
65735815085SAndre Guedes #define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */
65876c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev);
65976c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
66076c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
66176c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev);
66276c8686fSAndre Guedes 
663ab81cbf9SJohan Hedberg void hci_del_off_timer(struct hci_dev *hdev);
664ab81cbf9SJohan Hedberg 
6651da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
6661da177e4SLinus Torvalds 
66776bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb);
668ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
66999811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
670ef222013SMarcel Holtmann 
6710ac7e700SDavid Herrmann void hci_init_sysfs(struct hci_dev *hdev);
672ce242970SDavid Herrmann int hci_add_sysfs(struct hci_dev *hdev);
673ce242970SDavid Herrmann void hci_del_sysfs(struct hci_dev *hdev);
674a67e899cSMarcel Holtmann void hci_conn_init_sysfs(struct hci_conn *conn);
675b219e3acSMarcel Holtmann void hci_conn_add_sysfs(struct hci_conn *conn);
676b219e3acSMarcel Holtmann void hci_conn_del_sysfs(struct hci_conn *conn);
6771da177e4SLinus Torvalds 
678a91f2e39SMarcel Holtmann #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds /* ----- LMP capabilities ----- */
68104837f64SMarcel Holtmann #define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
68204837f64SMarcel Holtmann #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
68304837f64SMarcel Holtmann #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
68404837f64SMarcel Holtmann #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
6855b7f9909SMarcel Holtmann #define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
686769be974SMarcel Holtmann #define lmp_ssp_capable(dev)       ((dev)->features[6] & LMP_SIMPLE_PAIR)
687e702112fSAndrei Emeltchenko #define lmp_no_flush_capable(dev)  ((dev)->features[6] & LMP_NO_FLUSH)
6886ed58ec5SVille Tervo #define lmp_le_capable(dev)        ((dev)->features[4] & LMP_LE)
6891da177e4SLinus Torvalds 
690eead27daSAndre Guedes /* ----- Extended LMP capabilities ----- */
69159e29406SAndre Guedes #define lmp_host_le_capable(dev)   ((dev)->host_features[0] & LMP_HOST_LE)
692eead27daSAndre Guedes 
6931da177e4SLinus Torvalds /* ----- HCI protocols ----- */
6945a9d0a3fSWaldemar Rymarkiewicz static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
6955a9d0a3fSWaldemar Rymarkiewicz 								__u8 type)
6961da177e4SLinus Torvalds {
697686ebf28SUlisses Furquim 	switch (type) {
698686ebf28SUlisses Furquim 	case ACL_LINK:
699686ebf28SUlisses Furquim 		return l2cap_connect_ind(hdev, bdaddr);
7001da177e4SLinus Torvalds 
701686ebf28SUlisses Furquim 	case SCO_LINK:
702686ebf28SUlisses Furquim 	case ESCO_LINK:
703686ebf28SUlisses Furquim 		return sco_connect_ind(hdev, bdaddr);
7041da177e4SLinus Torvalds 
705686ebf28SUlisses Furquim 	default:
706686ebf28SUlisses Furquim 		BT_ERR("unknown link type %d", type);
707686ebf28SUlisses Furquim 		return -EINVAL;
708686ebf28SUlisses Furquim 	}
7091da177e4SLinus Torvalds }
7101da177e4SLinus Torvalds 
7111da177e4SLinus Torvalds static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
7121da177e4SLinus Torvalds {
713686ebf28SUlisses Furquim 	switch (conn->type) {
714686ebf28SUlisses Furquim 	case ACL_LINK:
715686ebf28SUlisses Furquim 	case LE_LINK:
716686ebf28SUlisses Furquim 		l2cap_connect_cfm(conn, status);
717686ebf28SUlisses Furquim 		break;
7181da177e4SLinus Torvalds 
719686ebf28SUlisses Furquim 	case SCO_LINK:
720686ebf28SUlisses Furquim 	case ESCO_LINK:
721686ebf28SUlisses Furquim 		sco_connect_cfm(conn, status);
722686ebf28SUlisses Furquim 		break;
7231da177e4SLinus Torvalds 
724686ebf28SUlisses Furquim 	default:
725686ebf28SUlisses Furquim 		BT_ERR("unknown link type %d", conn->type);
726686ebf28SUlisses Furquim 		break;
727686ebf28SUlisses Furquim 	}
728e9a416b5SJohan Hedberg 
729e9a416b5SJohan Hedberg 	if (conn->connect_cfm_cb)
730e9a416b5SJohan Hedberg 		conn->connect_cfm_cb(conn, status);
7311da177e4SLinus Torvalds }
7321da177e4SLinus Torvalds 
7332950f21aSMarcel Holtmann static inline int hci_proto_disconn_ind(struct hci_conn *conn)
7342950f21aSMarcel Holtmann {
735686ebf28SUlisses Furquim 	if (conn->type != ACL_LINK && conn->type != LE_LINK)
736686ebf28SUlisses Furquim 		return HCI_ERROR_REMOTE_USER_TERM;
7372950f21aSMarcel Holtmann 
738686ebf28SUlisses Furquim 	return l2cap_disconn_ind(conn);
7392950f21aSMarcel Holtmann }
7402950f21aSMarcel Holtmann 
7412950f21aSMarcel Holtmann static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
7421da177e4SLinus Torvalds {
743686ebf28SUlisses Furquim 	switch (conn->type) {
744686ebf28SUlisses Furquim 	case ACL_LINK:
745686ebf28SUlisses Furquim 	case LE_LINK:
746686ebf28SUlisses Furquim 		l2cap_disconn_cfm(conn, reason);
747686ebf28SUlisses Furquim 		break;
7481da177e4SLinus Torvalds 
749686ebf28SUlisses Furquim 	case SCO_LINK:
750686ebf28SUlisses Furquim 	case ESCO_LINK:
751686ebf28SUlisses Furquim 		sco_disconn_cfm(conn, reason);
752686ebf28SUlisses Furquim 		break;
7531da177e4SLinus Torvalds 
754686ebf28SUlisses Furquim 	default:
755686ebf28SUlisses Furquim 		BT_ERR("unknown link type %d", conn->type);
756686ebf28SUlisses Furquim 		break;
757686ebf28SUlisses Furquim 	}
758e9a416b5SJohan Hedberg 
759e9a416b5SJohan Hedberg 	if (conn->disconn_cfm_cb)
760e9a416b5SJohan Hedberg 		conn->disconn_cfm_cb(conn, reason);
7611da177e4SLinus Torvalds }
7621da177e4SLinus Torvalds 
7631da177e4SLinus Torvalds static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
7641da177e4SLinus Torvalds {
7658c1b2355SMarcel Holtmann 	__u8 encrypt;
7668c1b2355SMarcel Holtmann 
767686ebf28SUlisses Furquim 	if (conn->type != ACL_LINK && conn->type != LE_LINK)
768686ebf28SUlisses Furquim 		return;
769686ebf28SUlisses Furquim 
7708c1b2355SMarcel Holtmann 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
7718c1b2355SMarcel Holtmann 		return;
7728c1b2355SMarcel Holtmann 
7738c1b2355SMarcel Holtmann 	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
774686ebf28SUlisses Furquim 	l2cap_security_cfm(conn, status, encrypt);
775e9a416b5SJohan Hedberg 
776e9a416b5SJohan Hedberg 	if (conn->security_cfm_cb)
777e9a416b5SJohan Hedberg 		conn->security_cfm_cb(conn, status);
7781da177e4SLinus Torvalds }
7791da177e4SLinus Torvalds 
7805a9d0a3fSWaldemar Rymarkiewicz static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status,
7815a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt)
7821da177e4SLinus Torvalds {
783686ebf28SUlisses Furquim 	if (conn->type != ACL_LINK && conn->type != LE_LINK)
784686ebf28SUlisses Furquim 		return;
7851da177e4SLinus Torvalds 
786686ebf28SUlisses Furquim 	l2cap_security_cfm(conn, status, encrypt);
787e9a416b5SJohan Hedberg 
788e9a416b5SJohan Hedberg 	if (conn->security_cfm_cb)
789e9a416b5SJohan Hedberg 		conn->security_cfm_cb(conn, status);
7901da177e4SLinus Torvalds }
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds /* ----- HCI callbacks ----- */
7931da177e4SLinus Torvalds struct hci_cb {
7941da177e4SLinus Torvalds 	struct list_head list;
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds 	char *name;
7971da177e4SLinus Torvalds 
7985a9d0a3fSWaldemar Rymarkiewicz 	void (*security_cfm)	(struct hci_conn *conn, __u8 status,
7995a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt);
8001da177e4SLinus Torvalds 	void (*key_change_cfm)	(struct hci_conn *conn, __u8 status);
8011da177e4SLinus Torvalds 	void (*role_switch_cfm)	(struct hci_conn *conn, __u8 status, __u8 role);
8021da177e4SLinus Torvalds };
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
8051da177e4SLinus Torvalds {
8061da177e4SLinus Torvalds 	struct list_head *p;
8078c1b2355SMarcel Holtmann 	__u8 encrypt;
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds 	hci_proto_auth_cfm(conn, status);
8101da177e4SLinus Torvalds 
8118c1b2355SMarcel Holtmann 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
8128c1b2355SMarcel Holtmann 		return;
8138c1b2355SMarcel Holtmann 
8148c1b2355SMarcel Holtmann 	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
8158c1b2355SMarcel Holtmann 
816f20d09d5SGustavo F. Padovan 	read_lock(&hci_cb_list_lock);
8171da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8181da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8198c1b2355SMarcel Holtmann 		if (cb->security_cfm)
8208c1b2355SMarcel Holtmann 			cb->security_cfm(conn, status, encrypt);
8211da177e4SLinus Torvalds 	}
822f20d09d5SGustavo F. Padovan 	read_unlock(&hci_cb_list_lock);
8231da177e4SLinus Torvalds }
8241da177e4SLinus Torvalds 
8255a9d0a3fSWaldemar Rymarkiewicz static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
8265a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt)
8271da177e4SLinus Torvalds {
8281da177e4SLinus Torvalds 	struct list_head *p;
8291da177e4SLinus Torvalds 
830435fef20SMarcel Holtmann 	if (conn->sec_level == BT_SECURITY_SDP)
831435fef20SMarcel Holtmann 		conn->sec_level = BT_SECURITY_LOW;
832435fef20SMarcel Holtmann 
83388167aedSVinicius Costa Gomes 	if (conn->pending_sec_level > conn->sec_level)
83488167aedSVinicius Costa Gomes 		conn->sec_level = conn->pending_sec_level;
83588167aedSVinicius Costa Gomes 
8369719f8afSMarcel Holtmann 	hci_proto_encrypt_cfm(conn, status, encrypt);
8371da177e4SLinus Torvalds 
838f20d09d5SGustavo F. Padovan 	read_lock(&hci_cb_list_lock);
8391da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8401da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8418c1b2355SMarcel Holtmann 		if (cb->security_cfm)
8428c1b2355SMarcel Holtmann 			cb->security_cfm(conn, status, encrypt);
8431da177e4SLinus Torvalds 	}
844f20d09d5SGustavo F. Padovan 	read_unlock(&hci_cb_list_lock);
8451da177e4SLinus Torvalds }
8461da177e4SLinus Torvalds 
8471da177e4SLinus Torvalds static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
8481da177e4SLinus Torvalds {
8491da177e4SLinus Torvalds 	struct list_head *p;
8501da177e4SLinus Torvalds 
851f20d09d5SGustavo F. Padovan 	read_lock(&hci_cb_list_lock);
8521da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8531da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8541da177e4SLinus Torvalds 		if (cb->key_change_cfm)
8551da177e4SLinus Torvalds 			cb->key_change_cfm(conn, status);
8561da177e4SLinus Torvalds 	}
857f20d09d5SGustavo F. Padovan 	read_unlock(&hci_cb_list_lock);
8581da177e4SLinus Torvalds }
8591da177e4SLinus Torvalds 
8605a9d0a3fSWaldemar Rymarkiewicz static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
8615a9d0a3fSWaldemar Rymarkiewicz 								__u8 role)
8621da177e4SLinus Torvalds {
8631da177e4SLinus Torvalds 	struct list_head *p;
8641da177e4SLinus Torvalds 
865f20d09d5SGustavo F. Padovan 	read_lock(&hci_cb_list_lock);
8661da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8671da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8681da177e4SLinus Torvalds 		if (cb->role_switch_cfm)
8691da177e4SLinus Torvalds 			cb->role_switch_cfm(conn, status, role);
8701da177e4SLinus Torvalds 	}
871f20d09d5SGustavo F. Padovan 	read_unlock(&hci_cb_list_lock);
8721da177e4SLinus Torvalds }
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *hcb);
8751da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *hcb);
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb);
8781da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb);
8791da177e4SLinus Torvalds 
880a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
88173d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
8820d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
8831da177e4SLinus Torvalds 
884a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
8871da177e4SLinus Torvalds 
8881da177e4SLinus Torvalds /* ----- HCI Sockets ----- */
889eec8d2bcSJohan Hedberg void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
890eec8d2bcSJohan Hedberg 							struct sock *skip_sk);
8911da177e4SLinus Torvalds 
8920381101fSJohan Hedberg /* Management interface */
8930381101fSJohan Hedberg int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
894744cf19eSJohan Hedberg int mgmt_index_added(struct hci_dev *hdev);
895744cf19eSJohan Hedberg int mgmt_index_removed(struct hci_dev *hdev);
896744cf19eSJohan Hedberg int mgmt_powered(struct hci_dev *hdev, u8 powered);
897744cf19eSJohan Hedberg int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
898744cf19eSJohan Hedberg int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
899744cf19eSJohan Hedberg int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
900744cf19eSJohan Hedberg int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
901744cf19eSJohan Hedberg 								u8 persistent);
90248264f06SJohan Hedberg int mgmt_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
90348264f06SJohan Hedberg 								u8 addr_type);
90448264f06SJohan Hedberg int mgmt_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
90548264f06SJohan Hedberg 								u8 addr_type);
90637d9ef76SJohan Hedberg int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
90748264f06SJohan Hedberg int mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
90848264f06SJohan Hedberg 						u8 addr_type, u8 status);
909744cf19eSJohan Hedberg int mgmt_pin_code_request(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 secure);
910744cf19eSJohan Hedberg int mgmt_pin_code_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
911c35938b2SSzymon Janc 								u8 status);
912744cf19eSJohan Hedberg int mgmt_pin_code_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
913744cf19eSJohan Hedberg 								u8 status);
914744cf19eSJohan Hedberg int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr,
915744cf19eSJohan Hedberg 						__le32 value, u8 confirm_hint);
916744cf19eSJohan Hedberg int mgmt_user_confirm_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
917744cf19eSJohan Hedberg 								u8 status);
918744cf19eSJohan Hedberg int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev,
919744cf19eSJohan Hedberg 						bdaddr_t *bdaddr, u8 status);
920604086b7SBrian Gix int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr);
921604086b7SBrian Gix int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr,
922604086b7SBrian Gix 								u8 status);
923604086b7SBrian Gix int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev,
924604086b7SBrian Gix 						bdaddr_t *bdaddr, u8 status);
925744cf19eSJohan Hedberg int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 status);
926744cf19eSJohan Hedberg int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status);
927744cf19eSJohan Hedberg int mgmt_read_local_oob_data_reply_complete(struct hci_dev *hdev, u8 *hash,
928744cf19eSJohan Hedberg 						u8 *randomizer, u8 status);
92948264f06SJohan Hedberg int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
930561aafbcSJohan Hedberg 					u8 addr_type, u8 *dev_class, s8 rssi,
931561aafbcSJohan Hedberg 					u8 cfm_name, u8 *eir);
932744cf19eSJohan Hedberg int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *name);
9337a135109SAndre Guedes int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status);
934e6d465cbSAndre Guedes int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status);
935744cf19eSJohan Hedberg int mgmt_discovering(struct hci_dev *hdev, u8 discovering);
936744cf19eSJohan Hedberg int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr);
937744cf19eSJohan Hedberg int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr);
9380381101fSJohan Hedberg 
9391da177e4SLinus Torvalds /* HCI info for socket */
9401da177e4SLinus Torvalds #define hci_pi(sk) ((struct hci_pinfo *) sk)
9411da177e4SLinus Torvalds 
94214c0b608SJohan Hedberg /* HCI socket flags */
94314c0b608SJohan Hedberg #define HCI_PI_MGMT_INIT	0
94414c0b608SJohan Hedberg 
9451da177e4SLinus Torvalds struct hci_pinfo {
9461da177e4SLinus Torvalds 	struct bt_sock    bt;
9471da177e4SLinus Torvalds 	struct hci_dev    *hdev;
9481da177e4SLinus Torvalds 	struct hci_filter filter;
9491da177e4SLinus Torvalds 	__u32             cmsg_mask;
950c02178d2SJohan Hedberg 	unsigned short   channel;
95114c0b608SJohan Hedberg 	unsigned long     flags;
9521da177e4SLinus Torvalds };
9531da177e4SLinus Torvalds 
9541da177e4SLinus Torvalds /* HCI security filter */
9551da177e4SLinus Torvalds #define HCI_SFLT_MAX_OGF  5
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds struct hci_sec_filter {
9581da177e4SLinus Torvalds 	__u32 type_mask;
9591da177e4SLinus Torvalds 	__u32 event_mask[2];
9601da177e4SLinus Torvalds 	__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
9611da177e4SLinus Torvalds };
9621da177e4SLinus Torvalds 
9631da177e4SLinus Torvalds /* ----- HCI requests ----- */
9641da177e4SLinus Torvalds #define HCI_REQ_DONE	  0
9651da177e4SLinus Torvalds #define HCI_REQ_PEND	  1
9661da177e4SLinus Torvalds #define HCI_REQ_CANCELED  2
9671da177e4SLinus Torvalds 
968a6a67efdSThomas Gleixner #define hci_req_lock(d)		mutex_lock(&d->req_lock)
969a6a67efdSThomas Gleixner #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
9701da177e4SLinus Torvalds 
97123bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
9721da177e4SLinus Torvalds 
9732ce603ebSClaudio Takahasi void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
9742ce603ebSClaudio Takahasi 					u16 latency, u16 to_multiplier);
975a7a595f6SVinicius Costa Gomes void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
976a7a595f6SVinicius Costa Gomes 							__u8 ltk[16]);
977a7a595f6SVinicius Costa Gomes void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
978a7a595f6SVinicius Costa Gomes void hci_le_ltk_neg_reply(struct hci_conn *conn);
979a7a595f6SVinicius Costa Gomes 
9802519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length);
981023d5049SAndre Guedes int hci_cancel_inquiry(struct hci_dev *hdev);
9822519a1fcSAndre Guedes 
9831da177e4SLinus Torvalds #endif /* __HCI_CORE_H */
984