162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *  Bluetooth HCI UART driver
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci *  Copyright (C) 2000-2001  Qualcomm Incorporated
762306a36Sopenharmony_ci *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
862306a36Sopenharmony_ci *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef N_HCI
1262306a36Sopenharmony_ci#define N_HCI	15
1362306a36Sopenharmony_ci#endif
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/* Ioctls */
1662306a36Sopenharmony_ci#define HCIUARTSETPROTO		_IOW('U', 200, int)
1762306a36Sopenharmony_ci#define HCIUARTGETPROTO		_IOR('U', 201, int)
1862306a36Sopenharmony_ci#define HCIUARTGETDEVICE	_IOR('U', 202, int)
1962306a36Sopenharmony_ci#define HCIUARTSETFLAGS		_IOW('U', 203, int)
2062306a36Sopenharmony_ci#define HCIUARTGETFLAGS		_IOR('U', 204, int)
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* UART protocols */
2362306a36Sopenharmony_ci#define HCI_UART_MAX_PROTO	12
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define HCI_UART_H4	0
2662306a36Sopenharmony_ci#define HCI_UART_BCSP	1
2762306a36Sopenharmony_ci#define HCI_UART_3WIRE	2
2862306a36Sopenharmony_ci#define HCI_UART_H4DS	3
2962306a36Sopenharmony_ci#define HCI_UART_LL	4
3062306a36Sopenharmony_ci#define HCI_UART_ATH3K	5
3162306a36Sopenharmony_ci#define HCI_UART_INTEL	6
3262306a36Sopenharmony_ci#define HCI_UART_BCM	7
3362306a36Sopenharmony_ci#define HCI_UART_QCA	8
3462306a36Sopenharmony_ci#define HCI_UART_AG6XX	9
3562306a36Sopenharmony_ci#define HCI_UART_NOKIA	10
3662306a36Sopenharmony_ci#define HCI_UART_MRVL	11
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define HCI_UART_RAW_DEVICE	0
3962306a36Sopenharmony_ci#define HCI_UART_RESET_ON_INIT	1
4062306a36Sopenharmony_ci#define HCI_UART_CREATE_AMP	2
4162306a36Sopenharmony_ci#define HCI_UART_INIT_PENDING	3
4262306a36Sopenharmony_ci#define HCI_UART_EXT_CONFIG	4
4362306a36Sopenharmony_ci#define HCI_UART_VND_DETECT	5
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct hci_uart;
4662306a36Sopenharmony_cistruct serdev_device;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistruct hci_uart_proto {
4962306a36Sopenharmony_ci	unsigned int id;
5062306a36Sopenharmony_ci	const char *name;
5162306a36Sopenharmony_ci	unsigned int manufacturer;
5262306a36Sopenharmony_ci	unsigned int init_speed;
5362306a36Sopenharmony_ci	unsigned int oper_speed;
5462306a36Sopenharmony_ci	int (*open)(struct hci_uart *hu);
5562306a36Sopenharmony_ci	int (*close)(struct hci_uart *hu);
5662306a36Sopenharmony_ci	int (*flush)(struct hci_uart *hu);
5762306a36Sopenharmony_ci	int (*setup)(struct hci_uart *hu);
5862306a36Sopenharmony_ci	int (*set_baudrate)(struct hci_uart *hu, unsigned int speed);
5962306a36Sopenharmony_ci	int (*recv)(struct hci_uart *hu, const void *data, int len);
6062306a36Sopenharmony_ci	int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
6162306a36Sopenharmony_ci	struct sk_buff *(*dequeue)(struct hci_uart *hu);
6262306a36Sopenharmony_ci};
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistruct hci_uart {
6562306a36Sopenharmony_ci	struct tty_struct	*tty;
6662306a36Sopenharmony_ci	struct serdev_device	*serdev;
6762306a36Sopenharmony_ci	struct hci_dev		*hdev;
6862306a36Sopenharmony_ci	unsigned long		flags;
6962306a36Sopenharmony_ci	unsigned long		hdev_flags;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	struct work_struct	init_ready;
7262306a36Sopenharmony_ci	struct work_struct	write_work;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	const struct hci_uart_proto *proto;
7562306a36Sopenharmony_ci	struct percpu_rw_semaphore proto_lock;	/* Stop work for proto close */
7662306a36Sopenharmony_ci	void			*priv;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	struct sk_buff		*tx_skb;
7962306a36Sopenharmony_ci	unsigned long		tx_state;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	unsigned int init_speed;
8262306a36Sopenharmony_ci	unsigned int oper_speed;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	u8			alignment;
8562306a36Sopenharmony_ci	u8			padding;
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/* HCI_UART proto flag bits */
8962306a36Sopenharmony_ci#define HCI_UART_PROTO_SET		0
9062306a36Sopenharmony_ci#define HCI_UART_REGISTERED		1
9162306a36Sopenharmony_ci#define HCI_UART_PROTO_READY		2
9262306a36Sopenharmony_ci#define HCI_UART_NO_SUSPEND_NOTIFIER	3
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci/* TX states  */
9562306a36Sopenharmony_ci#define HCI_UART_SENDING	1
9662306a36Sopenharmony_ci#define HCI_UART_TX_WAKEUP	2
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ciint hci_uart_register_proto(const struct hci_uart_proto *p);
9962306a36Sopenharmony_ciint hci_uart_unregister_proto(const struct hci_uart_proto *p);
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ciint hci_uart_register_device_priv(struct hci_uart *hu,
10262306a36Sopenharmony_ci				  const struct hci_uart_proto *p,
10362306a36Sopenharmony_ci				  int sizeof_priv);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic inline int hci_uart_register_device(struct hci_uart *hu,
10662306a36Sopenharmony_ci					   const struct hci_uart_proto *p)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	return hci_uart_register_device_priv(hu, p, 0);
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_civoid hci_uart_unregister_device(struct hci_uart *hu);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciint hci_uart_tx_wakeup(struct hci_uart *hu);
11462306a36Sopenharmony_ciint hci_uart_wait_until_sent(struct hci_uart *hu);
11562306a36Sopenharmony_ciint hci_uart_init_ready(struct hci_uart *hu);
11662306a36Sopenharmony_civoid hci_uart_init_work(struct work_struct *work);
11762306a36Sopenharmony_civoid hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed);
11862306a36Sopenharmony_cibool hci_uart_has_flow_control(struct hci_uart *hu);
11962306a36Sopenharmony_civoid hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
12062306a36Sopenharmony_civoid hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
12162306a36Sopenharmony_ci			 unsigned int oper_speed);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_H4
12462306a36Sopenharmony_ciint h4_init(void);
12562306a36Sopenharmony_ciint h4_deinit(void);
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistruct h4_recv_pkt {
12862306a36Sopenharmony_ci	u8  type;	/* Packet type */
12962306a36Sopenharmony_ci	u8  hlen;	/* Header length */
13062306a36Sopenharmony_ci	u8  loff;	/* Data length offset in header */
13162306a36Sopenharmony_ci	u8  lsize;	/* Data length field size */
13262306a36Sopenharmony_ci	u16 maxlen;	/* Max overall packet length */
13362306a36Sopenharmony_ci	int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#define H4_RECV_ACL \
13762306a36Sopenharmony_ci	.type = HCI_ACLDATA_PKT, \
13862306a36Sopenharmony_ci	.hlen = HCI_ACL_HDR_SIZE, \
13962306a36Sopenharmony_ci	.loff = 2, \
14062306a36Sopenharmony_ci	.lsize = 2, \
14162306a36Sopenharmony_ci	.maxlen = HCI_MAX_FRAME_SIZE \
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#define H4_RECV_SCO \
14462306a36Sopenharmony_ci	.type = HCI_SCODATA_PKT, \
14562306a36Sopenharmony_ci	.hlen = HCI_SCO_HDR_SIZE, \
14662306a36Sopenharmony_ci	.loff = 2, \
14762306a36Sopenharmony_ci	.lsize = 1, \
14862306a36Sopenharmony_ci	.maxlen = HCI_MAX_SCO_SIZE
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci#define H4_RECV_EVENT \
15162306a36Sopenharmony_ci	.type = HCI_EVENT_PKT, \
15262306a36Sopenharmony_ci	.hlen = HCI_EVENT_HDR_SIZE, \
15362306a36Sopenharmony_ci	.loff = 1, \
15462306a36Sopenharmony_ci	.lsize = 1, \
15562306a36Sopenharmony_ci	.maxlen = HCI_MAX_EVENT_SIZE
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci#define H4_RECV_ISO \
15862306a36Sopenharmony_ci	.type = HCI_ISODATA_PKT, \
15962306a36Sopenharmony_ci	.hlen = HCI_ISO_HDR_SIZE, \
16062306a36Sopenharmony_ci	.loff = 2, \
16162306a36Sopenharmony_ci	.lsize = 2, \
16262306a36Sopenharmony_ci	.maxlen = HCI_MAX_FRAME_SIZE \
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistruct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
16562306a36Sopenharmony_ci			    const unsigned char *buffer, int count,
16662306a36Sopenharmony_ci			    const struct h4_recv_pkt *pkts, int pkts_count);
16762306a36Sopenharmony_ci#endif
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_BCSP
17062306a36Sopenharmony_ciint bcsp_init(void);
17162306a36Sopenharmony_ciint bcsp_deinit(void);
17262306a36Sopenharmony_ci#endif
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_LL
17562306a36Sopenharmony_ciint ll_init(void);
17662306a36Sopenharmony_ciint ll_deinit(void);
17762306a36Sopenharmony_ci#endif
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_ATH3K
18062306a36Sopenharmony_ciint ath_init(void);
18162306a36Sopenharmony_ciint ath_deinit(void);
18262306a36Sopenharmony_ci#endif
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_3WIRE
18562306a36Sopenharmony_ciint h5_init(void);
18662306a36Sopenharmony_ciint h5_deinit(void);
18762306a36Sopenharmony_ci#endif
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_INTEL
19062306a36Sopenharmony_ciint intel_init(void);
19162306a36Sopenharmony_ciint intel_deinit(void);
19262306a36Sopenharmony_ci#endif
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_BCM
19562306a36Sopenharmony_ciint bcm_init(void);
19662306a36Sopenharmony_ciint bcm_deinit(void);
19762306a36Sopenharmony_ci#endif
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_QCA
20062306a36Sopenharmony_ciint qca_init(void);
20162306a36Sopenharmony_ciint qca_deinit(void);
20262306a36Sopenharmony_ci#endif
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_AG6XX
20562306a36Sopenharmony_ciint ag6xx_init(void);
20662306a36Sopenharmony_ciint ag6xx_deinit(void);
20762306a36Sopenharmony_ci#endif
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci#ifdef CONFIG_BT_HCIUART_MRVL
21062306a36Sopenharmony_ciint mrvl_init(void);
21162306a36Sopenharmony_ciint mrvl_deinit(void);
21262306a36Sopenharmony_ci#endif
213