xref: /onnv-gate/usr/src/uts/common/sys/dcopy.h (revision 9638:8e20e33b68dc)
16707Sbrutus /*
26707Sbrutus  * CDDL HEADER START
36707Sbrutus  *
46707Sbrutus  * The contents of this file are subject to the terms of the
56707Sbrutus  * Common Development and Distribution License (the "License").
66707Sbrutus  * You may not use this file except in compliance with the License.
76707Sbrutus  *
86707Sbrutus  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96707Sbrutus  * or http://www.opensolaris.org/os/licensing.
106707Sbrutus  * See the License for the specific language governing permissions
116707Sbrutus  * and limitations under the License.
126707Sbrutus  *
136707Sbrutus  * When distributing Covered Code, include this CDDL HEADER in each
146707Sbrutus  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156707Sbrutus  * If applicable, add the following below this CDDL HEADER, with the
166707Sbrutus  * fields enclosed by brackets "[]" replaced with your own identifying
176707Sbrutus  * information: Portions Copyright [yyyy] [name of copyright owner]
186707Sbrutus  *
196707Sbrutus  * CDDL HEADER END
206707Sbrutus  */
216707Sbrutus 
226707Sbrutus /*
23*9638SRandy.Fishel@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
246707Sbrutus  * Use is subject to license terms.
256707Sbrutus  */
266707Sbrutus 
276707Sbrutus #ifndef _SYS_DCOPY_H
286707Sbrutus #define	_SYS_DCOPY_H
296707Sbrutus 
306707Sbrutus #ifdef __cplusplus
316707Sbrutus extern "C" {
326707Sbrutus #endif
336707Sbrutus 
346707Sbrutus #include <sys/types.h>
356707Sbrutus 
366707Sbrutus /*
376707Sbrutus  * *** This interface is for private use by the IP stack only ***
386707Sbrutus  */
396707Sbrutus 
406707Sbrutus /* Private dcopy/uioa interface for dcopy to enable/disable dcopy KAPI */
416707Sbrutus extern void uioa_dcopy_enable();
426707Sbrutus extern void uioa_dcopy_disable();
436707Sbrutus 
446707Sbrutus /* Function return status */
456707Sbrutus #define	DCOPY_FAILURE		(-1)
466707Sbrutus #define	DCOPY_SUCCESS		(0)
476707Sbrutus #define	DCOPY_NORESOURCES	(1) /* _alloc & _cmd_alloc, _cmd_post only */
486707Sbrutus #define	DCOPY_PENDING		(0x10) /* dcopy_poll(), dcopy_unregister() */
496707Sbrutus #define	DCOPY_COMPLETED		(0x20) /* dcopy_poll() only */
506707Sbrutus 
516707Sbrutus 
526707Sbrutus /* dq_version */
536707Sbrutus #define	DCOPY_QUERY_V0	0
546707Sbrutus 
556707Sbrutus typedef struct dcopy_query_s {
566707Sbrutus 	int		dq_version; /* DCOPY_QUERY_V0 */
576707Sbrutus 	uint_t		dq_num_channels; /* number of dma channels */
586707Sbrutus } dcopy_query_t;
596707Sbrutus 
606707Sbrutus /*
616707Sbrutus  * dcopy_query()
626707Sbrutus  *   query for the number of DMA engines usable in the system.
636707Sbrutus  */
646707Sbrutus void dcopy_query(dcopy_query_t *query);
656707Sbrutus 
666707Sbrutus 
676707Sbrutus typedef struct dcopy_channel_s *dcopy_handle_t;
686707Sbrutus 
696707Sbrutus /* dcopy_alloc() and dcopy_cmd_alloc() common flags */
706707Sbrutus #define	DCOPY_SLEEP	(0)
716707Sbrutus #define	DCOPY_NOSLEEP	(1 << 0)
726707Sbrutus 
736707Sbrutus /*
746707Sbrutus  * dcopy_alloc()
756707Sbrutus  *   Allocate a DMA channel which is used for posting DMA requests. Note: this
766707Sbrutus  *   does not give the caller exclusive access to the DMA engine. Commands
776707Sbrutus  *   posted to a channel will complete in order.
786707Sbrutus  *     flags - (DCOPY_SLEEP, DCOPY_NOSLEEP)
796707Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
806707Sbrutus  */
816707Sbrutus int dcopy_alloc(int flags, dcopy_handle_t *handle);
826707Sbrutus 
836707Sbrutus /*
846707Sbrutus  * dcopy_free()
856707Sbrutus  *   Free the DMA channel. The client can no longer use the handle to post or
866707Sbrutus  *   poll for status on posts which were previously done on this channel.
876707Sbrutus  */
886707Sbrutus void dcopy_free(dcopy_handle_t *handle);
896707Sbrutus 
906707Sbrutus /* dq_version */
916707Sbrutus #define	DCOPY_QUERY_CHANNEL_V0	0
926707Sbrutus 
936707Sbrutus /* Per DMA channel info */
946707Sbrutus typedef struct dcopy_query_channel_s {
956707Sbrutus 	int		qc_version; /* DCOPY_QUERY_CHANNEL_V0 */
966707Sbrutus 
976707Sbrutus 	/* Does DMA channel support DCA */
986707Sbrutus 	boolean_t	qc_dca_supported;
996707Sbrutus 
1006707Sbrutus 	/* device id and device specific capabilities */
1016707Sbrutus 	uint64_t	qc_id;
1026707Sbrutus 	uint64_t	qc_capabilities;
1036707Sbrutus 
1046707Sbrutus 	/*
1056707Sbrutus 	 * DMA channel size. This may not be the same as the number of posts
1066707Sbrutus 	 * that the DMA channel can handle since a post may consume 1 or more
1076707Sbrutus 	 * entries.
1086707Sbrutus 	 */
1096707Sbrutus 	uint64_t	qc_channel_size;
1106707Sbrutus 
1116707Sbrutus 	/* DMA channel number within the device. Not unique across devices */
1126707Sbrutus 	uint64_t	qc_chan_num;
1136707Sbrutus } dcopy_query_channel_t;
1146707Sbrutus 
1156707Sbrutus /*
1166707Sbrutus  * dcopy_query_channel()
1176707Sbrutus  *   query DMA engines capabilities
1186707Sbrutus  */
1196707Sbrutus void dcopy_query_channel(dcopy_handle_t handle, dcopy_query_channel_t *query);
1206707Sbrutus 
1216707Sbrutus 
1226707Sbrutus /* dp_version */
1236707Sbrutus #define	DCOPY_CMD_V0	0
1246707Sbrutus 
1256707Sbrutus /* dp_cmd */
1266707Sbrutus #define	DCOPY_CMD_COPY	0x1
1276707Sbrutus 
1286707Sbrutus /* dp_flags */
1296707Sbrutus /*
1306707Sbrutus  * DCOPY_CMD_QUEUE
1316707Sbrutus  *    Hint to queue up the post but don't notify the DMA engine. This can be
1326707Sbrutus  *    used as an optimization when multiple posts are going to be queued up and
1336707Sbrutus  *    you only want notify the DMA engine after the last post. Note, this does
1346707Sbrutus  *    not mean the DMA engine won't process the request since it could notice
1356707Sbrutus  *    it anyway.
1366707Sbrutus  * DCOPY_CMD_NOSTAT
1376707Sbrutus  *    Don't generate a status. If this flag is used, You cannot poll for
1386707Sbrutus  *    completion status on this command. This can be a useful performance
1396707Sbrutus  *    optimization if your posting multiple commands and just want to poll on
1406707Sbrutus  *    the last command.
1416707Sbrutus  * DCOPY_CMD_DCA
1426707Sbrutus  *    If DCA is supported, direct this and all future command data (until the
1436707Sbrutus  *    next command with DCOPY_POST_DCA set) to the processor specified in
1446707Sbrutus  *    dp_dca_id. This flag is ignored if DCA is not supported.
1456707Sbrutus  * DCOPY_CMD_INTR
1466707Sbrutus  *    Generate an interrupt when command completes. This flag is required if
1476707Sbrutus  *    the caller is going to call dcopy_cmd_poll(() with DCOPY_POLL_BLOCK set
1486707Sbrutus  *    for this command.
149*9638SRandy.Fishel@Sun.COM  * DCOPY_CMD_NOWAIT
150*9638SRandy.Fishel@Sun.COM  *    Return error instead of busy waiting if resource is not available.
151*9638SRandy.Fishel@Sun.COM  * DCOPY_CMD_NOSRCSNP
152*9638SRandy.Fishel@Sun.COM  *    Disable source cache snooping.
153*9638SRandy.Fishel@Sun.COM  * DCOPY_CMD_NODSTSNP
154*9638SRandy.Fishel@Sun.COM  *    Disable destination cache snooping.
155*9638SRandy.Fishel@Sun.COM  * DCOPY_CMD_LOOP
156*9638SRandy.Fishel@Sun.COM  *    For CBv1, generate a loop descriptor list, used to support FIPE driver.
157*9638SRandy.Fishel@Sun.COM  * DCOPY_CMD_SYNC
158*9638SRandy.Fishel@Sun.COM  *    Reserved for internal use.
1596707Sbrutus  */
1606707Sbrutus #define	DCOPY_CMD_NOFLAGS	(0)
1616707Sbrutus #define	DCOPY_CMD_QUEUE		(1 << 0)
1626707Sbrutus #define	DCOPY_CMD_NOSTAT	(1 << 1)
1636707Sbrutus #define	DCOPY_CMD_DCA		(1 << 2)
1646707Sbrutus #define	DCOPY_CMD_INTR		(1 << 3)
165*9638SRandy.Fishel@Sun.COM #define	DCOPY_CMD_NOWAIT	(1 << 4)
166*9638SRandy.Fishel@Sun.COM #define	DCOPY_CMD_NOSRCSNP	(1 << 5)
167*9638SRandy.Fishel@Sun.COM #define	DCOPY_CMD_NODSTSNP	(1 << 6)
168*9638SRandy.Fishel@Sun.COM #define	DCOPY_CMD_LOOP		(1 << 7)
169*9638SRandy.Fishel@Sun.COM #define	DCOPY_CMD_SYNC		(1 << 30)
1706707Sbrutus 
1716707Sbrutus typedef struct dcopy_cmd_copy_s {
1726707Sbrutus 	uint64_t	cc_source; /* Source physical address */
1736707Sbrutus 	uint64_t	cc_dest; /* Destination physical address */
1746707Sbrutus 	size_t		cc_size;
1756707Sbrutus } dcopy_cmd_copy_t;
1766707Sbrutus 
1776707Sbrutus typedef union dcopy_cmd_u {
1786707Sbrutus 	dcopy_cmd_copy_t	copy;
1796707Sbrutus } dcopy_cmd_u_t;
1806707Sbrutus 
1816707Sbrutus typedef struct dcopy_cmd_priv_s *dcopy_cmd_priv_t;
1826707Sbrutus 
1836707Sbrutus struct dcopy_cmd_s {
1846707Sbrutus 	uint_t			dp_version; /* DCOPY_CMD_V0 */
1856707Sbrutus 	uint_t			dp_flags;
1866707Sbrutus 	uint64_t		dp_cmd;
1876707Sbrutus 	dcopy_cmd_u_t   	dp;
1886707Sbrutus 	uint32_t		dp_dca_id;
1896707Sbrutus 	dcopy_cmd_priv_t	dp_private;
1906707Sbrutus };
1916707Sbrutus typedef struct dcopy_cmd_s *dcopy_cmd_t;
1926707Sbrutus 
1936707Sbrutus 
1946707Sbrutus /*
1956707Sbrutus  * dcopy_cmd_alloc() specific flags
1966707Sbrutus  *   DCOPY_ALLOC_LINK - when set, the caller passes in a previously alloced
1976707Sbrutus  *     command in cmd. dcopy_cmd_alloc() will allocate a new command and
1986707Sbrutus  *     link it to the old command. The caller can use this to build a
1996707Sbrutus  *     chain of commands, keeping only the last cmd alloced. calling
2006707Sbrutus  *     dcopy_cmd_free() with the last cmd alloced in the chain will free all of
2016707Sbrutus  *     the commands in the chain. dcopy_cmd_post() and dcopy_cmd_poll() have
2026707Sbrutus  *     no knowledge of a chain of commands.  It's only used for alloc/free.
2036707Sbrutus  */
2046707Sbrutus #define	DCOPY_ALLOC_LINK	(1 << 16)
2056707Sbrutus 
2066707Sbrutus /*
2076707Sbrutus  * dcopy_cmd_alloc()
2086707Sbrutus  *   allocate a command. A command can be re-used after it completes.
2096707Sbrutus  *     flags - (DCOPY_SLEEP || DCOPY_NOSLEEP), DCOPY_ALLOC_LINK
2106707Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
2116707Sbrutus  */
2126707Sbrutus int dcopy_cmd_alloc(dcopy_handle_t handle, int flags, dcopy_cmd_t *cmd);
2136707Sbrutus 
2146707Sbrutus /*
2156707Sbrutus  * dcopy_cmd_free()
2166707Sbrutus  *   free the command. This call cannot be called after dcopy_free().
2176707Sbrutus  */
2186707Sbrutus void dcopy_cmd_free(dcopy_cmd_t *cmd);
2196707Sbrutus 
2206707Sbrutus /*
2216707Sbrutus  * dcopy_cmd_post()
2226707Sbrutus  *   post a command (allocated from dcopy_cmd_alloc()) to the DMA channel
2236707Sbrutus  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
2246707Sbrutus  */
2256707Sbrutus int dcopy_cmd_post(dcopy_cmd_t cmd);
2266707Sbrutus 
2276707Sbrutus /* dcopy_cmd_poll() flags */
2286707Sbrutus #define	DCOPY_POLL_NOFLAGS	(0)
2296707Sbrutus #define	DCOPY_POLL_BLOCK	(1 << 0)
2306707Sbrutus 
2316707Sbrutus /*
2326707Sbrutus  * dcopy_cmd_poll()
2336707Sbrutus  *   poll on completion status of a previous post. This call cannot be called
2346707Sbrutus  *   after dcopy_free().
2356707Sbrutus  *
2366707Sbrutus  *   if flags == DCOPY_POLL_NOFLAGS, return status can be DCOPY_FAILURE,
2376707Sbrutus  *   DCOPY_PENDING, or DCOPY_COMPLETED.
2386707Sbrutus  *
2396707Sbrutus  *   if flags & DCOPY_POLL_BLOCK, return status can be DCOPY_FAILURE or
2406707Sbrutus  *   DCOPY_COMPLETED. DCOPY_POLL_BLOCK can only be set in base context.
2416707Sbrutus  *
2426707Sbrutus  *   The command cannot be re-used or freed until the command has completed
2436707Sbrutus  *   (e.g. DCOPY_FAILURE or DCOPY_COMPLETED).
2446707Sbrutus  */
2456707Sbrutus int dcopy_cmd_poll(dcopy_cmd_t cmd, int flags);
2466707Sbrutus 
2476707Sbrutus 
2486707Sbrutus #ifdef __cplusplus
2496707Sbrutus }
2506707Sbrutus #endif
2516707Sbrutus 
2526707Sbrutus #endif /* _SYS_DCOPY_H */
253