blob: 53fea3707a599a2a173d552643f81c47ec21f742 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 Copyright (c) 2010-2011 Code Aurora Forum. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License version 2 and
6 only version 2 as published by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12*/
13
14#ifndef __AMP_H
15#define __AMP_H
16
17/* AMP defaults */
18
Peter Krystad101c1842011-09-22 11:00:31 -070019#define A2MP_RSP_TIMEOUT (8000) /* 8 seconds */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020
21/* A2MP Protocol */
22
23/* A2MP command codes */
24#define A2MP_COMMAND_REJ 0x01
25#define A2MP_DISCOVER_REQ 0x02
26#define A2MP_DISCOVER_RSP 0x03
27#define A2MP_CHANGE_NOTIFY 0x04
28#define A2MP_CHANGE_RSP 0x05
29#define A2MP_GETINFO_REQ 0x06
30#define A2MP_GETINFO_RSP 0x07
31#define A2MP_GETAMPASSOC_REQ 0x08
32#define A2MP_GETAMPASSOC_RSP 0x09
33#define A2MP_CREATEPHYSLINK_REQ 0x0A
34#define A2MP_CREATEPHYSLINK_RSP 0x0B
35#define A2MP_DISCONNPHYSLINK_REQ 0x0C
36#define A2MP_DISCONNPHYSLINK_RSP 0x0D
37
38struct a2mp_cmd_hdr {
39 __u8 code;
40 __u8 ident;
41 __le16 len;
42} __packed;
43
44struct a2mp_cmd_rej {
45 __le16 reason;
46} __packed;
47
48#define HCI_A2MP_ID(id) ((id)+0x10) /* convert HCI dev index to AMP ID */
49#define A2MP_HCI_ID(id) ((id)-0x10) /* convert AMP ID to HCI dev index */
50
51struct a2mp_discover_req {
52 __le16 mtu;
53 __le16 ext_feat;
54} __packed;
55
56struct a2mp_cl {
57 __u8 id;
58 __u8 type;
59 __u8 status;
60} __packed;
61
62struct a2mp_discover_rsp {
63 __le16 mtu;
64 __le16 ext_feat;
65 struct a2mp_cl cl[0];
66} __packed;
67
68struct a2mp_getinfo_req {
69 __u8 id;
70} __packed;
71
72struct a2mp_getinfo_rsp {
73 __u8 id;
74 __u8 status;
75 __le32 total_bw;
76 __le32 max_bw;
77 __le32 min_latency;
78 __le16 pal_cap;
79 __le16 assoc_size;
80} __packed;
81
82struct a2mp_getampassoc_req {
83 __u8 id;
84} __packed;
85
86struct a2mp_getampassoc_rsp {
87 __u8 id;
88 __u8 status;
89 __u8 amp_assoc[0];
90} __packed;
91
92struct a2mp_createphyslink_req {
93 __u8 local_id;
94 __u8 remote_id;
95 __u8 amp_assoc[0];
96} __packed;
97
98struct a2mp_createphyslink_rsp {
99 __u8 local_id;
100 __u8 remote_id;
101 __u8 status;
102} __packed;
103
104struct a2mp_disconnphyslink_req {
105 __u8 local_id;
106 __u8 remote_id;
107} __packed;
108
109struct a2mp_disconnphyslink_rsp {
110 __u8 local_id;
111 __u8 remote_id;
112 __u8 status;
113} __packed;
114
115
116/* L2CAP-AMP module interface */
117int amp_init(void);
118void amp_exit(void);
119
120/* L2CAP-AMP fixed channel interface */
121void amp_conn_ind(struct l2cap_conn *conn, struct sk_buff *skb);
122
123/* L2CAP-AMP link interface */
124void amp_create_physical(struct l2cap_conn *conn, struct sock *sk);
125void amp_accept_physical(struct l2cap_conn *conn, u8 id, struct sock *sk);
126
127/* AMP manager internals */
128struct amp_ctrl {
129 struct amp_mgr *mgr;
130 __u8 id;
131 __u8 type;
132 __u8 status;
133 __u32 total_bw;
134 __u32 max_bw;
135 __u32 min_latency;
136 __u16 pal_cap;
137 __u16 max_assoc_size;
138};
139
140struct amp_mgr {
141 struct list_head list;
142 __u8 discovered;
143 __u8 next_ident;
144 struct l2cap_conn *l2cap_conn;
145 struct socket *a2mp_sock;
146 struct list_head ctx_list;
147 rwlock_t ctx_list_lock;
148 struct amp_ctrl *ctrls; /* @@ TODO s.b. list of controllers */
149 struct sk_buff *skb;
150 __u8 connected;
151};
152
153/* AMP Manager signalling contexts */
154#define AMP_GETAMPASSOC 1
155#define AMP_CREATEPHYSLINK 2
156#define AMP_ACCEPTPHYSLINK 3
157#define AMP_CREATELOGLINK 4
158#define AMP_ACCEPTLOGLINK 5
159
160/* Get AMP Assoc sequence */
161#define AMP_GAA_INIT 0
162#define AMP_GAA_RLAA_COMPLETE 1
163struct amp_gaa_state {
164 __u8 req_ident;
165 __u16 len_so_far;
166 __u8 *assoc;
167};
168
169/* Create Physical Link sequence */
170#define AMP_CPL_INIT 0
171#define AMP_CPL_DISC_RSP 1
172#define AMP_CPL_GETINFO_RSP 2
173#define AMP_CPL_GAA_RSP 3
174#define AMP_CPL_CPL_STATUS 4
175#define AMP_CPL_WRA_COMPLETE 5
176#define AMP_CPL_CHANNEL_SELECT 6
177#define AMP_CPL_RLA_COMPLETE 7
178#define AMP_CPL_PL_COMPLETE 8
179#define AMP_CPL_PL_CANCEL 9
180struct amp_cpl_state {
181 __u8 remote_id;
182 __u16 max_len;
183 __u8 *remote_assoc;
184 __u8 *local_assoc;
185 __u16 len_so_far;
186 __u16 rem_len;
187 __u8 phy_handle;
188};
189
190/* Accept Physical Link sequence */
191#define AMP_APL_INIT 0
192#define AMP_APL_APL_STATUS 1
193#define AMP_APL_WRA_COMPLETE 2
194#define AMP_APL_PL_COMPLETE 3
195struct amp_apl_state {
196 __u8 remote_id;
197 __u8 req_ident;
198 __u8 *remote_assoc;
199 __u16 len_so_far;
200 __u16 rem_len;
201 __u8 phy_handle;
202};
203
204/* Create/Accept Logical Link sequence */
205#define AMP_LOG_INIT 0
206#define AMP_LOG_LL_STATUS 1
207#define AMP_LOG_LL_COMPLETE 2
208struct amp_log_state {
209 __u8 remote_id;
210};
211
212/* Possible event types a context may wait for */
213#define AMP_INIT 0x01
214#define AMP_HCI_EVENT 0x02
215#define AMP_HCI_CMD_CMPLT 0x04
216#define AMP_HCI_CMD_STATUS 0x08
217#define AMP_A2MP_RSP 0x10
218#define AMP_KILLED 0x20
219#define AMP_CANCEL 0x40
220struct amp_ctx {
221 struct list_head list;
222 struct amp_mgr *mgr;
223 struct hci_dev *hdev;
224 __u8 type;
225 __u8 state;
226 union {
227 struct amp_gaa_state gaa;
228 struct amp_cpl_state cpl;
229 struct amp_apl_state apl;
230 } d;
231 __u8 evt_type;
232 __u8 evt_code;
233 __u16 opcode;
234 __u8 id;
235 __u8 rsp_ident;
236
237 struct sock *sk;
238 struct amp_ctx *deferred;
239 struct timer_list timer;
240};
241
242/* AMP work */
243struct amp_work_pl_timeout {
244 struct work_struct work;
245 struct amp_ctrl *ctrl;
246};
247struct amp_work_ctx_timeout {
248 struct work_struct work;
249 struct amp_ctx *ctx;
250};
251struct amp_work_data_ready {
252 struct work_struct work;
253 struct sock *sk;
254 int bytes;
255};
256struct amp_work_state_change {
257 struct work_struct work;
258 struct sock *sk;
259};
260struct amp_work_conn_ind {
261 struct work_struct work;
262 struct l2cap_conn *conn;
263 struct sk_buff *skb;
264};
265struct amp_work_create_physical {
266 struct work_struct work;
267 struct l2cap_conn *conn;
268 u8 id;
269 struct sock *sk;
270};
271struct amp_work_accept_physical {
272 struct work_struct work;
273 struct l2cap_conn *conn;
274 u8 id;
275 struct sock *sk;
276};
277struct amp_work_cmd_cmplt {
278 struct work_struct work;
279 struct hci_dev *hdev;
280 u16 opcode;
281 struct sk_buff *skb;
282};
283struct amp_work_cmd_status {
284 struct work_struct work;
285 struct hci_dev *hdev;
286 u16 opcode;
287 u8 status;
288};
289struct amp_work_event {
290 struct work_struct work;
291 struct hci_dev *hdev;
292 u8 event;
293 struct sk_buff *skb;
294};
295
296#endif /* __AMP_H */