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