18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci   Copyright (c) 2010,2011 Code Aurora Forum.  All rights reserved.
48c2ecf20Sopenharmony_ci   Copyright (c) 2011,2012 Intel Corp.
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci*/
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __A2MP_H
98c2ecf20Sopenharmony_ci#define __A2MP_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <net/bluetooth/l2cap.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cienum amp_mgr_state {
148c2ecf20Sopenharmony_ci	READ_LOC_AMP_INFO,
158c2ecf20Sopenharmony_ci	READ_LOC_AMP_ASSOC,
168c2ecf20Sopenharmony_ci	READ_LOC_AMP_ASSOC_FINAL,
178c2ecf20Sopenharmony_ci	WRITE_REMOTE_AMP_ASSOC,
188c2ecf20Sopenharmony_ci};
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistruct amp_mgr {
218c2ecf20Sopenharmony_ci	struct list_head	list;
228c2ecf20Sopenharmony_ci	struct l2cap_conn	*l2cap_conn;
238c2ecf20Sopenharmony_ci	struct l2cap_chan	*a2mp_chan;
248c2ecf20Sopenharmony_ci	struct l2cap_chan	*bredr_chan;
258c2ecf20Sopenharmony_ci	struct kref		kref;
268c2ecf20Sopenharmony_ci	__u8			ident;
278c2ecf20Sopenharmony_ci	__u8			handle;
288c2ecf20Sopenharmony_ci	unsigned long		state;
298c2ecf20Sopenharmony_ci	unsigned long		flags;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	struct list_head	amp_ctrls;
328c2ecf20Sopenharmony_ci	struct mutex		amp_ctrls_lock;
338c2ecf20Sopenharmony_ci};
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistruct a2mp_cmd {
368c2ecf20Sopenharmony_ci	__u8	code;
378c2ecf20Sopenharmony_ci	__u8	ident;
388c2ecf20Sopenharmony_ci	__le16	len;
398c2ecf20Sopenharmony_ci	__u8	data[];
408c2ecf20Sopenharmony_ci} __packed;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/* A2MP command codes */
438c2ecf20Sopenharmony_ci#define A2MP_COMMAND_REJ         0x01
448c2ecf20Sopenharmony_cistruct a2mp_cmd_rej {
458c2ecf20Sopenharmony_ci	__le16	reason;
468c2ecf20Sopenharmony_ci	__u8	data[];
478c2ecf20Sopenharmony_ci} __packed;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#define A2MP_DISCOVER_REQ        0x02
508c2ecf20Sopenharmony_cistruct a2mp_discov_req {
518c2ecf20Sopenharmony_ci	__le16	mtu;
528c2ecf20Sopenharmony_ci	__le16	ext_feat;
538c2ecf20Sopenharmony_ci} __packed;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistruct a2mp_cl {
568c2ecf20Sopenharmony_ci	__u8	id;
578c2ecf20Sopenharmony_ci	__u8	type;
588c2ecf20Sopenharmony_ci	__u8	status;
598c2ecf20Sopenharmony_ci} __packed;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci#define A2MP_DISCOVER_RSP        0x03
628c2ecf20Sopenharmony_cistruct a2mp_discov_rsp {
638c2ecf20Sopenharmony_ci	__le16     mtu;
648c2ecf20Sopenharmony_ci	__le16     ext_feat;
658c2ecf20Sopenharmony_ci	struct a2mp_cl cl[];
668c2ecf20Sopenharmony_ci} __packed;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci#define A2MP_CHANGE_NOTIFY       0x04
698c2ecf20Sopenharmony_ci#define A2MP_CHANGE_RSP          0x05
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci#define A2MP_GETINFO_REQ         0x06
728c2ecf20Sopenharmony_cistruct a2mp_info_req {
738c2ecf20Sopenharmony_ci	__u8       id;
748c2ecf20Sopenharmony_ci} __packed;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#define A2MP_GETINFO_RSP         0x07
778c2ecf20Sopenharmony_cistruct a2mp_info_rsp {
788c2ecf20Sopenharmony_ci	__u8	id;
798c2ecf20Sopenharmony_ci	__u8	status;
808c2ecf20Sopenharmony_ci	__le32	total_bw;
818c2ecf20Sopenharmony_ci	__le32	max_bw;
828c2ecf20Sopenharmony_ci	__le32	min_latency;
838c2ecf20Sopenharmony_ci	__le16	pal_cap;
848c2ecf20Sopenharmony_ci	__le16	assoc_size;
858c2ecf20Sopenharmony_ci} __packed;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#define A2MP_GETAMPASSOC_REQ     0x08
888c2ecf20Sopenharmony_cistruct a2mp_amp_assoc_req {
898c2ecf20Sopenharmony_ci	__u8	id;
908c2ecf20Sopenharmony_ci} __packed;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#define A2MP_GETAMPASSOC_RSP     0x09
938c2ecf20Sopenharmony_cistruct a2mp_amp_assoc_rsp {
948c2ecf20Sopenharmony_ci	__u8	id;
958c2ecf20Sopenharmony_ci	__u8	status;
968c2ecf20Sopenharmony_ci	__u8	amp_assoc[];
978c2ecf20Sopenharmony_ci} __packed;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#define A2MP_CREATEPHYSLINK_REQ  0x0A
1008c2ecf20Sopenharmony_ci#define A2MP_DISCONNPHYSLINK_REQ 0x0C
1018c2ecf20Sopenharmony_cistruct a2mp_physlink_req {
1028c2ecf20Sopenharmony_ci	__u8	local_id;
1038c2ecf20Sopenharmony_ci	__u8	remote_id;
1048c2ecf20Sopenharmony_ci	__u8	amp_assoc[];
1058c2ecf20Sopenharmony_ci} __packed;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci#define A2MP_CREATEPHYSLINK_RSP  0x0B
1088c2ecf20Sopenharmony_ci#define A2MP_DISCONNPHYSLINK_RSP 0x0D
1098c2ecf20Sopenharmony_cistruct a2mp_physlink_rsp {
1108c2ecf20Sopenharmony_ci	__u8	local_id;
1118c2ecf20Sopenharmony_ci	__u8	remote_id;
1128c2ecf20Sopenharmony_ci	__u8	status;
1138c2ecf20Sopenharmony_ci} __packed;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci/* A2MP response status */
1168c2ecf20Sopenharmony_ci#define A2MP_STATUS_SUCCESS			0x00
1178c2ecf20Sopenharmony_ci#define A2MP_STATUS_INVALID_CTRL_ID		0x01
1188c2ecf20Sopenharmony_ci#define A2MP_STATUS_UNABLE_START_LINK_CREATION	0x02
1198c2ecf20Sopenharmony_ci#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS	0x02
1208c2ecf20Sopenharmony_ci#define A2MP_STATUS_COLLISION_OCCURED		0x03
1218c2ecf20Sopenharmony_ci#define A2MP_STATUS_DISCONN_REQ_RECVD		0x04
1228c2ecf20Sopenharmony_ci#define A2MP_STATUS_PHYS_LINK_EXISTS		0x05
1238c2ecf20Sopenharmony_ci#define A2MP_STATUS_SECURITY_VIOLATION		0x06
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_cistruct amp_mgr *amp_mgr_get(struct amp_mgr *mgr);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_BT_HS)
1288c2ecf20Sopenharmony_ciint amp_mgr_put(struct amp_mgr *mgr);
1298c2ecf20Sopenharmony_cistruct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
1308c2ecf20Sopenharmony_ci				       struct sk_buff *skb);
1318c2ecf20Sopenharmony_civoid a2mp_discover_amp(struct l2cap_chan *chan);
1328c2ecf20Sopenharmony_ci#else
1338c2ecf20Sopenharmony_cistatic inline int amp_mgr_put(struct amp_mgr *mgr)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	return 0;
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_cistatic inline struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
1398c2ecf20Sopenharmony_ci						     struct sk_buff *skb)
1408c2ecf20Sopenharmony_ci{
1418c2ecf20Sopenharmony_ci	return NULL;
1428c2ecf20Sopenharmony_ci}
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistatic inline void a2mp_discover_amp(struct l2cap_chan *chan)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci#endif
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_civoid a2mp_send_getinfo_rsp(struct hci_dev *hdev);
1508c2ecf20Sopenharmony_civoid a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status);
1518c2ecf20Sopenharmony_civoid a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status);
1528c2ecf20Sopenharmony_civoid a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#endif /* __A2MP_H */
155