xref: /illumos-gate/usr/src/uts/common/sys/1394/ixl1394.h (revision 7c478bd9)
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
40 extern "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 */
168 typedef struct ixl_priv_handle	*ixl1394_priv_t;
169 
170 /* IXL1394_OP_SET_SKIPMODE values (used only with isoch transmit) */
171 typedef 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 */
183 typedef 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  */
200 typedef 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  */
222 typedef 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  */
244 typedef 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  */
269 typedef 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  */
285 typedef 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  */
303 typedef 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  */
315 typedef 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  */
331 typedef 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  */
349 typedef 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  */
368 typedef 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  */
381 typedef 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