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 1999-2002 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _SYS_1394_ADAPTERS_HCI1394_IXL_H
28#define	_SYS_1394_ADAPTERS_HCI1394_IXL_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32/*
33 * hci1394_ixl.h
34 *    Structures and defines for IXL processing.
35 *	1. Structures tracking per-command state [created during compilation
36 *	    and stored in each command's compiler_privatep].
37 *	2. Structures used for state tracking during IXL program compilation.
38 *	3. Structures used during IXL dynamic update for assessment and the
39 *	    performing the update itself.
40 */
41
42#ifdef	__cplusplus
43extern "C" {
44#endif
45
46#include <sys/note.h>
47
48#include <sys/1394/adapters/hci1394_def.h>
49#include <sys/1394/adapters/hci1394_isoch.h>
50
51/*
52 * function return codes from hci1394_ixl_dma_sync()
53 */
54#define	HCI1394_IXL_INTR_NOERROR    (0) /* no error */
55#define	HCI1394_IXL_INTR_INUPDATE   (1) /* update active at intr entry */
56					/* (info only, not err) */
57#define	HCI1394_IXL_INTR_DMASTOP    (2) /* encountered end of dma or stopped */
58					/* (might be info only) */
59#define	HCI1394_IXL_INTR_DMALOST   (-1) /* dma location indeterminate (lost) */
60#define	HCI1394_IXL_INTR_NOADV	   (-2) /* dma non-advance retries exhausted */
61					/* (stuck or lost) */
62/* fatal internal errors from hci1394_ixl_dma_sync() */
63#define	HCI1394_IXL_INTR_ININTR    (-3) /* interrupt active at intrrupt entry */
64#define	HCI1394_IXL_INTR_INCALL    (-4) /* callback active at entry */
65#define	HCI1394_IXL_INTR_STOP	   (-5) /* context is being stopped */
66
67/*
68 * maximum number of jump IXL commands permitted between two data transfer
69 * commands.  This allows for several label and jump combinations to exist, but
70 * also is used to detect when the label/jump complexity probably indicates
71 * an infinite loop without any transfers.
72 */
73#define	HCI1394_IXL_MAX_SEQ_JUMPS   10
74
75/*
76 * xfer control structures - for execution and update control of compiled
77 * ixl program.
78 *
79 * For pkt, buf and special xfer start ixl commands, address
80 * of allocated xfer_ctl struct is set into ixl compiler_privatep.
81 *
82 * For pkt xfer non-start ixl commands, address of pkt xfer start ixl
83 * command is set into compiler_privatep and the index [1-n] of
84 * this non-start pkt xfer ixl command to its related component in the
85 * generated descriptor block is set into compiler_resv.
86 *
87 * The xfer_ctl_dma struct array is needed because allocation of subsequent
88 * descriptor blocks may be from different memory pages (i.e. not contiguous)
89 * and thus, during update processing, subsequent descriptor block addrs
90 * can't be calculated (e.g. change of buf addr or size or modification to
91 * set tag&sync, setskipmode or jump cmds).
92 */
93
94#define	XCTL_LABELLED 1	/* flag: ixl xfer cmd initiated by ixl label cmd  */
95
96typedef struct hci1394_xfer_ctl_dma {
97	/*
98	 * dma descriptor block's bound addr (with "Z" bits set); is used to
99	 * fill jump/skip addrs of previous dma descriptor block (previous on
100	 * exec path, not link path); Note:("Z" bits)*16 is size of this
101	 * descriptor block; individual component's format depends on IXL cmd
102	 * type;
103	 */
104	uint32_t dma_bound;
105
106	/*
107	 * kernel virtual (unbound) addr of last component of allocated
108	 * descriptor block; start addr of descriptor block can be calculated
109	 * by adding size of a descriptor block component(16) and subtracting
110	 * ("Z" bits)*16;  Note: if ixl cmd is xmit_hdr_only, must add 2*desc
111	 * block component(32), instead;
112	 * used to determine current location during exec by examining/clearing
113	 *    the status/timestamp value;
114	 * used to obtain value for store timestamp cmd; used to set new
115	 *    jump/skip addr on update calls;
116	 * used to set new tag and sync on update calls;
117	 */
118	caddr_t dma_descp;
119
120	/*
121	 * pointer to the hci1394_buf_info_t structure corresponding to the
122	 * mapped DMA memory into which this descriptor was written.  Contains
123	 * the DMA handles necessary for ddi_dma_sync() and ddi_put32/get32()
124	 * calls.
125	 */
126	hci1394_buf_info_t	*dma_buf;
127
128} hci1394_xfer_ctl_dma_t;
129
130
131typedef struct hci1394_xfer_ctl {
132	struct hci1394_xfer_ctl	*ctl_nextp; /* next ixl xfer_ctl struct */
133	ixl1394_command_t	*execp;	/* next ixlxfer cmd (along exec path) */
134	ixl1394_set_skipmode_t	*skipmodep; /* associated skip cmd. if any */
135	uint16_t		ctl_flags;  /* xctl flags defined above */
136	uint16_t		cnt;	/* dma descriptor blocks alloc count */
137					/* (for pkt=1) */
138	hci1394_xfer_ctl_dma_t	dma[1];	/* addrs of descriptor blocks, cnt of */
139					/* these are allocated */
140} hci1394_xfer_ctl_t;
141
142_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", hci1394_xfer_ctl))
143
144/*
145 * IXL Compiler temporary working variables for building IXL context program.
146 * (i.e. converting IXL program to a list of hci descriptor blocks)
147 */
148typedef struct hci1394_comp_ixl_vars_s {
149	/* COMMON RECV/XMIT COMPILE VALUES */
150	hci1394_state_t		*soft_statep;	/* driver state */
151	hci1394_iso_ctxt_t	*ctxtp;		/* current context */
152	hci1394_xfer_ctl_t	*xcs_firstp;	/* 1st alloc xfer_ctl_t struc */
153	hci1394_xfer_ctl_t	*xcs_currentp; /* last alloc xfer_ctl_t struc */
154
155	hci1394_idma_desc_mem_t *dma_firstp;	/* 1st alloc descriptor mem */
156	hci1394_idma_desc_mem_t *dma_currentp;	/* cur dma descriptor mem */
157
158	int dma_bld_error;			/* compilation error code */
159	uint_t ixl_io_mode;			/* I/O mode: 0=recv,1=xmit */
160
161	ixl1394_command_t *ixl_cur_cmdp;	/* processing current ixl cmd */
162	ixl1394_command_t *ixl_cur_xfer_stp;	/* currently buildng xfer cmd */
163	ixl1394_command_t *ixl_cur_labelp;	/* set if xfer inited by labl */
164
165	uint16_t	ixl_xfer_st_cnt; /* # of xfer start ixl cmds built */
166
167	uint_t		xfer_state;	/* none, pkt, buf, skip, hdronly */
168	uint_t		xfer_hci_flush;	/* updateable - xfer, jump, set */
169
170	uint32_t	xfer_pktlen;
171	uint32_t	xfer_bufp[HCI1394_DESC_MAX_Z];
172	uint16_t	xfer_bufcnt;
173	uint16_t	xfer_size[HCI1394_DESC_MAX_Z];
174
175	uint16_t	descriptors;
176	uint16_t	reserved;
177	hci1394_desc_t	descriptor_block[HCI1394_DESC_MAX_Z];
178
179	/* START RECV ONLY SECTION */
180	uint16_t	ixl_setsyncwait_cnt;
181	/* END RECV ONLY SECTION */
182
183	/* START XMIT ONLY SECTION */
184	ixl1394_set_tagsync_t	*ixl_settagsync_cmdp;
185	ixl1394_set_skipmode_t	*ixl_setskipmode_cmdp;
186
187	uint16_t		default_tag;
188	uint16_t		default_sync;
189	uint16_t		default_skipmode;   /* next, self, stop, jump */
190	uint16_t		skipmode;	    /* next, self, stop, jump */
191	ixl1394_command_t	*default_skiplabelp;
192	ixl1394_command_t	*default_skipxferp;
193	ixl1394_command_t	*skiplabelp;
194	ixl1394_command_t	*skipxferp;
195
196	uint32_t		xmit_pkthdr1;
197	uint32_t		xmit_pkthdr2;
198	uint32_t		storevalue_bufp;
199	uint32_t		storevalue_data;
200	/* END XMIT ONLY SECTION */
201} hci1394_comp_ixl_vars_t;
202
203_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", hci1394_comp_ixl_vars_s))
204
205/*
206 * hci1394_comp_ixl_vars.xfer_hci_flush - xfer descriptor block build hci
207 * flush evaluation flags
208 */
209#define	UPDATEABLE_XFER	0x01	/* current xfer command is updateable */
210#define	UPDATEABLE_JUMP	0x02	/* cur xfer is finalized by updateable jump */
211#define	UPDATEABLE_SET	0x04	/* current xfer has associated updateable set */
212#define	INITIATING_LBL  0x08	/* current xfer is initiated by a label cmd */
213
214/* hci1394_comp_ixl_vars.xfer_state - xfer descriptr block build state values */
215#define	XFER_NONE	0	/* build inactive */
216#define	XFER_PKT	1	/* building xfer packet descriptor block */
217#define	XFER_BUF	2	/* building xfer buffer descriptor blocks */
218#define	XMIT_NOPKT	3	/* building skip cycle xmit descriptor block */
219#define	XMIT_HDRONLY	4	/* building header only xmit descriptor block */
220
221/*
222 * IXL Dynamic Update  temporary working variables.
223 * (used when assessing feasibility of an update based on where the hardware
224 * is, and for performing the actual update.)
225 */
226#define	IXL_MAX_LOCN	4		/* extent of location array */
227
228typedef struct hci1394_upd_locn_info {
229	ixl1394_command_t *ixlp;
230	uint_t ixldepth;
231} hci1394_upd_locn_info_t;
232
233typedef struct hci1394_ixl_update_vars {
234
235	hci1394_state_t	*soft_statep;	/* driver state struct */
236	hci1394_iso_ctxt_t *ctxtp;	/* current iso context */
237	ixl1394_command_t *ixlnewp;	/* ixl cmd containing new values */
238	ixl1394_command_t *ixloldp;	/* cmd to be updated with new vals */
239
240	ixl1394_command_t *ixlxferp;	/* xfer cmd which is real targ of upd */
241	ixl1394_command_t *skipxferp;	/* xfer cmd if mode is skip to label */
242
243	/* currently exec xfer and MAX_LOCN-1 xfers following */
244	hci1394_upd_locn_info_t locn_info[IXL_MAX_LOCN];
245
246	uint_t	    ixldepth;	/* xferp depth at which to start upd */
247	uint_t	    skipmode; 	/* set skip mode mode value */
248	uint_t	    pkthdr1;	/* new pkt header 1 if tag or sync update */
249	uint_t	    pkthdr2;	/* new pkt hdr 2 if send xfer size change */
250	uint32_t    skipaddr;	/* bound skip destaddr (0=not skip to labl) */
251	uint32_t    jumpaddr;	/* bound jump destaddr if jump update (w/Z) */
252	uint32_t    bufaddr;	/* new buf addr if xfer buffr addr change */
253	uint32_t    bufsize;	/* new buf size if xfer buffr size change */
254	uint32_t    hcihdr;	/* new hci descriptor hdr field (cmd,int,cnt) */
255	uint32_t    hcistatus;	/* new hci descrptr stat field (rescount) */
256	int32_t	    hci_offset;	/* offset from xfer_ctl dma_descp to */
257				/* hci changing */
258	int	    hdr_offset; /* offset from xfer_ctl dma_descp to */
259				/* pkthdrs hci */
260	int	    upd_status; /* update completion return status value */
261
262	uint_t	    risklevel;	/* caller risk override spec (unimplemented) */
263	uint16_t    ixl_opcode; /* ixl update command code */
264	uint16_t    ixlcount;	/* ixlxferp # of dma cmds to update */
265} hci1394_ixl_update_vars_t;
266
267_NOTE(SCHEME_PROTECTS_DATA("Single thread modifies", hci1394_ixl_update_vars))
268
269int hci1394_compile_ixl(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
270    ixl1394_command_t *ixlp, int *resultp);
271int hci1394_ixl_update(hci1394_state_t *soft_statep, hci1394_iso_ctxt_t *ctxtp,
272    ixl1394_command_t *ixlnewp, ixl1394_command_t *ixloldp, uint_t riskoverride,
273    int *resultp);
274void hci1394_ixl_interrupt(hci1394_state_t *soft_statep,
275    hci1394_iso_ctxt_t *ctxtp, boolean_t in_stop);
276int hci1394_ixl_dma_sync(hci1394_state_t *soft_statep,
277    hci1394_iso_ctxt_t *ctxtp);
278int hci1394_ixl_set_start(hci1394_iso_ctxt_t *ctxtp, ixl1394_command_t *ixlstp);
279void hci1394_ixl_reset_status(hci1394_iso_ctxt_t *ctxtp);
280int hci1394_ixl_check_status(hci1394_xfer_ctl_dma_t *dma, uint16_t ixlopcode,
281    uint16_t *timestamp, boolean_t do_status_reset);
282int hci1394_ixl_find_next_exec_xfer(ixl1394_command_t *ixl_start,
283    uint_t *callback_cnt, ixl1394_command_t **next_exec_ixlpp);
284void hci1394_ixl_cleanup(hci1394_state_t *soft_statep,
285    hci1394_iso_ctxt_t *ctxtp);
286
287#ifdef	__cplusplus
288}
289#endif
290
291#endif	/* _SYS_1394_ADAPTERS_HCI1394_IXL_H */
292