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