1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#ifndef	_SYS_1394_IXL1394_H
28#define	_SYS_1394_IXL1394_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32/*
33 * ixl1394.h
34 *    Contains all defines and structures necessary for Isochronous Transfer
35 *    Language (IXL) programs. IXL programs are used to specify the transmission
36 *    or receipt of isochronous packets for an isochronous channel.
37 */
38
39#ifdef	__cplusplus
40extern "C" {
41#endif
42
43#include <sys/note.h>
44
45/*
46 * Error codes for IXL program compilation and dynamic update
47 * Comments indicate which are source of error
48 * NOTE: Make sure IXL1394_COMP_ERR_LAST is updated if a new error code is
49 * added. t1394_errmsg.c uses *FIRST and *LAST as bounds checks.
50 */
51#define	IXL1394_EMEM_ALLOC_FAIL		(-301)	/* compile only */
52#define	IXL1394_EBAD_IXL_OPCODE		(-302)	/* compile only */
53#define	IXL1394_EFRAGMENT_OFLO		(-303)	/* compile only */
54#define	IXL1394_ENO_DATA_PKTS		(-304)	/* compile only */
55#define	IXL1394_EMISPLACED_RECV		(-305)	/* compile only */
56#define	IXL1394_EMISPLACED_SEND		(-306)	/* compile only */
57#define	IXL1394_EPKT_HDR_MISSING	(-307)	/* compile & update */
58#define	IXL1394_ENULL_BUFFER_ADDR	(-308)	/* compile only */
59#define	IXL1394_EPKTSIZE_MAX_OFLO	(-309)	/* compile & update */
60#define	IXL1394_EPKTSIZE_RATIO		(-310)	/* compile only */
61#define	IXL1394_EUNAPPLIED_SET_CMD	(-311)	/* compile only */
62#define	IXL1394_EDUPLICATE_SET_CMD	(-312)	/* compile only */
63#define	IXL1394_EJUMP_NOT_TO_LABEL	(-313)	/* compile & update */
64#define	IXL1394_EUPDATE_DISALLOWED	(-314)	/* compile & update */
65#define	IXL1394_EBAD_SKIPMODE		(-315)	/* compile & update */
66#define	IXL1394_EWRONG_XR_CMD_MODE	(-316)	/* compile only */
67#define	IXL1394_EINTERNAL_ERROR		(-317)	/* compile & update */
68#define	IXL1394_ENOT_IMPLEMENTED	(-318)	/* compile only */
69#define	IXL1394_EOPCODE_MISMATCH	(-319)	/* update only */
70#define	IXL1394_EOPCODE_DISALLOWED	(-320)	/* update only */
71#define	IXL1394_EBAD_SKIP_LABEL		(-321)	/* update only */
72#define	IXL1394_EXFER_BUF_MISSING	(-322)	/* update only */
73#define	IXL1394_EXFER_BUF_CNT_DIFF	(-323)	/* update only */
74#define	IXL1394_EORIG_IXL_CORRUPTED	(-324)	/* update only */
75#define	IXL1394_ECOUNT_MISMATCH		(-325)	/* update only */
76#define	IXL1394_EPRE_UPD_DMALOST	(-326)	/* update only */
77#define	IXL1394_EPOST_UPD_DMALOST	(-327)	/* update only */
78#define	IXL1394_ERISK_PROHIBITS_UPD	(-328)	/* update only */
79
80#define	IXL1394_COMP_ERR_FIRST		IXL1394_EMEM_ALLOC_FAIL
81#define	IXL1394_COMP_ERR_LAST		IXL1394_ERISK_PROHIBITS_UPD
82
83#define	IXL1394_ENO_DMA_RESRCS		(-200)
84
85
86/*
87 * IXL command opcodes
88 *
89 * IXL opcodes contain a unique opcode identifier and various flags to
90 * speed compilation.
91 */
92
93/* 5 flag bits at high end of opcode field. */
94#define	IXL1394_OPF_MASK	0xF800
95#define	IXL1394_OPF_UPDATE	0x8000	/* cmd update allowed during exec */
96#define	IXL1394_OPF_ONRECV	0x4000	/* cmd is allowed on recv */
97#define	IXL1394_OPF_ONXMIT	0x2000	/* cmd is allowed on xmit */
98#define	IXL1394_OPF_ENDSXFER	0x1000	/* cmd ends cur pkt xfer build */
99#define	IXL1394_OPF_ISXFER	0x0800	/* cmd is data transfer command */
100
101/* Useful flag composites. */
102#define	IXL1394_OPF_ONXFER	(IXL1394_OPF_ONXMIT | IXL1394_OPF_ONRECV)
103#define	IXL1394_OPF_ONXFER_ENDS (IXL1394_OPF_ONXFER | IXL1394_OPF_ENDSXFER)
104#define	IXL1394_OPF_ONRECV_ENDS (IXL1394_OPF_ONRECV | IXL1394_OPF_ENDSXFER)
105#define	IXL1394_OPF_ONXMIT_ENDS (IXL1394_OPF_ONXMIT | IXL1394_OPF_ENDSXFER)
106
107/* 2 type bits whose contents are interpreted based on isxr setting */
108#define	IXL1394_OPTY_MASK		0x0600
109
110/* type bits when isxfer == 0 */
111#define	IXL1394_OPTY_OTHER		0x0000
112
113/* type bits when isxr == 1 */
114#define	IXL1394_OPTY_XFER_PKT		(0x0000 | IXL1394_OPF_ISXFER)
115#define	IXL1394_OPTY_XFER_PKT_ST	(0x0200 | IXL1394_OPF_ISXFER)
116#define	IXL1394_OPTY_XFER_BUF_ST	(0x0400 | IXL1394_OPF_ISXFER)
117#define	IXL1394_OPTY_XFER_SPCL_ST	(0x0600 | IXL1394_OPF_ISXFER)
118
119/*
120 * IXL Command Opcodes.
121 */
122#define	IXL1394_OP_LABEL    (1 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONXFER_ENDS)
123#define	IXL1394_OP_JUMP	    (2 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONXFER_ENDS)
124#define	IXL1394_OP_CALLBACK (3 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONXFER)
125#define	IXL1394_OP_RECV_PKT (4 | IXL1394_OPTY_XFER_PKT | IXL1394_OPF_ONRECV)
126#define	IXL1394_OP_RECV_PKT_ST \
127		(5 | IXL1394_OPTY_XFER_PKT_ST |	IXL1394_OPF_ONRECV_ENDS)
128#define	IXL1394_OP_RECV_BUF \
129		(6 | IXL1394_OPTY_XFER_BUF_ST |	IXL1394_OPF_ONRECV_ENDS)
130#define	IXL1394_OP_SEND_PKT (7 | IXL1394_OPTY_XFER_PKT | IXL1394_OPF_ONXMIT)
131#define	IXL1394_OP_SEND_PKT_ST \
132		(8 | IXL1394_OPTY_XFER_PKT_ST |	IXL1394_OPF_ONXMIT_ENDS)
133#define	IXL1394_OP_SEND_PKT_WHDR_ST \
134		(9  | IXL1394_OPTY_XFER_PKT_ST | IXL1394_OPF_ONXMIT_ENDS)
135#define	IXL1394_OP_SEND_BUF \
136		(10 | IXL1394_OPTY_XFER_BUF_ST | IXL1394_OPF_ONXMIT_ENDS)
137#define	IXL1394_OP_SEND_HDR_ONLY \
138		(12 | IXL1394_OPTY_XFER_SPCL_ST | IXL1394_OPF_ONXMIT_ENDS)
139#define	IXL1394_OP_SEND_NO_PKT \
140		(13 | IXL1394_OPTY_XFER_SPCL_ST | IXL1394_OPF_ONXMIT_ENDS)
141#define	IXL1394_OP_STORE_TIMESTAMP \
142		(14 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONXFER)
143#define	IXL1394_OP_SET_TAGSYNC \
144		(15 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONXMIT_ENDS)
145#define	IXL1394_OP_SET_SKIPMODE \
146		(16 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONXMIT_ENDS)
147#define	IXL1394_OP_SET_SYNCWAIT \
148		(17 | IXL1394_OPTY_OTHER | IXL1394_OPF_ONRECV_ENDS)
149
150/*
151 * The dynamic UPDATE versions of each updatable command.
152 */
153#define	IXL1394_OP_JUMP_U	(IXL1394_OP_JUMP | IXL1394_OPF_UPDATE)
154#define	IXL1394_OP_CALLBACK_U	(IXL1394_OP_CALLBACK | IXL1394_OPF_UPDATE)
155#define	IXL1394_OP_RECV_PKT_U	(IXL1394_OP_RECV_PKT | IXL1394_OPF_UPDATE)
156#define	IXL1394_OP_RECV_PKT_ST_U (IXL1394_OP_RECV_PKT_ST | IXL1394_OPF_UPDATE)
157#define	IXL1394_OP_RECV_BUF_U	(IXL1394_OP_RECV_BUF | IXL1394_OPF_UPDATE)
158#define	IXL1394_OP_SEND_PKT_U	(IXL1394_OP_SEND_PKT | IXL1394_OPF_UPDATE)
159#define	IXL1394_OP_SEND_PKT_ST_U (IXL1394_OP_SEND_PKT_ST | IXL1394_OPF_UPDATE)
160#define	IXL1394_OP_SEND_PKT_WHDR_ST_U (IXL1394_OP_SEND_PKT_WHDR_ST |	\
161	    IXL1394_OPF_UPDATE)
162#define	IXL1394_OP_SEND_BUF_U	(IXL1394_OP_SEND_BUF | IXL1394_OPF_UPDATE)
163#define	IXL1394_OP_SET_TAGSYNC_U (IXL1394_OP_SET_TAGSYNC | IXL1394_OPF_UPDATE)
164#define	IXL1394_OP_SET_SKIPMODE_U (IXL1394_OP_SET_SKIPMODE | IXL1394_OPF_UPDATE)
165
166
167/* Opaque type for the ixl private data */
168typedef struct ixl_priv_handle	*ixl1394_priv_t;
169
170/* IXL1394_OP_SET_SKIPMODE values (used only with isoch transmit) */
171typedef enum {
172	IXL1394_SKIP_TO_SELF	= 0,
173	IXL1394_SKIP_TO_NEXT	= 1,
174	IXL1394_SKIP_TO_STOP	= 2,
175	IXL1394_SKIP_TO_LABEL	= 3
176} ixl1394_skip_t;
177
178/*
179 * IXL Program Command Primitives
180 */
181
182/* The general command format.  The operands vary depending on the opcode */
183typedef struct ixl1394_command {
184	struct ixl1394_command	*next_ixlp;
185	ixl1394_priv_t		compiler_privatep;
186	uint16_t		compiler_resv;
187	uint16_t		ixl_opcode;
188	uint32_t		operands[1];
189} ixl1394_command_t;
190
191_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
192	ixl1394_command::compiler_privatep \
193	ixl1394_command::compiler_resv))
194
195/*
196 * command structure used for a DDI_DMA bound buffer. For portability,
197 * set this _dmac_ll to the buffer's allocated and bound
198 * ddi_dma_cookie_t's _dmac_ll.
199 */
200typedef union ixl1394_buf_u {
201	uint64_t		_dmac_ll;	/* 64-bit DMA address */
202	uint32_t		_dmac_la[2];	/* 2 x 32-bit address */
203} ixl1394_buf_t;
204
205/* shorthand access to IXL command buffers.  similar to defs in dditypes.h */
206#define	ixldmac_laddr	_dmac_ll
207#ifdef _LONG_LONG_HTOL
208#define	ixldmac_notused	_dmac_la[0]
209#define	ixldmac_addr	_dmac_la[1]
210#else
211#define	ixldmac_addr	_dmac_la[0]
212#define	ixldmac_notused	_dmac_la[1]
213#endif
214
215
216/*
217 * ixl1394_xfer_pkt
218 * Specifies a packet fragment.
219 * Used with IXL1394_OP_SEND_PKT_ST, IXL1394_OP_SEND_PKT_WHDR_ST,
220 * IXL1394_OP_SEND_PKT, IXL1394_OP_RECV_PKT_ST and IXL1394_OP_RECV_PKT.
221 */
222typedef struct ixl1394_xfer_pkt {
223	ixl1394_command_t	*next_ixlp;
224	ixl1394_priv_t		compiler_privatep;
225	uint16_t		compiler_resv;
226	uint16_t		ixl_opcode;
227	uint16_t		size;		/* bytes in ixl_buf */
228	uint16_t		resv;
229	ixl1394_buf_t		ixl_buf;	/* ddi_dma bound address */
230	caddr_t			mem_bufp;	/* kernel virtual addr */
231} ixl1394_xfer_pkt_t;
232
233_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
234	ixl1394_xfer_pkt::ixl_buf._dmac_ll \
235        ixl1394_xfer_pkt::ixl_buf._dmac_la \
236        ixl1394_xfer_pkt::mem_bufp \
237        ixl1394_xfer_pkt::size))
238
239/*
240 * ixl1394_xfer_buf
241 * Specifies a buffer of multiple packets.
242 * Used with IXL1394_OP_SEND_BUF and IXL1394_OP_RECV_BUF.
243 */
244typedef struct ixl1394_xfer_buf {
245	ixl1394_command_t	*next_ixlp;
246	ixl1394_priv_t		compiler_privatep;
247	uint16_t		compiler_resv;
248	uint16_t		ixl_opcode;
249	uint16_t		size;		/* bytes in ixl_buf */
250	uint16_t		pkt_size;	/* bytes in each packet */
251	ixl1394_buf_t		ixl_buf;	/* ddi_dma bound address */
252	caddr_t			mem_bufp;	/* kernel (not bound) addrss */
253} ixl1394_xfer_buf_t;
254
255_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
256	ixl1394_xfer_buf::compiler_privatep \
257	ixl1394_xfer_buf::ixl_buf._dmac_ll \
258	ixl1394_xfer_buf::ixl_buf._dmac_la \
259	ixl1394_xfer_buf::mem_bufp \
260	ixl1394_xfer_buf::pkt_size \
261	ixl1394_xfer_buf::size))
262
263/*
264 * ixl1394_xmit_special
265 * Specifies how many cycles are to be skipped before the next packet
266 * is sent.  Specifies number of header only packets to be sent, next.
267 * Used with IXL1394_OP_SEND_HDR_ONLY and IXL1394_OP_SEND_NO_PKT.
268 */
269typedef struct ixl1394_xmit_special {
270	ixl1394_command_t	*next_ixlp;
271	ixl1394_priv_t		compiler_privatep;
272	uint16_t		compiler_resv;
273	uint16_t		ixl_opcode;
274	uint16_t		count;
275	uint16_t		resv;
276} ixl1394_xmit_special_t;
277
278/*
279 * ixl1394_callback
280 * Specifies a callback function and callback data.
281 * When the callback is invoked, it is passed the addr of this IXL
282 * command, which it can use to retrieve the arg it has stored in
283 * this struct. Used with IXL1394_OP_CALLBACK.
284 */
285typedef struct ixl1394_callback {
286	ixl1394_command_t   *next_ixlp;
287	ixl1394_priv_t	    compiler_privatep;
288	uint16_t	    compiler_resv;
289	uint16_t	    ixl_opcode;
290	void		    (*callback)(opaque_t, struct ixl1394_callback *);
291	opaque_t	    callback_arg;
292} ixl1394_callback_t;
293
294_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
295        ixl1394_callback::callback \
296	ixl1394_callback::callback_arg))
297
298/*
299 * ixl1394_label
300 * Specifies a label (location) which can be used as the target of a jump.
301 * Used with IXL1394_OP_LABEL.
302 */
303typedef struct ixl1394_label {
304	ixl1394_command_t	*next_ixlp;
305	ixl1394_priv_t		compiler_privatep;
306	uint16_t		compiler_resv;
307	uint16_t		ixl_opcode;
308} ixl1394_label_t;
309
310/*
311 * ixl1394_jump
312 * Specifies a label (location) which can then be used as the target of a jump.
313 * Used with IXL1394_OP_JUMP.
314 */
315typedef struct ixl1394_jump {
316	ixl1394_command_t	*next_ixlp;
317	ixl1394_priv_t		compiler_privatep;
318	uint16_t		compiler_resv;
319	uint16_t		ixl_opcode;
320	ixl1394_command_t	*label;
321} ixl1394_jump_t;
322
323_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
324	ixl1394_jump::label))
325
326/*
327 * ixl1394_set_tagsync
328 * Specifies the tag and sync bits used for the port.
329 * Used with IXL1394_OP_SET_TAGSYNC.
330 */
331typedef struct ixl1394_set_tagsync {
332	ixl1394_command_t	*next_ixlp;
333	ixl1394_priv_t		compiler_privatep;
334	uint16_t		compiler_resv;
335	uint16_t		ixl_opcode;
336	uint16_t		tag;
337	uint16_t		sync;
338} ixl1394_set_tagsync_t;
339
340_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
341	ixl1394_set_tagsync::sync \
342	ixl1394_set_tagsync::tag))
343
344/*
345 * ixl1394_set_skipmode
346 * Specifies the tag and sync bits used for the port.
347 * Used with IXL1394_OP_SET_SKIPMODE.
348 */
349typedef struct ixl1394_set_skipmode {
350	ixl1394_command_t	*next_ixlp;
351	ixl1394_priv_t		compiler_privatep;
352	uint16_t		compiler_resv;
353	uint16_t		ixl_opcode;
354	ixl1394_command_t 	*label;
355	ixl1394_skip_t		skipmode;
356} ixl1394_set_skipmode_t;
357
358_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
359	ixl1394_set_skipmode::compiler_privatep \
360	ixl1394_set_skipmode::label \
361	ixl1394_set_skipmode::skipmode))
362
363/*
364 * ixl1394_set_syncwait
365 * Specifies that next receive is to wait for sync before accepting input.
366 * Used with IXL1394_OP_SET_SYNCWAIT.
367 */
368typedef struct ixl1394_set_syncwait {
369	ixl1394_command_t	*next_ixlp;
370	ixl1394_priv_t		compiler_privatep;
371	uint16_t		compiler_resv;
372	uint16_t		ixl_opcode;
373} ixl1394_set_syncwait_t;
374
375/*
376 * ixl1394_store_timestamp
377 * Specifies that the timestamp value of the most recently sent
378 * packet be stored into the timestamp field of this ixl command.
379 * Used with IXL1394_OP_STORE_TIMESTAMP.
380 */
381typedef struct ixl1394_store_timestamp {
382	ixl1394_command_t	*next_ixlp;
383	ixl1394_priv_t		compiler_privatep;
384	uint16_t		compiler_resv;
385	uint16_t		ixl_opcode;
386	uint16_t		timestamp;
387	uint16_t		resv;
388} ixl1394_store_timestamp_t;
389
390_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", \
391	ixl1394_store_timestamp::timestamp))
392
393/*
394 * Macros for extracting isochronous packet header fields when receiving
395 * packets via IXL1394_OP_RECV_PKT_ST or IXL1394_OP_RECV_BUF with
396 * ID1394_RECV_HEADERS mode enabled.
397 * The argument to each macro is a quadlet of data.
398 * Prior to using the macro, target drivers first retrieve this quadlet from
399 * bound memory by using ddi_get32(9F).
400 */
401
402/*
403 * timestamp is the first quadlet in an IXL1394_OP_RECV_PKT_ST packet, and is
404 * the last quadlet (after the data payload) in an IXL1394_OP_RECV_BUF packet.
405 */
406#define	IXL1394_GET_IR_TIMESTAMP(PKT_QUADLET) ((PKT_QUADLET) & 0x0000FFFF)
407
408/*
409 * the following macros apply to the second quadlet in an
410 * IXL1394_OP_RECV_PKT_ST packet, and the first quadlet in an
411 * IXL1394_OP_RECV_BUF packet.
412 */
413#define	IXL1394_GET_IR_DATALEN(PKT_QUADLET) (((PKT_QUADLET) & 0xFFFF0000) >> 16)
414#define	IXL1394_GET_IR_TAG(PKT_QUADLET)	    (((PKT_QUADLET) & 0x0000C000) >> 14)
415#define	IXL1394_GET_IR_CHAN(PKT_QUADLET)    (((PKT_QUADLET) & 0x00003F00) >> 8)
416#define	IXL1394_GET_IR_SYNC(PKT_QUADLET)    ((PKT_QUADLET) & 0x0000000F)
417
418#ifdef __cplusplus
419}
420#endif
421
422#endif	/* _SYS_1394_IXL1394_H */
423