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