xref: /openbmc/linux/include/net/bluetooth/hci_core.h (revision 2519a1fc)
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 
311da177e4SLinus Torvalds /* HCI upper protocols */
321da177e4SLinus Torvalds #define HCI_PROTO_L2CAP	0
331da177e4SLinus Torvalds #define HCI_PROTO_SCO	1
341da177e4SLinus Torvalds 
355e59b791SLuiz Augusto von Dentz /* HCI priority */
365e59b791SLuiz Augusto von Dentz #define HCI_PRIO_MAX	7
375e59b791SLuiz Augusto von Dentz 
381da177e4SLinus Torvalds /* HCI Core structures */
391da177e4SLinus Torvalds struct inquiry_data {
401da177e4SLinus Torvalds 	bdaddr_t	bdaddr;
411da177e4SLinus Torvalds 	__u8		pscan_rep_mode;
421da177e4SLinus Torvalds 	__u8		pscan_period_mode;
431da177e4SLinus Torvalds 	__u8		pscan_mode;
441da177e4SLinus Torvalds 	__u8		dev_class[3];
451ebb9252SMarcel Holtmann 	__le16		clock_offset;
461da177e4SLinus Torvalds 	__s8		rssi;
4741a96212SMarcel Holtmann 	__u8		ssp_mode;
481da177e4SLinus Torvalds };
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds struct inquiry_entry {
511da177e4SLinus Torvalds 	struct inquiry_entry	*next;
521da177e4SLinus Torvalds 	__u32			timestamp;
531da177e4SLinus Torvalds 	struct inquiry_data	data;
541da177e4SLinus Torvalds };
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds struct inquiry_cache {
571da177e4SLinus Torvalds 	spinlock_t		lock;
581da177e4SLinus Torvalds 	__u32			timestamp;
591da177e4SLinus Torvalds 	struct inquiry_entry	*list;
601da177e4SLinus Torvalds };
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds struct hci_conn_hash {
631da177e4SLinus Torvalds 	struct list_head list;
641da177e4SLinus Torvalds 	spinlock_t       lock;
651da177e4SLinus Torvalds 	unsigned int     acl_num;
661da177e4SLinus Torvalds 	unsigned int     sco_num;
67fcd89c09SVille Tervo 	unsigned int     le_num;
681da177e4SLinus Torvalds };
691da177e4SLinus Torvalds 
7073d80debSLuiz Augusto von Dentz struct hci_chan_hash {
7173d80debSLuiz Augusto von Dentz 	struct list_head list;
7273d80debSLuiz Augusto von Dentz 	spinlock_t       lock;
7373d80debSLuiz Augusto von Dentz 	unsigned int     num;
7473d80debSLuiz Augusto von Dentz };
7573d80debSLuiz Augusto von Dentz 
76f0358568SJohan Hedberg struct bdaddr_list {
77f0358568SJohan Hedberg 	struct list_head list;
78f0358568SJohan Hedberg 	bdaddr_t bdaddr;
79f0358568SJohan Hedberg };
802aeb9a1aSJohan Hedberg 
812aeb9a1aSJohan Hedberg struct bt_uuid {
822aeb9a1aSJohan Hedberg 	struct list_head list;
832aeb9a1aSJohan Hedberg 	u8 uuid[16];
841aff6f09SJohan Hedberg 	u8 svc_hint;
852aeb9a1aSJohan Hedberg };
862aeb9a1aSJohan Hedberg 
8734918cd7SVinicius Costa Gomes struct key_master_id {
8834918cd7SVinicius Costa Gomes 	__le16 ediv;
8934918cd7SVinicius Costa Gomes 	u8 rand[8];
9034918cd7SVinicius Costa Gomes } __packed;
9134918cd7SVinicius Costa Gomes 
9234918cd7SVinicius Costa Gomes struct link_key_data {
9334918cd7SVinicius Costa Gomes 	bdaddr_t bdaddr;
9434918cd7SVinicius Costa Gomes 	u8 type;
9534918cd7SVinicius Costa Gomes 	u8 val[16];
9634918cd7SVinicius Costa Gomes 	u8 pin_len;
9734918cd7SVinicius Costa Gomes 	u8 dlen;
9834918cd7SVinicius Costa Gomes 	u8 data[0];
9934918cd7SVinicius Costa Gomes } __packed;
10034918cd7SVinicius Costa Gomes 
10155ed8ca1SJohan Hedberg struct link_key {
10255ed8ca1SJohan Hedberg 	struct list_head list;
10355ed8ca1SJohan Hedberg 	bdaddr_t bdaddr;
10455ed8ca1SJohan Hedberg 	u8 type;
10555ed8ca1SJohan Hedberg 	u8 val[16];
10655ed8ca1SJohan Hedberg 	u8 pin_len;
10734918cd7SVinicius Costa Gomes 	u8 dlen;
10834918cd7SVinicius Costa Gomes 	u8 data[0];
10955ed8ca1SJohan Hedberg };
11055ed8ca1SJohan Hedberg 
1112763eda6SSzymon Janc struct oob_data {
1122763eda6SSzymon Janc 	struct list_head list;
1132763eda6SSzymon Janc 	bdaddr_t bdaddr;
1142763eda6SSzymon Janc 	u8 hash[16];
1152763eda6SSzymon Janc 	u8 randomizer[16];
1162763eda6SSzymon Janc };
1172763eda6SSzymon Janc 
11876c8686fSAndre Guedes struct adv_entry {
11976c8686fSAndre Guedes 	struct list_head list;
12076c8686fSAndre Guedes 	bdaddr_t bdaddr;
12176c8686fSAndre Guedes 	u8 bdaddr_type;
12276c8686fSAndre Guedes };
12376c8686fSAndre Guedes 
124cd4c5391SSuraj Sumangala #define NUM_REASSEMBLY 4
1251da177e4SLinus Torvalds struct hci_dev {
1261da177e4SLinus Torvalds 	struct list_head list;
1271da177e4SLinus Torvalds 	spinlock_t	lock;
1281da177e4SLinus Torvalds 	atomic_t	refcnt;
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds 	char		name[8];
1311da177e4SLinus Torvalds 	unsigned long	flags;
1321da177e4SLinus Torvalds 	__u16		id;
133c13854ceSMarcel Holtmann 	__u8		bus;
134943da25dSMarcel Holtmann 	__u8		dev_type;
1351da177e4SLinus Torvalds 	bdaddr_t	bdaddr;
1361f6c6378SJohan Hedberg 	__u8		dev_name[HCI_MAX_NAME_LENGTH];
13780a1e1dbSJohan Hedberg 	__u8		eir[HCI_MAX_EIR_LENGTH];
138a9de9248SMarcel Holtmann 	__u8		dev_class[3];
1391aff6f09SJohan Hedberg 	__u8		major_class;
1401aff6f09SJohan Hedberg 	__u8		minor_class;
1411da177e4SLinus Torvalds 	__u8		features[8];
142971e3a4bSAndre Guedes 	__u8		extfeatures[8];
143a9de9248SMarcel Holtmann 	__u8		commands[64];
144333140b5SMarcel Holtmann 	__u8		ssp_mode;
1451143e5a6SMarcel Holtmann 	__u8		hci_ver;
1461143e5a6SMarcel Holtmann 	__u16		hci_rev;
147d5859e22SJohan Hedberg 	__u8		lmp_ver;
1481143e5a6SMarcel Holtmann 	__u16		manufacturer;
149d5859e22SJohan Hedberg 	__le16		lmp_subver;
1501da177e4SLinus Torvalds 	__u16		voice_setting;
15117fa4b9dSJohan Hedberg 	__u8		io_capability;
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds 	__u16		pkt_type;
1545b7f9909SMarcel Holtmann 	__u16		esco_type;
1551da177e4SLinus Torvalds 	__u16		link_policy;
1561da177e4SLinus Torvalds 	__u16		link_mode;
1571da177e4SLinus Torvalds 
15804837f64SMarcel Holtmann 	__u32		idle_timeout;
15904837f64SMarcel Holtmann 	__u16		sniff_min_interval;
16004837f64SMarcel Holtmann 	__u16		sniff_max_interval;
16104837f64SMarcel Holtmann 
162928abaa7SAndrei Emeltchenko 	__u8		amp_status;
163928abaa7SAndrei Emeltchenko 	__u32		amp_total_bw;
164928abaa7SAndrei Emeltchenko 	__u32		amp_max_bw;
165928abaa7SAndrei Emeltchenko 	__u32		amp_min_latency;
166928abaa7SAndrei Emeltchenko 	__u32		amp_max_pdu;
167928abaa7SAndrei Emeltchenko 	__u8		amp_type;
168928abaa7SAndrei Emeltchenko 	__u16		amp_pal_cap;
169928abaa7SAndrei Emeltchenko 	__u16		amp_assoc_size;
170928abaa7SAndrei Emeltchenko 	__u32		amp_max_flush_to;
171928abaa7SAndrei Emeltchenko 	__u32		amp_be_flush_to;
172928abaa7SAndrei Emeltchenko 
1739f61656aSJohan Hedberg 	unsigned int	auto_accept_delay;
1749f61656aSJohan Hedberg 
1751da177e4SLinus Torvalds 	unsigned long	quirks;
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds 	atomic_t	cmd_cnt;
1781da177e4SLinus Torvalds 	unsigned int	acl_cnt;
1791da177e4SLinus Torvalds 	unsigned int	sco_cnt;
1806ed58ec5SVille Tervo 	unsigned int	le_cnt;
1811da177e4SLinus Torvalds 
1821da177e4SLinus Torvalds 	unsigned int	acl_mtu;
1831da177e4SLinus Torvalds 	unsigned int	sco_mtu;
1846ed58ec5SVille Tervo 	unsigned int	le_mtu;
1851da177e4SLinus Torvalds 	unsigned int	acl_pkts;
1861da177e4SLinus Torvalds 	unsigned int	sco_pkts;
1876ed58ec5SVille Tervo 	unsigned int	le_pkts;
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds 	unsigned long	acl_last_tx;
1901da177e4SLinus Torvalds 	unsigned long	sco_last_tx;
1916ed58ec5SVille Tervo 	unsigned long	le_last_tx;
1921da177e4SLinus Torvalds 
193f48fd9c8SMarcel Holtmann 	struct workqueue_struct	*workqueue;
194f48fd9c8SMarcel Holtmann 
195ab81cbf9SJohan Hedberg 	struct work_struct	power_on;
196ab81cbf9SJohan Hedberg 	struct work_struct	power_off;
197ab81cbf9SJohan Hedberg 	struct timer_list	off_timer;
198ab81cbf9SJohan Hedberg 
1996bd32326SVille Tervo 	struct timer_list	cmd_timer;
2001da177e4SLinus Torvalds 	struct tasklet_struct	cmd_task;
2011da177e4SLinus Torvalds 	struct tasklet_struct	rx_task;
2021da177e4SLinus Torvalds 	struct tasklet_struct	tx_task;
2031da177e4SLinus Torvalds 
2041da177e4SLinus Torvalds 	struct sk_buff_head	rx_q;
2051da177e4SLinus Torvalds 	struct sk_buff_head	raw_q;
2061da177e4SLinus Torvalds 	struct sk_buff_head	cmd_q;
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 	struct sk_buff		*sent_cmd;
209cd4c5391SSuraj Sumangala 	struct sk_buff		*reassembly[NUM_REASSEMBLY];
2101da177e4SLinus Torvalds 
211a6a67efdSThomas Gleixner 	struct mutex		req_lock;
2121da177e4SLinus Torvalds 	wait_queue_head_t	req_wait_q;
2131da177e4SLinus Torvalds 	__u32			req_status;
2141da177e4SLinus Torvalds 	__u32			req_result;
215a5040efaSJohan Hedberg 
216a5040efaSJohan Hedberg 	__u16			init_last_cmd;
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds 	struct inquiry_cache	inq_cache;
2191da177e4SLinus Torvalds 	struct hci_conn_hash	conn_hash;
220ea4bd8baSDavid Miller 	struct list_head	blacklist;
2211da177e4SLinus Torvalds 
2222aeb9a1aSJohan Hedberg 	struct list_head	uuids;
2232aeb9a1aSJohan Hedberg 
22455ed8ca1SJohan Hedberg 	struct list_head	link_keys;
22555ed8ca1SJohan Hedberg 
2262763eda6SSzymon Janc 	struct list_head	remote_oob_data;
2272763eda6SSzymon Janc 
22876c8686fSAndre Guedes 	struct list_head	adv_entries;
22935815085SAndre Guedes 	struct timer_list	adv_timer;
23076c8686fSAndre Guedes 
2311da177e4SLinus Torvalds 	struct hci_dev_stats	stat;
2321da177e4SLinus Torvalds 
2331da177e4SLinus Torvalds 	struct sk_buff_head	driver_init;
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds 	void			*driver_data;
2361da177e4SLinus Torvalds 	void			*core_data;
2371da177e4SLinus Torvalds 
2381da177e4SLinus Torvalds 	atomic_t		promisc;
2391da177e4SLinus Torvalds 
240ca325f69SMarcel Holtmann 	struct dentry		*debugfs;
241ca325f69SMarcel Holtmann 
242a91f2e39SMarcel Holtmann 	struct device		*parent;
243a91f2e39SMarcel Holtmann 	struct device		dev;
2441da177e4SLinus Torvalds 
245611b30f7SMarcel Holtmann 	struct rfkill		*rfkill;
246611b30f7SMarcel Holtmann 
2471da177e4SLinus Torvalds 	struct module		*owner;
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds 	int (*open)(struct hci_dev *hdev);
2501da177e4SLinus Torvalds 	int (*close)(struct hci_dev *hdev);
2511da177e4SLinus Torvalds 	int (*flush)(struct hci_dev *hdev);
2521da177e4SLinus Torvalds 	int (*send)(struct sk_buff *skb);
2531da177e4SLinus Torvalds 	void (*destruct)(struct hci_dev *hdev);
2541da177e4SLinus Torvalds 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
2551da177e4SLinus Torvalds 	int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
2561da177e4SLinus Torvalds };
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds struct hci_conn {
2591da177e4SLinus Torvalds 	struct list_head list;
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds 	atomic_t	refcnt;
2621da177e4SLinus Torvalds 
2631da177e4SLinus Torvalds 	bdaddr_t	dst;
26429b7988aSAndre Guedes 	__u8		dst_type;
2651da177e4SLinus Torvalds 	__u16		handle;
2661da177e4SLinus Torvalds 	__u16		state;
26704837f64SMarcel Holtmann 	__u8		mode;
2681da177e4SLinus Torvalds 	__u8		type;
2691da177e4SLinus Torvalds 	__u8		out;
2704c67bc74SMarcel Holtmann 	__u8		attempt;
2711da177e4SLinus Torvalds 	__u8		dev_class[3];
27204837f64SMarcel Holtmann 	__u8		features[8];
27341a96212SMarcel Holtmann 	__u8		ssp_mode;
27404837f64SMarcel Holtmann 	__u16		interval;
275a8746417SMarcel Holtmann 	__u16		pkt_type;
27604837f64SMarcel Holtmann 	__u16		link_policy;
2771da177e4SLinus Torvalds 	__u32		link_mode;
27813d39315SWaldemar Rymarkiewicz 	__u8		key_type;
27940be492fSMarcel Holtmann 	__u8		auth_type;
2808c1b2355SMarcel Holtmann 	__u8		sec_level;
281765c2a96SJohan Hedberg 	__u8		pending_sec_level;
282980e1a53SJohan Hedberg 	__u8		pin_length;
283726b4ffcSVinicius Costa Gomes 	__u8		enc_key_size;
28417fa4b9dSJohan Hedberg 	__u8		io_capability;
28504837f64SMarcel Holtmann 	__u8		power_save;
286052b30b0SMarcel Holtmann 	__u16		disc_timeout;
2871da177e4SLinus Torvalds 	unsigned long	pend;
2881da177e4SLinus Torvalds 
28903b555e1SJohan Hedberg 	__u8		remote_cap;
29003b555e1SJohan Hedberg 	__u8		remote_oob;
29103b555e1SJohan Hedberg 	__u8		remote_auth;
29203b555e1SJohan Hedberg 
2931da177e4SLinus Torvalds 	unsigned int	sent;
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds 	struct sk_buff_head data_q;
29673d80debSLuiz Augusto von Dentz 	struct hci_chan_hash chan_hash;
2971da177e4SLinus Torvalds 
29804837f64SMarcel Holtmann 	struct timer_list disc_timer;
29904837f64SMarcel Holtmann 	struct timer_list idle_timer;
3009f61656aSJohan Hedberg 	struct timer_list auto_accept_timer;
3011da177e4SLinus Torvalds 
302f3784d83SRoger Quadros 	struct work_struct work_add;
303f3784d83SRoger Quadros 	struct work_struct work_del;
304b219e3acSMarcel Holtmann 
305b219e3acSMarcel Holtmann 	struct device	dev;
3069eba32b8SMarcel Holtmann 	atomic_t	devref;
307b219e3acSMarcel Holtmann 
3081da177e4SLinus Torvalds 	struct hci_dev	*hdev;
3091da177e4SLinus Torvalds 	void		*l2cap_data;
3101da177e4SLinus Torvalds 	void		*sco_data;
3111da177e4SLinus Torvalds 
3121da177e4SLinus Torvalds 	struct hci_conn	*link;
313e9a416b5SJohan Hedberg 
314e9a416b5SJohan Hedberg 	void (*connect_cfm_cb)	(struct hci_conn *conn, u8 status);
315e9a416b5SJohan Hedberg 	void (*security_cfm_cb)	(struct hci_conn *conn, u8 status);
316e9a416b5SJohan Hedberg 	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
3171da177e4SLinus Torvalds };
3181da177e4SLinus Torvalds 
31973d80debSLuiz Augusto von Dentz struct hci_chan {
32073d80debSLuiz Augusto von Dentz 	struct list_head list;
32173d80debSLuiz Augusto von Dentz 
32273d80debSLuiz Augusto von Dentz 	struct hci_conn *conn;
32373d80debSLuiz Augusto von Dentz 	struct sk_buff_head data_q;
32473d80debSLuiz Augusto von Dentz 	unsigned int	sent;
32573d80debSLuiz Augusto von Dentz };
32673d80debSLuiz Augusto von Dentz 
3271da177e4SLinus Torvalds extern struct hci_proto *hci_proto[];
3281da177e4SLinus Torvalds extern struct list_head hci_dev_list;
3291da177e4SLinus Torvalds extern struct list_head hci_cb_list;
3301da177e4SLinus Torvalds extern rwlock_t hci_dev_list_lock;
3311da177e4SLinus Torvalds extern rwlock_t hci_cb_list_lock;
3321da177e4SLinus Torvalds 
3331da177e4SLinus Torvalds /* ----- Inquiry cache ----- */
33470f23020SAndrei Emeltchenko #define INQUIRY_CACHE_AGE_MAX   (HZ*30)   /* 30 seconds */
33570f23020SAndrei Emeltchenko #define INQUIRY_ENTRY_AGE_MAX   (HZ*60)   /* 60 seconds */
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds #define inquiry_cache_lock(c)		spin_lock(&c->lock)
3381da177e4SLinus Torvalds #define inquiry_cache_unlock(c)		spin_unlock(&c->lock)
3391da177e4SLinus Torvalds #define inquiry_cache_lock_bh(c)	spin_lock_bh(&c->lock)
3401da177e4SLinus Torvalds #define inquiry_cache_unlock_bh(c)	spin_unlock_bh(&c->lock)
3411da177e4SLinus Torvalds 
3421da177e4SLinus Torvalds static inline void inquiry_cache_init(struct hci_dev *hdev)
3431da177e4SLinus Torvalds {
3441da177e4SLinus Torvalds 	struct inquiry_cache *c = &hdev->inq_cache;
3451da177e4SLinus Torvalds 	spin_lock_init(&c->lock);
3461da177e4SLinus Torvalds 	c->list = NULL;
3471da177e4SLinus Torvalds }
3481da177e4SLinus Torvalds 
3491da177e4SLinus Torvalds static inline int inquiry_cache_empty(struct hci_dev *hdev)
3501da177e4SLinus Torvalds {
3511da177e4SLinus Torvalds 	struct inquiry_cache *c = &hdev->inq_cache;
352a02cec21SEric Dumazet 	return c->list == NULL;
3531da177e4SLinus Torvalds }
3541da177e4SLinus Torvalds 
3551da177e4SLinus Torvalds static inline long inquiry_cache_age(struct hci_dev *hdev)
3561da177e4SLinus Torvalds {
3571da177e4SLinus Torvalds 	struct inquiry_cache *c = &hdev->inq_cache;
3581da177e4SLinus Torvalds 	return jiffies - c->timestamp;
3591da177e4SLinus Torvalds }
3601da177e4SLinus Torvalds 
3611da177e4SLinus Torvalds static inline long inquiry_entry_age(struct inquiry_entry *e)
3621da177e4SLinus Torvalds {
3631da177e4SLinus Torvalds 	return jiffies - e->timestamp;
3641da177e4SLinus Torvalds }
3651da177e4SLinus Torvalds 
3665a9d0a3fSWaldemar Rymarkiewicz struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
3675a9d0a3fSWaldemar Rymarkiewicz 							bdaddr_t *bdaddr);
3681da177e4SLinus Torvalds void hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data);
3691da177e4SLinus Torvalds 
3701da177e4SLinus Torvalds /* ----- HCI Connections ----- */
3711da177e4SLinus Torvalds enum {
3721da177e4SLinus Torvalds 	HCI_CONN_AUTH_PEND,
37319f8def0SWaldemar Rymarkiewicz 	HCI_CONN_REAUTH_PEND,
3741da177e4SLinus Torvalds 	HCI_CONN_ENCRYPT_PEND,
37504837f64SMarcel Holtmann 	HCI_CONN_RSWITCH_PEND,
37604837f64SMarcel Holtmann 	HCI_CONN_MODE_CHANGE_PEND,
377e73439d8SMarcel Holtmann 	HCI_CONN_SCO_SETUP_PEND,
378d26a2345SVinicius Costa Gomes 	HCI_CONN_LE_SMP_PEND,
3791da177e4SLinus Torvalds };
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds static inline void hci_conn_hash_init(struct hci_dev *hdev)
3821da177e4SLinus Torvalds {
3831da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
3841da177e4SLinus Torvalds 	INIT_LIST_HEAD(&h->list);
3851da177e4SLinus Torvalds 	spin_lock_init(&h->lock);
3861da177e4SLinus Torvalds 	h->acl_num = 0;
3871da177e4SLinus Torvalds 	h->sco_num = 0;
3881da177e4SLinus Torvalds }
3891da177e4SLinus Torvalds 
3901da177e4SLinus Torvalds static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
3911da177e4SLinus Torvalds {
3921da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
3931da177e4SLinus Torvalds 	list_add(&c->list, &h->list);
394fcd89c09SVille Tervo 	switch (c->type) {
395fcd89c09SVille Tervo 	case ACL_LINK:
3961da177e4SLinus Torvalds 		h->acl_num++;
397fcd89c09SVille Tervo 		break;
398fcd89c09SVille Tervo 	case LE_LINK:
399fcd89c09SVille Tervo 		h->le_num++;
400fcd89c09SVille Tervo 		break;
401fcd89c09SVille Tervo 	case SCO_LINK:
402fcd89c09SVille Tervo 	case ESCO_LINK:
4031da177e4SLinus Torvalds 		h->sco_num++;
404fcd89c09SVille Tervo 		break;
405fcd89c09SVille Tervo 	}
4061da177e4SLinus Torvalds }
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
4091da177e4SLinus Torvalds {
4101da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
4111da177e4SLinus Torvalds 	list_del(&c->list);
412fcd89c09SVille Tervo 	switch (c->type) {
413fcd89c09SVille Tervo 	case ACL_LINK:
4141da177e4SLinus Torvalds 		h->acl_num--;
415fcd89c09SVille Tervo 		break;
416fcd89c09SVille Tervo 	case LE_LINK:
417fcd89c09SVille Tervo 		h->le_num--;
418fcd89c09SVille Tervo 		break;
419fcd89c09SVille Tervo 	case SCO_LINK:
420fcd89c09SVille Tervo 	case ESCO_LINK:
4211da177e4SLinus Torvalds 		h->sco_num--;
422fcd89c09SVille Tervo 		break;
423fcd89c09SVille Tervo 	}
4241da177e4SLinus Torvalds }
4251da177e4SLinus Torvalds 
42652087a79SLuiz Augusto von Dentz static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
42752087a79SLuiz Augusto von Dentz {
42852087a79SLuiz Augusto von Dentz 	struct hci_conn_hash *h = &hdev->conn_hash;
42952087a79SLuiz Augusto von Dentz 	switch (type) {
43052087a79SLuiz Augusto von Dentz 	case ACL_LINK:
43152087a79SLuiz Augusto von Dentz 		return h->acl_num;
43252087a79SLuiz Augusto von Dentz 	case LE_LINK:
43352087a79SLuiz Augusto von Dentz 		return h->le_num;
43452087a79SLuiz Augusto von Dentz 	case SCO_LINK:
43552087a79SLuiz Augusto von Dentz 	case ESCO_LINK:
43652087a79SLuiz Augusto von Dentz 		return h->sco_num;
43752087a79SLuiz Augusto von Dentz 	default:
43852087a79SLuiz Augusto von Dentz 		return 0;
43952087a79SLuiz Augusto von Dentz 	}
44052087a79SLuiz Augusto von Dentz }
44152087a79SLuiz Augusto von Dentz 
4421da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
4431da177e4SLinus Torvalds 								__u16 handle)
4441da177e4SLinus Torvalds {
4451da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
4461da177e4SLinus Torvalds 	struct list_head *p;
4471da177e4SLinus Torvalds 	struct hci_conn  *c;
4481da177e4SLinus Torvalds 
4491da177e4SLinus Torvalds 	list_for_each(p, &h->list) {
4501da177e4SLinus Torvalds 		c = list_entry(p, struct hci_conn, list);
4511da177e4SLinus Torvalds 		if (c->handle == handle)
4521da177e4SLinus Torvalds 			return c;
4531da177e4SLinus Torvalds 	}
4541da177e4SLinus Torvalds 	return NULL;
4551da177e4SLinus Torvalds }
4561da177e4SLinus Torvalds 
4571da177e4SLinus Torvalds static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
4581da177e4SLinus Torvalds 							__u8 type, bdaddr_t *ba)
4591da177e4SLinus Torvalds {
4601da177e4SLinus Torvalds 	struct hci_conn_hash *h = &hdev->conn_hash;
4611da177e4SLinus Torvalds 	struct list_head *p;
4621da177e4SLinus Torvalds 	struct hci_conn  *c;
4631da177e4SLinus Torvalds 
4641da177e4SLinus Torvalds 	list_for_each(p, &h->list) {
4651da177e4SLinus Torvalds 		c = list_entry(p, struct hci_conn, list);
4661da177e4SLinus Torvalds 		if (c->type == type && !bacmp(&c->dst, ba))
4671da177e4SLinus Torvalds 			return c;
4681da177e4SLinus Torvalds 	}
4691da177e4SLinus Torvalds 	return NULL;
4701da177e4SLinus Torvalds }
4711da177e4SLinus Torvalds 
4724c67bc74SMarcel Holtmann static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
4734c67bc74SMarcel Holtmann 							__u8 type, __u16 state)
4744c67bc74SMarcel Holtmann {
4754c67bc74SMarcel Holtmann 	struct hci_conn_hash *h = &hdev->conn_hash;
4764c67bc74SMarcel Holtmann 	struct list_head *p;
4774c67bc74SMarcel Holtmann 	struct hci_conn  *c;
4784c67bc74SMarcel Holtmann 
4794c67bc74SMarcel Holtmann 	list_for_each(p, &h->list) {
4804c67bc74SMarcel Holtmann 		c = list_entry(p, struct hci_conn, list);
4814c67bc74SMarcel Holtmann 		if (c->type == type && c->state == state)
4824c67bc74SMarcel Holtmann 			return c;
4834c67bc74SMarcel Holtmann 	}
4844c67bc74SMarcel Holtmann 	return NULL;
4854c67bc74SMarcel Holtmann }
4864c67bc74SMarcel Holtmann 
48773d80debSLuiz Augusto von Dentz static inline void hci_chan_hash_init(struct hci_conn *c)
48873d80debSLuiz Augusto von Dentz {
48973d80debSLuiz Augusto von Dentz 	struct hci_chan_hash *h = &c->chan_hash;
49073d80debSLuiz Augusto von Dentz 	INIT_LIST_HEAD(&h->list);
49173d80debSLuiz Augusto von Dentz 	spin_lock_init(&h->lock);
49273d80debSLuiz Augusto von Dentz 	h->num = 0;
49373d80debSLuiz Augusto von Dentz }
49473d80debSLuiz Augusto von Dentz 
49573d80debSLuiz Augusto von Dentz static inline void hci_chan_hash_add(struct hci_conn *c, struct hci_chan *chan)
49673d80debSLuiz Augusto von Dentz {
49773d80debSLuiz Augusto von Dentz 	struct hci_chan_hash *h = &c->chan_hash;
49873d80debSLuiz Augusto von Dentz 	list_add(&chan->list, &h->list);
49973d80debSLuiz Augusto von Dentz 	h->num++;
50073d80debSLuiz Augusto von Dentz }
50173d80debSLuiz Augusto von Dentz 
50273d80debSLuiz Augusto von Dentz static inline void hci_chan_hash_del(struct hci_conn *c, struct hci_chan *chan)
50373d80debSLuiz Augusto von Dentz {
50473d80debSLuiz Augusto von Dentz 	struct hci_chan_hash *h = &c->chan_hash;
50573d80debSLuiz Augusto von Dentz 	list_del(&chan->list);
50673d80debSLuiz Augusto von Dentz 	h->num--;
50773d80debSLuiz Augusto von Dentz }
50873d80debSLuiz Augusto von Dentz 
5094c67bc74SMarcel Holtmann void hci_acl_connect(struct hci_conn *conn);
5101da177e4SLinus Torvalds void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
5111da177e4SLinus Torvalds void hci_add_sco(struct hci_conn *conn, __u16 handle);
512b6a0dc82SMarcel Holtmann void hci_setup_sync(struct hci_conn *conn, __u16 handle);
513e73439d8SMarcel Holtmann void hci_sco_setup(struct hci_conn *conn, __u8 status);
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
5161da177e4SLinus Torvalds int hci_conn_del(struct hci_conn *conn);
5171da177e4SLinus Torvalds void hci_conn_hash_flush(struct hci_dev *hdev);
518a9de9248SMarcel Holtmann void hci_conn_check_pending(struct hci_dev *hdev);
5191da177e4SLinus Torvalds 
52073d80debSLuiz Augusto von Dentz struct hci_chan *hci_chan_create(struct hci_conn *conn);
52173d80debSLuiz Augusto von Dentz int hci_chan_del(struct hci_chan *chan);
52273d80debSLuiz Augusto von Dentz void hci_chan_hash_flush(struct hci_conn *conn);
52373d80debSLuiz Augusto von Dentz 
5245a9d0a3fSWaldemar Rymarkiewicz struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
5255a9d0a3fSWaldemar Rymarkiewicz 						__u8 sec_level, __u8 auth_type);
526e7c29cb1SMarcel Holtmann int hci_conn_check_link_mode(struct hci_conn *conn);
527b3b1b061SWaldemar Rymarkiewicz int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
5280684e5f9SMarcel Holtmann int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
5291da177e4SLinus Torvalds int hci_conn_change_link_key(struct hci_conn *conn);
5308c1b2355SMarcel Holtmann int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
5311da177e4SLinus Torvalds 
53214b12d0bSJaikumar Ganesh void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
53304837f64SMarcel Holtmann void hci_conn_enter_sniff_mode(struct hci_conn *conn);
5341da177e4SLinus Torvalds 
5359eba32b8SMarcel Holtmann void hci_conn_hold_device(struct hci_conn *conn);
5369eba32b8SMarcel Holtmann void hci_conn_put_device(struct hci_conn *conn);
5379eba32b8SMarcel Holtmann 
5381da177e4SLinus Torvalds static inline void hci_conn_hold(struct hci_conn *conn)
5391da177e4SLinus Torvalds {
5401da177e4SLinus Torvalds 	atomic_inc(&conn->refcnt);
54104837f64SMarcel Holtmann 	del_timer(&conn->disc_timer);
5421da177e4SLinus Torvalds }
5431da177e4SLinus Torvalds 
5441da177e4SLinus Torvalds static inline void hci_conn_put(struct hci_conn *conn)
5451da177e4SLinus Torvalds {
5461da177e4SLinus Torvalds 	if (atomic_dec_and_test(&conn->refcnt)) {
54704837f64SMarcel Holtmann 		unsigned long timeo;
548454d48ffSVinicius Costa Gomes 		if (conn->type == ACL_LINK || conn->type == LE_LINK) {
5496ac59344SMarcel Holtmann 			del_timer(&conn->idle_timer);
5506ac59344SMarcel Holtmann 			if (conn->state == BT_CONNECTED) {
551052b30b0SMarcel Holtmann 				timeo = msecs_to_jiffies(conn->disc_timeout);
55204837f64SMarcel Holtmann 				if (!conn->out)
553052b30b0SMarcel Holtmann 					timeo *= 2;
5545a9d0a3fSWaldemar Rymarkiewicz 			} else {
5556ac59344SMarcel Holtmann 				timeo = msecs_to_jiffies(10);
5565a9d0a3fSWaldemar Rymarkiewicz 			}
5575a9d0a3fSWaldemar Rymarkiewicz 		} else {
55804837f64SMarcel Holtmann 			timeo = msecs_to_jiffies(10);
5595a9d0a3fSWaldemar Rymarkiewicz 		}
56004837f64SMarcel Holtmann 		mod_timer(&conn->disc_timer, jiffies + timeo);
5611da177e4SLinus Torvalds 	}
5621da177e4SLinus Torvalds }
5631da177e4SLinus Torvalds 
5641da177e4SLinus Torvalds /* ----- HCI Devices ----- */
5651da177e4SLinus Torvalds static inline void __hci_dev_put(struct hci_dev *d)
5661da177e4SLinus Torvalds {
5671da177e4SLinus Torvalds 	if (atomic_dec_and_test(&d->refcnt))
5681da177e4SLinus Torvalds 		d->destruct(d);
5691da177e4SLinus Torvalds }
5701da177e4SLinus Torvalds 
5711da177e4SLinus Torvalds static inline void hci_dev_put(struct hci_dev *d)
5721da177e4SLinus Torvalds {
5731da177e4SLinus Torvalds 	__hci_dev_put(d);
5741da177e4SLinus Torvalds 	module_put(d->owner);
5751da177e4SLinus Torvalds }
5761da177e4SLinus Torvalds 
5771da177e4SLinus Torvalds static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
5781da177e4SLinus Torvalds {
5791da177e4SLinus Torvalds 	atomic_inc(&d->refcnt);
5801da177e4SLinus Torvalds 	return d;
5811da177e4SLinus Torvalds }
5821da177e4SLinus Torvalds 
5831da177e4SLinus Torvalds static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
5841da177e4SLinus Torvalds {
5851da177e4SLinus Torvalds 	if (try_module_get(d->owner))
5861da177e4SLinus Torvalds 		return __hci_dev_hold(d);
5871da177e4SLinus Torvalds 	return NULL;
5881da177e4SLinus Torvalds }
5891da177e4SLinus Torvalds 
5901da177e4SLinus Torvalds #define hci_dev_lock(d)		spin_lock(&d->lock)
5911da177e4SLinus Torvalds #define hci_dev_unlock(d)	spin_unlock(&d->lock)
5921da177e4SLinus Torvalds #define hci_dev_lock_bh(d)	spin_lock_bh(&d->lock)
5931da177e4SLinus Torvalds #define hci_dev_unlock_bh(d)	spin_unlock_bh(&d->lock)
5941da177e4SLinus Torvalds 
5951da177e4SLinus Torvalds struct hci_dev *hci_dev_get(int index);
5961da177e4SLinus Torvalds struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
5971da177e4SLinus Torvalds 
5981da177e4SLinus Torvalds struct hci_dev *hci_alloc_dev(void);
5991da177e4SLinus Torvalds void hci_free_dev(struct hci_dev *hdev);
6001da177e4SLinus Torvalds int hci_register_dev(struct hci_dev *hdev);
60159735631SDavid Herrmann void hci_unregister_dev(struct hci_dev *hdev);
6021da177e4SLinus Torvalds int hci_suspend_dev(struct hci_dev *hdev);
6031da177e4SLinus Torvalds int hci_resume_dev(struct hci_dev *hdev);
6041da177e4SLinus Torvalds int hci_dev_open(__u16 dev);
6051da177e4SLinus Torvalds int hci_dev_close(__u16 dev);
6061da177e4SLinus Torvalds int hci_dev_reset(__u16 dev);
6071da177e4SLinus Torvalds int hci_dev_reset_stat(__u16 dev);
6081da177e4SLinus Torvalds int hci_dev_cmd(unsigned int cmd, void __user *arg);
6091da177e4SLinus Torvalds int hci_get_dev_list(void __user *arg);
6101da177e4SLinus Torvalds int hci_get_dev_info(void __user *arg);
6111da177e4SLinus Torvalds int hci_get_conn_list(void __user *arg);
6121da177e4SLinus Torvalds int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
61340be492fSMarcel Holtmann int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
6141da177e4SLinus Torvalds int hci_inquiry(void __user *arg);
6151da177e4SLinus Torvalds 
616f0358568SJohan Hedberg struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
617f0358568SJohan Hedberg int hci_blacklist_clear(struct hci_dev *hdev);
618b2a66aadSAntti Julku int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr);
619b2a66aadSAntti Julku int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr);
620f0358568SJohan Hedberg 
6212aeb9a1aSJohan Hedberg int hci_uuids_clear(struct hci_dev *hdev);
6222aeb9a1aSJohan Hedberg 
62355ed8ca1SJohan Hedberg int hci_link_keys_clear(struct hci_dev *hdev);
62455ed8ca1SJohan Hedberg struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
625d25e28abSJohan Hedberg int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
626d25e28abSJohan Hedberg 			bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
62775d262c2SVinicius Costa Gomes struct link_key *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]);
62875d262c2SVinicius Costa Gomes struct link_key *hci_find_link_key_type(struct hci_dev *hdev,
62975d262c2SVinicius Costa Gomes 					bdaddr_t *bdaddr, u8 type);
63075d262c2SVinicius Costa Gomes int hci_add_ltk(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
631726b4ffcSVinicius Costa Gomes 			u8 key_size, __le16 ediv, u8 rand[8], u8 ltk[16]);
63255ed8ca1SJohan Hedberg int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
63355ed8ca1SJohan Hedberg 
6342763eda6SSzymon Janc int hci_remote_oob_data_clear(struct hci_dev *hdev);
6352763eda6SSzymon Janc struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
6362763eda6SSzymon Janc 							bdaddr_t *bdaddr);
6372763eda6SSzymon Janc int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
6382763eda6SSzymon Janc 								u8 *randomizer);
6392763eda6SSzymon Janc int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
6402763eda6SSzymon Janc 
64135815085SAndre Guedes #define ADV_CLEAR_TIMEOUT (3*60*HZ) /* Three minutes */
64276c8686fSAndre Guedes int hci_adv_entries_clear(struct hci_dev *hdev);
64376c8686fSAndre Guedes struct adv_entry *hci_find_adv_entry(struct hci_dev *hdev, bdaddr_t *bdaddr);
64476c8686fSAndre Guedes int hci_add_adv_entry(struct hci_dev *hdev,
64576c8686fSAndre Guedes 					struct hci_ev_le_advertising_info *ev);
64676c8686fSAndre Guedes 
647ab81cbf9SJohan Hedberg void hci_del_off_timer(struct hci_dev *hdev);
648ab81cbf9SJohan Hedberg 
6491da177e4SLinus Torvalds void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
6501da177e4SLinus Torvalds 
65176bca880SMarcel Holtmann int hci_recv_frame(struct sk_buff *skb);
652ef222013SMarcel Holtmann int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
65399811510SSuraj Sumangala int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
654ef222013SMarcel Holtmann 
6550ac7e700SDavid Herrmann void hci_init_sysfs(struct hci_dev *hdev);
656ce242970SDavid Herrmann int hci_add_sysfs(struct hci_dev *hdev);
657ce242970SDavid Herrmann void hci_del_sysfs(struct hci_dev *hdev);
658a67e899cSMarcel Holtmann void hci_conn_init_sysfs(struct hci_conn *conn);
659b219e3acSMarcel Holtmann void hci_conn_add_sysfs(struct hci_conn *conn);
660b219e3acSMarcel Holtmann void hci_conn_del_sysfs(struct hci_conn *conn);
6611da177e4SLinus Torvalds 
662a91f2e39SMarcel Holtmann #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
6631da177e4SLinus Torvalds 
6641da177e4SLinus Torvalds /* ----- LMP capabilities ----- */
66504837f64SMarcel Holtmann #define lmp_rswitch_capable(dev)   ((dev)->features[0] & LMP_RSWITCH)
66604837f64SMarcel Holtmann #define lmp_encrypt_capable(dev)   ((dev)->features[0] & LMP_ENCRYPT)
66704837f64SMarcel Holtmann #define lmp_sniff_capable(dev)     ((dev)->features[0] & LMP_SNIFF)
66804837f64SMarcel Holtmann #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
6695b7f9909SMarcel Holtmann #define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
670769be974SMarcel Holtmann #define lmp_ssp_capable(dev)       ((dev)->features[6] & LMP_SIMPLE_PAIR)
671e702112fSAndrei Emeltchenko #define lmp_no_flush_capable(dev)  ((dev)->features[6] & LMP_NO_FLUSH)
6726ed58ec5SVille Tervo #define lmp_le_capable(dev)        ((dev)->features[4] & LMP_LE)
6731da177e4SLinus Torvalds 
674eead27daSAndre Guedes /* ----- Extended LMP capabilities ----- */
675eead27daSAndre Guedes #define lmp_host_le_capable(dev)   ((dev)->extfeatures[0] & LMP_HOST_LE)
676eead27daSAndre Guedes 
6771da177e4SLinus Torvalds /* ----- HCI protocols ----- */
6781da177e4SLinus Torvalds struct hci_proto {
6791da177e4SLinus Torvalds 	char		*name;
6801da177e4SLinus Torvalds 	unsigned int	id;
6811da177e4SLinus Torvalds 	unsigned long	flags;
6821da177e4SLinus Torvalds 
6831da177e4SLinus Torvalds 	void		*priv;
6841da177e4SLinus Torvalds 
6855a9d0a3fSWaldemar Rymarkiewicz 	int (*connect_ind)	(struct hci_dev *hdev, bdaddr_t *bdaddr,
6865a9d0a3fSWaldemar Rymarkiewicz 								__u8 type);
6871da177e4SLinus Torvalds 	int (*connect_cfm)	(struct hci_conn *conn, __u8 status);
6882950f21aSMarcel Holtmann 	int (*disconn_ind)	(struct hci_conn *conn);
6892950f21aSMarcel Holtmann 	int (*disconn_cfm)	(struct hci_conn *conn, __u8 reason);
6905a9d0a3fSWaldemar Rymarkiewicz 	int (*recv_acldata)	(struct hci_conn *conn, struct sk_buff *skb,
6915a9d0a3fSWaldemar Rymarkiewicz 								__u16 flags);
6921da177e4SLinus Torvalds 	int (*recv_scodata)	(struct hci_conn *conn, struct sk_buff *skb);
6935a9d0a3fSWaldemar Rymarkiewicz 	int (*security_cfm)	(struct hci_conn *conn, __u8 status,
6945a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt);
6951da177e4SLinus Torvalds };
6961da177e4SLinus Torvalds 
6975a9d0a3fSWaldemar Rymarkiewicz static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
6985a9d0a3fSWaldemar Rymarkiewicz 								__u8 type)
6991da177e4SLinus Torvalds {
7001da177e4SLinus Torvalds 	register struct hci_proto *hp;
7011da177e4SLinus Torvalds 	int mask = 0;
7021da177e4SLinus Torvalds 
7031da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_L2CAP];
7041da177e4SLinus Torvalds 	if (hp && hp->connect_ind)
7051da177e4SLinus Torvalds 		mask |= hp->connect_ind(hdev, bdaddr, type);
7061da177e4SLinus Torvalds 
7071da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_SCO];
7081da177e4SLinus Torvalds 	if (hp && hp->connect_ind)
7091da177e4SLinus Torvalds 		mask |= hp->connect_ind(hdev, bdaddr, type);
7101da177e4SLinus Torvalds 
7111da177e4SLinus Torvalds 	return mask;
7121da177e4SLinus Torvalds }
7131da177e4SLinus Torvalds 
7141da177e4SLinus Torvalds static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
7151da177e4SLinus Torvalds {
7161da177e4SLinus Torvalds 	register struct hci_proto *hp;
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_L2CAP];
7191da177e4SLinus Torvalds 	if (hp && hp->connect_cfm)
7201da177e4SLinus Torvalds 		hp->connect_cfm(conn, status);
7211da177e4SLinus Torvalds 
7221da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_SCO];
7231da177e4SLinus Torvalds 	if (hp && hp->connect_cfm)
7241da177e4SLinus Torvalds 		hp->connect_cfm(conn, status);
725e9a416b5SJohan Hedberg 
726e9a416b5SJohan Hedberg 	if (conn->connect_cfm_cb)
727e9a416b5SJohan Hedberg 		conn->connect_cfm_cb(conn, status);
7281da177e4SLinus Torvalds }
7291da177e4SLinus Torvalds 
7302950f21aSMarcel Holtmann static inline int hci_proto_disconn_ind(struct hci_conn *conn)
7312950f21aSMarcel Holtmann {
7322950f21aSMarcel Holtmann 	register struct hci_proto *hp;
7339f5a0d7bSAndrei Emeltchenko 	int reason = HCI_ERROR_REMOTE_USER_TERM;
7342950f21aSMarcel Holtmann 
7352950f21aSMarcel Holtmann 	hp = hci_proto[HCI_PROTO_L2CAP];
7362950f21aSMarcel Holtmann 	if (hp && hp->disconn_ind)
7372950f21aSMarcel Holtmann 		reason = hp->disconn_ind(conn);
7382950f21aSMarcel Holtmann 
7392950f21aSMarcel Holtmann 	hp = hci_proto[HCI_PROTO_SCO];
7402950f21aSMarcel Holtmann 	if (hp && hp->disconn_ind)
7412950f21aSMarcel Holtmann 		reason = hp->disconn_ind(conn);
7422950f21aSMarcel Holtmann 
7432950f21aSMarcel Holtmann 	return reason;
7442950f21aSMarcel Holtmann }
7452950f21aSMarcel Holtmann 
7462950f21aSMarcel Holtmann static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
7471da177e4SLinus Torvalds {
7481da177e4SLinus Torvalds 	register struct hci_proto *hp;
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_L2CAP];
7512950f21aSMarcel Holtmann 	if (hp && hp->disconn_cfm)
7522950f21aSMarcel Holtmann 		hp->disconn_cfm(conn, reason);
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_SCO];
7552950f21aSMarcel Holtmann 	if (hp && hp->disconn_cfm)
7562950f21aSMarcel Holtmann 		hp->disconn_cfm(conn, reason);
757e9a416b5SJohan Hedberg 
758e9a416b5SJohan Hedberg 	if (conn->disconn_cfm_cb)
759e9a416b5SJohan Hedberg 		conn->disconn_cfm_cb(conn, reason);
7601da177e4SLinus Torvalds }
7611da177e4SLinus Torvalds 
7621da177e4SLinus Torvalds static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
7631da177e4SLinus Torvalds {
7641da177e4SLinus Torvalds 	register struct hci_proto *hp;
7658c1b2355SMarcel Holtmann 	__u8 encrypt;
7668c1b2355SMarcel Holtmann 
7678c1b2355SMarcel Holtmann 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
7688c1b2355SMarcel Holtmann 		return;
7698c1b2355SMarcel Holtmann 
7708c1b2355SMarcel Holtmann 	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_L2CAP];
7738c1b2355SMarcel Holtmann 	if (hp && hp->security_cfm)
7748c1b2355SMarcel Holtmann 		hp->security_cfm(conn, status, encrypt);
7751da177e4SLinus Torvalds 
7761da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_SCO];
7778c1b2355SMarcel Holtmann 	if (hp && hp->security_cfm)
7788c1b2355SMarcel Holtmann 		hp->security_cfm(conn, status, encrypt);
779e9a416b5SJohan Hedberg 
780e9a416b5SJohan Hedberg 	if (conn->security_cfm_cb)
781e9a416b5SJohan Hedberg 		conn->security_cfm_cb(conn, status);
7821da177e4SLinus Torvalds }
7831da177e4SLinus Torvalds 
7845a9d0a3fSWaldemar Rymarkiewicz static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status,
7855a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt)
7861da177e4SLinus Torvalds {
7871da177e4SLinus Torvalds 	register struct hci_proto *hp;
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_L2CAP];
7908c1b2355SMarcel Holtmann 	if (hp && hp->security_cfm)
7918c1b2355SMarcel Holtmann 		hp->security_cfm(conn, status, encrypt);
7921da177e4SLinus Torvalds 
7931da177e4SLinus Torvalds 	hp = hci_proto[HCI_PROTO_SCO];
7948c1b2355SMarcel Holtmann 	if (hp && hp->security_cfm)
7958c1b2355SMarcel Holtmann 		hp->security_cfm(conn, status, encrypt);
796e9a416b5SJohan Hedberg 
797e9a416b5SJohan Hedberg 	if (conn->security_cfm_cb)
798e9a416b5SJohan Hedberg 		conn->security_cfm_cb(conn, status);
7991da177e4SLinus Torvalds }
8001da177e4SLinus Torvalds 
8011da177e4SLinus Torvalds int hci_register_proto(struct hci_proto *hproto);
8021da177e4SLinus Torvalds int hci_unregister_proto(struct hci_proto *hproto);
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds /* ----- HCI callbacks ----- */
8051da177e4SLinus Torvalds struct hci_cb {
8061da177e4SLinus Torvalds 	struct list_head list;
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds 	char *name;
8091da177e4SLinus Torvalds 
8105a9d0a3fSWaldemar Rymarkiewicz 	void (*security_cfm)	(struct hci_conn *conn, __u8 status,
8115a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt);
8121da177e4SLinus Torvalds 	void (*key_change_cfm)	(struct hci_conn *conn, __u8 status);
8131da177e4SLinus Torvalds 	void (*role_switch_cfm)	(struct hci_conn *conn, __u8 status, __u8 role);
8141da177e4SLinus Torvalds };
8151da177e4SLinus Torvalds 
8161da177e4SLinus Torvalds static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
8171da177e4SLinus Torvalds {
8181da177e4SLinus Torvalds 	struct list_head *p;
8198c1b2355SMarcel Holtmann 	__u8 encrypt;
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	hci_proto_auth_cfm(conn, status);
8221da177e4SLinus Torvalds 
8238c1b2355SMarcel Holtmann 	if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
8248c1b2355SMarcel Holtmann 		return;
8258c1b2355SMarcel Holtmann 
8268c1b2355SMarcel Holtmann 	encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
8278c1b2355SMarcel Holtmann 
8281da177e4SLinus Torvalds 	read_lock_bh(&hci_cb_list_lock);
8291da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8301da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8318c1b2355SMarcel Holtmann 		if (cb->security_cfm)
8328c1b2355SMarcel Holtmann 			cb->security_cfm(conn, status, encrypt);
8331da177e4SLinus Torvalds 	}
8341da177e4SLinus Torvalds 	read_unlock_bh(&hci_cb_list_lock);
8351da177e4SLinus Torvalds }
8361da177e4SLinus Torvalds 
8375a9d0a3fSWaldemar Rymarkiewicz static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
8385a9d0a3fSWaldemar Rymarkiewicz 								__u8 encrypt)
8391da177e4SLinus Torvalds {
8401da177e4SLinus Torvalds 	struct list_head *p;
8411da177e4SLinus Torvalds 
842435fef20SMarcel Holtmann 	if (conn->sec_level == BT_SECURITY_SDP)
843435fef20SMarcel Holtmann 		conn->sec_level = BT_SECURITY_LOW;
844435fef20SMarcel Holtmann 
84588167aedSVinicius Costa Gomes 	if (conn->pending_sec_level > conn->sec_level)
84688167aedSVinicius Costa Gomes 		conn->sec_level = conn->pending_sec_level;
84788167aedSVinicius Costa Gomes 
8489719f8afSMarcel Holtmann 	hci_proto_encrypt_cfm(conn, status, encrypt);
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 	read_lock_bh(&hci_cb_list_lock);
8511da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8521da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8538c1b2355SMarcel Holtmann 		if (cb->security_cfm)
8548c1b2355SMarcel Holtmann 			cb->security_cfm(conn, status, encrypt);
8551da177e4SLinus Torvalds 	}
8561da177e4SLinus Torvalds 	read_unlock_bh(&hci_cb_list_lock);
8571da177e4SLinus Torvalds }
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status)
8601da177e4SLinus Torvalds {
8611da177e4SLinus Torvalds 	struct list_head *p;
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds 	read_lock_bh(&hci_cb_list_lock);
8641da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8651da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8661da177e4SLinus Torvalds 		if (cb->key_change_cfm)
8671da177e4SLinus Torvalds 			cb->key_change_cfm(conn, status);
8681da177e4SLinus Torvalds 	}
8691da177e4SLinus Torvalds 	read_unlock_bh(&hci_cb_list_lock);
8701da177e4SLinus Torvalds }
8711da177e4SLinus Torvalds 
8725a9d0a3fSWaldemar Rymarkiewicz static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
8735a9d0a3fSWaldemar Rymarkiewicz 								__u8 role)
8741da177e4SLinus Torvalds {
8751da177e4SLinus Torvalds 	struct list_head *p;
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds 	read_lock_bh(&hci_cb_list_lock);
8781da177e4SLinus Torvalds 	list_for_each(p, &hci_cb_list) {
8791da177e4SLinus Torvalds 		struct hci_cb *cb = list_entry(p, struct hci_cb, list);
8801da177e4SLinus Torvalds 		if (cb->role_switch_cfm)
8811da177e4SLinus Torvalds 			cb->role_switch_cfm(conn, status, role);
8821da177e4SLinus Torvalds 	}
8831da177e4SLinus Torvalds 	read_unlock_bh(&hci_cb_list_lock);
8841da177e4SLinus Torvalds }
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds int hci_register_cb(struct hci_cb *hcb);
8871da177e4SLinus Torvalds int hci_unregister_cb(struct hci_cb *hcb);
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds int hci_register_notifier(struct notifier_block *nb);
8901da177e4SLinus Torvalds int hci_unregister_notifier(struct notifier_block *nb);
8911da177e4SLinus Torvalds 
892a9de9248SMarcel Holtmann int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
89373d80debSLuiz Augusto von Dentz void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
8940d861d8bSGustavo F. Padovan void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
8951da177e4SLinus Torvalds 
896a9de9248SMarcel Holtmann void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
8971da177e4SLinus Torvalds 
8981da177e4SLinus Torvalds void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
8991da177e4SLinus Torvalds 
9001da177e4SLinus Torvalds /* ----- HCI Sockets ----- */
901eec8d2bcSJohan Hedberg void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
902eec8d2bcSJohan Hedberg 							struct sock *skip_sk);
9031da177e4SLinus Torvalds 
9040381101fSJohan Hedberg /* Management interface */
9050381101fSJohan Hedberg int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
906c71e97bfSJohan Hedberg int mgmt_index_added(u16 index);
907c71e97bfSJohan Hedberg int mgmt_index_removed(u16 index);
9085add6af8SJohan Hedberg int mgmt_powered(u16 index, u8 powered);
90973f22f62SJohan Hedberg int mgmt_discoverable(u16 index, u8 discoverable);
9109fbcbb45SJohan Hedberg int mgmt_connectable(u16 index, u8 connectable);
9114df378a1SJohan Hedberg int mgmt_new_key(u16 index, struct link_key *key, u8 persistent);
912cfafccf7SVinicius Costa Gomes int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 link_type);
913f7520543SJohan Hedberg int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
9148962ee74SJohan Hedberg int mgmt_disconnect_failed(u16 index);
91517d5c04cSJohan Hedberg int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
916a770bb5aSWaldemar Rymarkiewicz int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
917980e1a53SJohan Hedberg int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
918980e1a53SJohan Hedberg int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
91955bc1a37SJohan Hedberg int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
92055bc1a37SJohan Hedberg 							u8 confirm_hint);
921a5c29683SJohan Hedberg int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
922a5c29683SJohan Hedberg int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
923a5c29683SJohan Hedberg 								u8 status);
9242a611692SJohan Hedberg int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
925b312b161SJohan Hedberg int mgmt_set_local_name_complete(u16 index, u8 *name, u8 status);
926c35938b2SSzymon Janc int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
927c35938b2SSzymon Janc 								u8 status);
928e17acd40SJohan Hedberg int mgmt_device_found(u16 index, bdaddr_t *bdaddr, u8 *dev_class, s8 rssi,
929e17acd40SJohan Hedberg 								u8 *eir);
930a88a9652SJohan Hedberg int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 *name);
931164a6e78SJohan Hedberg int mgmt_inquiry_failed(u16 index, u8 status);
932314b2381SJohan Hedberg int mgmt_discovering(u16 index, u8 discovering);
9335e762444SAntti Julku int mgmt_device_blocked(u16 index, bdaddr_t *bdaddr);
9345e762444SAntti Julku int mgmt_device_unblocked(u16 index, bdaddr_t *bdaddr);
9350381101fSJohan Hedberg 
9361da177e4SLinus Torvalds /* HCI info for socket */
9371da177e4SLinus Torvalds #define hci_pi(sk) ((struct hci_pinfo *) sk)
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds struct hci_pinfo {
9401da177e4SLinus Torvalds 	struct bt_sock    bt;
9411da177e4SLinus Torvalds 	struct hci_dev    *hdev;
9421da177e4SLinus Torvalds 	struct hci_filter filter;
9431da177e4SLinus Torvalds 	__u32             cmsg_mask;
944c02178d2SJohan Hedberg 	unsigned short   channel;
9451da177e4SLinus Torvalds };
9461da177e4SLinus Torvalds 
9471da177e4SLinus Torvalds /* HCI security filter */
9481da177e4SLinus Torvalds #define HCI_SFLT_MAX_OGF  5
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds struct hci_sec_filter {
9511da177e4SLinus Torvalds 	__u32 type_mask;
9521da177e4SLinus Torvalds 	__u32 event_mask[2];
9531da177e4SLinus Torvalds 	__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
9541da177e4SLinus Torvalds };
9551da177e4SLinus Torvalds 
9561da177e4SLinus Torvalds /* ----- HCI requests ----- */
9571da177e4SLinus Torvalds #define HCI_REQ_DONE	  0
9581da177e4SLinus Torvalds #define HCI_REQ_PEND	  1
9591da177e4SLinus Torvalds #define HCI_REQ_CANCELED  2
9601da177e4SLinus Torvalds 
961a6a67efdSThomas Gleixner #define hci_req_lock(d)		mutex_lock(&d->req_lock)
962a6a67efdSThomas Gleixner #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
9631da177e4SLinus Torvalds 
96423bb5763SJohan Hedberg void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result);
9651da177e4SLinus Torvalds 
9662ce603ebSClaudio Takahasi void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
9672ce603ebSClaudio Takahasi 					u16 latency, u16 to_multiplier);
968a7a595f6SVinicius Costa Gomes void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8],
969a7a595f6SVinicius Costa Gomes 							__u8 ltk[16]);
970a7a595f6SVinicius Costa Gomes void hci_le_ltk_reply(struct hci_conn *conn, u8 ltk[16]);
971a7a595f6SVinicius Costa Gomes void hci_le_ltk_neg_reply(struct hci_conn *conn);
972a7a595f6SVinicius Costa Gomes 
9732519a1fcSAndre Guedes int hci_do_inquiry(struct hci_dev *hdev, u8 length);
9742519a1fcSAndre Guedes 
9751da177e4SLinus Torvalds #endif /* __HCI_CORE_H */
976