xref: /onnv-gate/usr/src/uts/common/sys/dcopy.h (revision 6707:c3bc7e4da11b)
1*6707Sbrutus /*
2*6707Sbrutus  * CDDL HEADER START
3*6707Sbrutus  *
4*6707Sbrutus  * The contents of this file are subject to the terms of the
5*6707Sbrutus  * Common Development and Distribution License (the "License").
6*6707Sbrutus  * You may not use this file except in compliance with the License.
7*6707Sbrutus  *
8*6707Sbrutus  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6707Sbrutus  * or http://www.opensolaris.org/os/licensing.
10*6707Sbrutus  * See the License for the specific language governing permissions
11*6707Sbrutus  * and limitations under the License.
12*6707Sbrutus  *
13*6707Sbrutus  * When distributing Covered Code, include this CDDL HEADER in each
14*6707Sbrutus  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6707Sbrutus  * If applicable, add the following below this CDDL HEADER, with the
16*6707Sbrutus  * fields enclosed by brackets "[]" replaced with your own identifying
17*6707Sbrutus  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6707Sbrutus  *
19*6707Sbrutus  * CDDL HEADER END
20*6707Sbrutus  */
21*6707Sbrutus 
22*6707Sbrutus /*
23*6707Sbrutus  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*6707Sbrutus  * Use is subject to license terms.
25*6707Sbrutus  */
26*6707Sbrutus 
27*6707Sbrutus #ifndef _SYS_DCOPY_H
28*6707Sbrutus #define	_SYS_DCOPY_H
29*6707Sbrutus 
30*6707Sbrutus #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*6707Sbrutus 
32*6707Sbrutus #ifdef __cplusplus
33*6707Sbrutus extern "C" {
34*6707Sbrutus #endif
35*6707Sbrutus 
36*6707Sbrutus #include <sys/types.h>
37*6707Sbrutus 
38*6707Sbrutus /*
39*6707Sbrutus  * *** This interface is for private use by the IP stack only ***
40*6707Sbrutus  */
41*6707Sbrutus 
42*6707Sbrutus /* Private dcopy/uioa interface for dcopy to enable/disable dcopy KAPI */
43*6707Sbrutus extern void uioa_dcopy_enable();
44*6707Sbrutus extern void uioa_dcopy_disable();
45*6707Sbrutus 
46*6707Sbrutus /* Function return status */
47*6707Sbrutus #define	DCOPY_FAILURE		(-1)
48*6707Sbrutus #define	DCOPY_SUCCESS		(0)
49*6707Sbrutus #define	DCOPY_NORESOURCES	(1) /* _alloc & _cmd_alloc, _cmd_post only */
50*6707Sbrutus #define	DCOPY_PENDING		(0x10) /* dcopy_poll(), dcopy_unregister() */
51*6707Sbrutus #define	DCOPY_COMPLETED		(0x20) /* dcopy_poll() only */
52*6707Sbrutus 
53*6707Sbrutus 
54*6707Sbrutus /* dq_version */
55*6707Sbrutus #define	DCOPY_QUERY_V0	0
56*6707Sbrutus 
57*6707Sbrutus typedef struct dcopy_query_s {
58*6707Sbrutus 	int		dq_version; /* DCOPY_QUERY_V0 */
59*6707Sbrutus 	uint_t		dq_num_channels; /* number of dma channels */
60*6707Sbrutus } dcopy_query_t;
61*6707Sbrutus 
62*6707Sbrutus /*
63*6707Sbrutus  * dcopy_query()
64*6707Sbrutus  *   query for the number of DMA engines usable in the system.
65*6707Sbrutus  */
66*6707Sbrutus void dcopy_query(dcopy_query_t *query);
67*6707Sbrutus 
68*6707Sbrutus 
69*6707Sbrutus typedef struct dcopy_channel_s *dcopy_handle_t;
70*6707Sbrutus 
71*6707Sbrutus /* dcopy_alloc() and dcopy_cmd_alloc() common flags */
72*6707Sbrutus #define	DCOPY_SLEEP	(0)
73*6707Sbrutus #define	DCOPY_NOSLEEP	(1 << 0)
74*6707Sbrutus 
75*6707Sbrutus /*
76*6707Sbrutus  * dcopy_alloc()
77*6707Sbrutus  *   Allocate a DMA channel which is used for posting DMA requests. Note: this
78*6707Sbrutus  *   does not give the caller exclusive access to the DMA engine. Commands
79*6707Sbrutus  *   posted to a channel will complete in order.
80*6707Sbrutus  *     flags - (DCOPY_SLEEP, DCOPY_NOSLEEP)
81*6707Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
82*6707Sbrutus  */
83*6707Sbrutus int dcopy_alloc(int flags, dcopy_handle_t *handle);
84*6707Sbrutus 
85*6707Sbrutus /*
86*6707Sbrutus  * dcopy_free()
87*6707Sbrutus  *   Free the DMA channel. The client can no longer use the handle to post or
88*6707Sbrutus  *   poll for status on posts which were previously done on this channel.
89*6707Sbrutus  */
90*6707Sbrutus void dcopy_free(dcopy_handle_t *handle);
91*6707Sbrutus 
92*6707Sbrutus /* dq_version */
93*6707Sbrutus #define	DCOPY_QUERY_CHANNEL_V0	0
94*6707Sbrutus 
95*6707Sbrutus /* Per DMA channel info */
96*6707Sbrutus typedef struct dcopy_query_channel_s {
97*6707Sbrutus 	int		qc_version; /* DCOPY_QUERY_CHANNEL_V0 */
98*6707Sbrutus 
99*6707Sbrutus 	/* Does DMA channel support DCA */
100*6707Sbrutus 	boolean_t	qc_dca_supported;
101*6707Sbrutus 
102*6707Sbrutus 	/* device id and device specific capabilities */
103*6707Sbrutus 	uint64_t	qc_id;
104*6707Sbrutus 	uint64_t	qc_capabilities;
105*6707Sbrutus 
106*6707Sbrutus 	/*
107*6707Sbrutus 	 * DMA channel size. This may not be the same as the number of posts
108*6707Sbrutus 	 * that the DMA channel can handle since a post may consume 1 or more
109*6707Sbrutus 	 * entries.
110*6707Sbrutus 	 */
111*6707Sbrutus 	uint64_t	qc_channel_size;
112*6707Sbrutus 
113*6707Sbrutus 	/* DMA channel number within the device. Not unique across devices */
114*6707Sbrutus 	uint64_t	qc_chan_num;
115*6707Sbrutus } dcopy_query_channel_t;
116*6707Sbrutus 
117*6707Sbrutus /*
118*6707Sbrutus  * dcopy_query_channel()
119*6707Sbrutus  *   query DMA engines capabilities
120*6707Sbrutus  */
121*6707Sbrutus void dcopy_query_channel(dcopy_handle_t handle, dcopy_query_channel_t *query);
122*6707Sbrutus 
123*6707Sbrutus 
124*6707Sbrutus /* dp_version */
125*6707Sbrutus #define	DCOPY_CMD_V0	0
126*6707Sbrutus 
127*6707Sbrutus /* dp_cmd */
128*6707Sbrutus #define	DCOPY_CMD_COPY	0x1
129*6707Sbrutus 
130*6707Sbrutus /* dp_flags */
131*6707Sbrutus /*
132*6707Sbrutus  * DCOPY_CMD_QUEUE
133*6707Sbrutus  *    Hint to queue up the post but don't notify the DMA engine. This can be
134*6707Sbrutus  *    used as an optimization when multiple posts are going to be queued up and
135*6707Sbrutus  *    you only want notify the DMA engine after the last post. Note, this does
136*6707Sbrutus  *    not mean the DMA engine won't process the request since it could notice
137*6707Sbrutus  *    it anyway.
138*6707Sbrutus  * DCOPY_CMD_NOSTAT
139*6707Sbrutus  *    Don't generate a status. If this flag is used, You cannot poll for
140*6707Sbrutus  *    completion status on this command. This can be a useful performance
141*6707Sbrutus  *    optimization if your posting multiple commands and just want to poll on
142*6707Sbrutus  *    the last command.
143*6707Sbrutus  * DCOPY_CMD_DCA
144*6707Sbrutus  *    If DCA is supported, direct this and all future command data (until the
145*6707Sbrutus  *    next command with DCOPY_POST_DCA set) to the processor specified in
146*6707Sbrutus  *    dp_dca_id. This flag is ignored if DCA is not supported.
147*6707Sbrutus  * DCOPY_CMD_INTR
148*6707Sbrutus  *    Generate an interrupt when command completes. This flag is required if
149*6707Sbrutus  *    the caller is going to call dcopy_cmd_poll(() with DCOPY_POLL_BLOCK set
150*6707Sbrutus  *    for this command.
151*6707Sbrutus  */
152*6707Sbrutus #define	DCOPY_CMD_NOFLAGS	(0)
153*6707Sbrutus #define	DCOPY_CMD_QUEUE		(1 << 0)
154*6707Sbrutus #define	DCOPY_CMD_NOSTAT	(1 << 1)
155*6707Sbrutus #define	DCOPY_CMD_DCA		(1 << 2)
156*6707Sbrutus #define	DCOPY_CMD_INTR		(1 << 3)
157*6707Sbrutus 
158*6707Sbrutus typedef struct dcopy_cmd_copy_s {
159*6707Sbrutus 	uint64_t	cc_source; /* Source physical address */
160*6707Sbrutus 	uint64_t	cc_dest; /* Destination physical address */
161*6707Sbrutus 	size_t		cc_size;
162*6707Sbrutus } dcopy_cmd_copy_t;
163*6707Sbrutus 
164*6707Sbrutus typedef union dcopy_cmd_u {
165*6707Sbrutus 	dcopy_cmd_copy_t	copy;
166*6707Sbrutus } dcopy_cmd_u_t;
167*6707Sbrutus 
168*6707Sbrutus typedef struct dcopy_cmd_priv_s *dcopy_cmd_priv_t;
169*6707Sbrutus 
170*6707Sbrutus struct dcopy_cmd_s {
171*6707Sbrutus 	uint_t			dp_version; /* DCOPY_CMD_V0 */
172*6707Sbrutus 	uint_t			dp_flags;
173*6707Sbrutus 	uint64_t		dp_cmd;
174*6707Sbrutus 	dcopy_cmd_u_t   	dp;
175*6707Sbrutus 	uint32_t		dp_dca_id;
176*6707Sbrutus 	dcopy_cmd_priv_t	dp_private;
177*6707Sbrutus };
178*6707Sbrutus typedef struct dcopy_cmd_s *dcopy_cmd_t;
179*6707Sbrutus 
180*6707Sbrutus 
181*6707Sbrutus /*
182*6707Sbrutus  * dcopy_cmd_alloc() specific flags
183*6707Sbrutus  *   DCOPY_ALLOC_LINK - when set, the caller passes in a previously alloced
184*6707Sbrutus  *     command in cmd. dcopy_cmd_alloc() will allocate a new command and
185*6707Sbrutus  *     link it to the old command. The caller can use this to build a
186*6707Sbrutus  *     chain of commands, keeping only the last cmd alloced. calling
187*6707Sbrutus  *     dcopy_cmd_free() with the last cmd alloced in the chain will free all of
188*6707Sbrutus  *     the commands in the chain. dcopy_cmd_post() and dcopy_cmd_poll() have
189*6707Sbrutus  *     no knowledge of a chain of commands.  It's only used for alloc/free.
190*6707Sbrutus  */
191*6707Sbrutus #define	DCOPY_ALLOC_LINK	(1 << 16)
192*6707Sbrutus 
193*6707Sbrutus /*
194*6707Sbrutus  * dcopy_cmd_alloc()
195*6707Sbrutus  *   allocate a command. A command can be re-used after it completes.
196*6707Sbrutus  *     flags - (DCOPY_SLEEP || DCOPY_NOSLEEP), DCOPY_ALLOC_LINK
197*6707Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
198*6707Sbrutus  */
199*6707Sbrutus int dcopy_cmd_alloc(dcopy_handle_t handle, int flags, dcopy_cmd_t *cmd);
200*6707Sbrutus 
201*6707Sbrutus /*
202*6707Sbrutus  * dcopy_cmd_free()
203*6707Sbrutus  *   free the command. This call cannot be called after dcopy_free().
204*6707Sbrutus  */
205*6707Sbrutus void dcopy_cmd_free(dcopy_cmd_t *cmd);
206*6707Sbrutus 
207*6707Sbrutus /*
208*6707Sbrutus  * dcopy_cmd_post()
209*6707Sbrutus  *   post a command (allocated from dcopy_cmd_alloc()) to the DMA channel
210*6707Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
211*6707Sbrutus  */
212*6707Sbrutus int dcopy_cmd_post(dcopy_cmd_t cmd);
213*6707Sbrutus 
214*6707Sbrutus /* dcopy_cmd_poll() flags */
215*6707Sbrutus #define	DCOPY_POLL_NOFLAGS	(0)
216*6707Sbrutus #define	DCOPY_POLL_BLOCK	(1 << 0)
217*6707Sbrutus 
218*6707Sbrutus /*
219*6707Sbrutus  * dcopy_cmd_poll()
220*6707Sbrutus  *   poll on completion status of a previous post. This call cannot be called
221*6707Sbrutus  *   after dcopy_free().
222*6707Sbrutus  *
223*6707Sbrutus  *   if flags == DCOPY_POLL_NOFLAGS, return status can be DCOPY_FAILURE,
224*6707Sbrutus  *   DCOPY_PENDING, or DCOPY_COMPLETED.
225*6707Sbrutus  *
226*6707Sbrutus  *   if flags & DCOPY_POLL_BLOCK, return status can be DCOPY_FAILURE or
227*6707Sbrutus  *   DCOPY_COMPLETED. DCOPY_POLL_BLOCK can only be set in base context.
228*6707Sbrutus  *
229*6707Sbrutus  *   The command cannot be re-used or freed until the command has completed
230*6707Sbrutus  *   (e.g. DCOPY_FAILURE or DCOPY_COMPLETED).
231*6707Sbrutus  */
232*6707Sbrutus int dcopy_cmd_poll(dcopy_cmd_t cmd, int flags);
233*6707Sbrutus 
234*6707Sbrutus 
235*6707Sbrutus #ifdef __cplusplus
236*6707Sbrutus }
237*6707Sbrutus #endif
238*6707Sbrutus 
239*6707Sbrutus #endif /* _SYS_DCOPY_H */
240