1/* -----------------------------------------------------------------------------
2 * Copyright (c) 2011 Ozmo Inc
3 * Released under the GNU General Public License Version 2 (GPLv2).
4 * -----------------------------------------------------------------------------
5 */
6#ifndef _OZPROTOCOL_H
7#define _OZPROTOCOL_H
8
9#define PACKED __packed
10
11#define OZ_ETHERTYPE 0x892e
12
13/* Status codes
14 */
15#define OZ_STATUS_SUCCESS		0
16#define OZ_STATUS_INVALID_PARAM		1
17#define OZ_STATUS_TOO_MANY_PDS		2
18#define OZ_STATUS_NOT_ALLOWED		4
19#define OZ_STATUS_SESSION_MISMATCH	5
20#define OZ_STATUS_SESSION_TEARDOWN	6
21
22/* This is the generic element header.
23   Every element starts with this.
24 */
25struct oz_elt {
26	u8 type;
27	u8 length;
28} PACKED;
29
30#define oz_next_elt(__elt)	\
31	(struct oz_elt *)((u8 *)((__elt) + 1) + (__elt)->length)
32
33/* Protocol element IDs.
34 */
35#define OZ_ELT_CONNECT_REQ	0x06
36#define OZ_ELT_CONNECT_RSP	0x07
37#define OZ_ELT_DISCONNECT	0x08
38#define OZ_ELT_UPDATE_PARAM_REQ	0x11
39#define OZ_ELT_FAREWELL_REQ	0x12
40#define OZ_ELT_APP_DATA		0x31
41
42/* This is the Ozmo header which is the first Ozmo specific part
43 * of a frame and comes after the MAC header.
44 */
45struct oz_hdr {
46	u8	control;
47	u8	last_pkt_num;
48	u32	pkt_num;
49} PACKED;
50
51#define OZ_PROTOCOL_VERSION	0x1
52/* Bits in the control field. */
53#define OZ_VERSION_MASK		0xc
54#define OZ_VERSION_SHIFT	2
55#define OZ_F_ACK		0x10
56#define OZ_F_ISOC		0x20
57#define OZ_F_MORE_DATA		0x40
58#define OZ_F_ACK_REQUESTED	0x80
59
60#define oz_get_prot_ver(__x)	(((__x) & OZ_VERSION_MASK) >> OZ_VERSION_SHIFT)
61
62/* Used to select the bits of packet number to put in the last_pkt_num.
63 */
64#define OZ_LAST_PN_MASK		0x00ff
65
66#define OZ_LAST_PN_HALF_CYCLE	127
67
68#define OZ_LATENCY_MASK		0xc0
69#define OZ_ONE_MS_LATENCY	0x40
70#define OZ_TEN_MS_LATENCY	0x80
71
72/* Connect request data structure.
73 */
74struct oz_elt_connect_req {
75	u8	mode;
76	u8	resv1[16];
77	u8	pd_info;
78	u8	session_id;
79	u8	presleep;
80	u8	ms_isoc_latency;
81	u8	host_vendor;
82	u8	keep_alive;
83	u16	apps;
84	u8	max_len_div16;
85	u8	ms_per_isoc;
86	u8	resv3[2];
87} PACKED;
88
89/* mode field bits.
90 */
91#define OZ_MODE_POLLED		0x0
92#define OZ_MODE_TRIGGERED	0x1
93#define OZ_MODE_MASK		0xf
94#define OZ_F_ISOC_NO_ELTS	0x40
95#define OZ_F_ISOC_ANYTIME	0x80
96#define OZ_NO_ELTS_ANYTIME	0xc0
97
98/* Keep alive field.
99 */
100#define OZ_KALIVE_TYPE_MASK	0xc0
101#define OZ_KALIVE_VALUE_MASK	0x3f
102#define OZ_KALIVE_SPECIAL	0x00
103#define OZ_KALIVE_SECS		0x40
104#define OZ_KALIVE_MINS		0x80
105#define OZ_KALIVE_HOURS		0xc0
106
107/* Connect response data structure.
108 */
109struct oz_elt_connect_rsp {
110	u8	mode;
111	u8	status;
112	u8	resv1[3];
113	u8	session_id;
114	u16	apps;
115	u32	resv2;
116} PACKED;
117
118struct oz_elt_farewell {
119	u8	ep_num;
120	u8	index;
121	u8	report[1];
122} PACKED;
123
124struct oz_elt_update_param {
125	u8	resv1[16];
126	u8	presleep;
127	u8	resv2;
128	u8	host_vendor;
129	u8	keepalive;
130} PACKED;
131
132/* Header common to all application elements.
133 */
134struct oz_app_hdr {
135	u8	app_id;
136	u8	elt_seq_num;
137} PACKED;
138
139/* Values for app_id.
140 */
141#define OZ_APPID_USB				0x1
142#define OZ_APPID_SERIAL				0x4
143#define OZ_APPID_MAX				OZ_APPID_SERIAL
144#define OZ_NB_APPS				(OZ_APPID_MAX+1)
145
146/* USB header common to all elements for the  USB application.
147 * This header extends the oz_app_hdr and comes directly after
148 * the element header in a USB application.
149 */
150struct oz_usb_hdr {
151	u8	app_id;
152	u8	elt_seq_num;
153	u8	type;
154} PACKED;
155
156
157
158/* USB requests element subtypes (type field of hs_usb_hdr).
159 */
160#define OZ_GET_DESC_REQ			1
161#define OZ_GET_DESC_RSP			2
162#define OZ_SET_CONFIG_REQ		3
163#define OZ_SET_CONFIG_RSP		4
164#define OZ_SET_INTERFACE_REQ		5
165#define OZ_SET_INTERFACE_RSP		6
166#define OZ_VENDOR_CLASS_REQ		7
167#define OZ_VENDOR_CLASS_RSP		8
168#define OZ_GET_STATUS_REQ		9
169#define OZ_GET_STATUS_RSP		10
170#define OZ_CLEAR_FEATURE_REQ		11
171#define OZ_CLEAR_FEATURE_RSP		12
172#define OZ_SET_FEATURE_REQ		13
173#define OZ_SET_FEATURE_RSP		14
174#define OZ_GET_CONFIGURATION_REQ	15
175#define OZ_GET_CONFIGURATION_RSP	16
176#define OZ_GET_INTERFACE_REQ		17
177#define OZ_GET_INTERFACE_RSP		18
178#define OZ_SYNCH_FRAME_REQ		19
179#define OZ_SYNCH_FRAME_RSP		20
180#define OZ_USB_ENDPOINT_DATA		23
181
182#define OZ_REQD_D2H			0x80
183
184struct oz_get_desc_req {
185	u8	app_id;
186	u8	elt_seq_num;
187	u8	type;
188	u8	req_id;
189	u16	offset;
190	u16	size;
191	u8	req_type;
192	u8	desc_type;
193	__le16	w_index;
194	u8	index;
195} PACKED;
196
197/* Values for desc_type field.
198*/
199#define OZ_DESC_DEVICE			0x01
200#define OZ_DESC_CONFIG			0x02
201#define OZ_DESC_STRING			0x03
202
203/* Values for req_type field.
204 */
205#define OZ_RECP_MASK			0x1F
206#define OZ_RECP_DEVICE			0x00
207#define OZ_RECP_INTERFACE		0x01
208#define OZ_RECP_ENDPOINT		0x02
209
210#define OZ_REQT_MASK			0x60
211#define OZ_REQT_STD			0x00
212#define OZ_REQT_CLASS			0x20
213#define OZ_REQT_VENDOR			0x40
214
215struct oz_get_desc_rsp {
216	u8	app_id;
217	u8	elt_seq_num;
218	u8	type;
219	u8	req_id;
220	__le16	offset;
221	__le16	total_size;
222	u8	rcode;
223	u8	data[1];
224} PACKED;
225
226struct oz_feature_req {
227	u8	app_id;
228	u8	elt_seq_num;
229	u8	type;
230	u8	req_id;
231	u8	recipient;
232	u8	index;
233	u16	feature;
234} PACKED;
235
236struct oz_feature_rsp {
237	u8	app_id;
238	u8	elt_seq_num;
239	u8	type;
240	u8	req_id;
241	u8	rcode;
242} PACKED;
243
244struct oz_set_config_req {
245	u8	app_id;
246	u8	elt_seq_num;
247	u8	type;
248	u8	req_id;
249	u8	index;
250} PACKED;
251
252struct oz_set_config_rsp {
253	u8	app_id;
254	u8	elt_seq_num;
255	u8	type;
256	u8	req_id;
257	u8	rcode;
258} PACKED;
259
260struct oz_set_interface_req {
261	u8	app_id;
262	u8	elt_seq_num;
263	u8	type;
264	u8	req_id;
265	u8	index;
266	u8	alternative;
267} PACKED;
268
269struct oz_set_interface_rsp {
270	u8	app_id;
271	u8	elt_seq_num;
272	u8	type;
273	u8	req_id;
274	u8	rcode;
275} PACKED;
276
277struct oz_get_interface_req {
278	u8	app_id;
279	u8	elt_seq_num;
280	u8	type;
281	u8	req_id;
282	u8	index;
283} PACKED;
284
285struct oz_get_interface_rsp {
286	u8	app_id;
287	u8	elt_seq_num;
288	u8	type;
289	u8	req_id;
290	u8	rcode;
291	u8	alternative;
292} PACKED;
293
294struct oz_vendor_class_req {
295	u8	app_id;
296	u8	elt_seq_num;
297	u8	type;
298	u8	req_id;
299	u8	req_type;
300	u8	request;
301	u16	value;
302	u16	index;
303	u8	data[1];
304} PACKED;
305
306struct oz_vendor_class_rsp {
307	u8	app_id;
308	u8	elt_seq_num;
309	u8	type;
310	u8	req_id;
311	u8	rcode;
312	u8	data[1];
313} PACKED;
314
315struct oz_data {
316	u8	app_id;
317	u8	elt_seq_num;
318	u8	type;
319	u8	endpoint;
320	u8	format;
321} PACKED;
322
323struct oz_isoc_fixed {
324	u8	app_id;
325	u8	elt_seq_num;
326	u8	type;
327	u8	endpoint;
328	u8	format;
329	u8	unit_size;
330	u8	frame_number;
331	u8	data[1];
332} PACKED;
333
334struct oz_multiple_fixed {
335	u8	app_id;
336	u8	elt_seq_num;
337	u8	type;
338	u8	endpoint;
339	u8	format;
340	u8	unit_size;
341	u8	data[1];
342} PACKED;
343
344struct oz_fragmented {
345	u8	app_id;
346	u8	elt_seq_num;
347	u8	type;
348	u8	endpoint;
349	u8	format;
350	u16	total_size;
351	u16	offset;
352	u8	data[1];
353} PACKED;
354
355/* Note: the following does not get packaged in an element in the same way
356 * that other data formats are packaged. Instead the data is put in a frame
357 * directly after the oz_header and is the only permitted data in such a
358 * frame. The length of the data is directly determined from the frame size.
359 */
360struct oz_isoc_large {
361	u8	endpoint;
362	u8	format;
363	u8	ms_data;
364	u8	frame_number;
365} PACKED;
366
367#define OZ_DATA_F_TYPE_MASK		0xF
368#define OZ_DATA_F_MULTIPLE_FIXED	0x1
369#define OZ_DATA_F_MULTIPLE_VAR		0x2
370#define OZ_DATA_F_ISOC_FIXED		0x3
371#define OZ_DATA_F_ISOC_VAR		0x4
372#define OZ_DATA_F_FRAGMENTED		0x5
373#define OZ_DATA_F_ISOC_LARGE		0x7
374
375#endif /* _OZPROTOCOL_H */
376