1*d14abf15SRobert Mustacchi /*******************************************************************************
2*d14abf15SRobert Mustacchi  *
3*d14abf15SRobert Mustacchi  * CDDL HEADER START
4*d14abf15SRobert Mustacchi  *
5*d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
6*d14abf15SRobert Mustacchi  * Common Development and Distribution License (the "License").
7*d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
8*d14abf15SRobert Mustacchi  *
9*d14abf15SRobert Mustacchi  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*d14abf15SRobert Mustacchi  * or http://www.opensolaris.org/os/licensing.
11*d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
12*d14abf15SRobert Mustacchi  * and limitations under the License.
13*d14abf15SRobert Mustacchi  *
14*d14abf15SRobert Mustacchi  * When distributing Covered Code, include this CDDL HEADER in each
15*d14abf15SRobert Mustacchi  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*d14abf15SRobert Mustacchi  * If applicable, add the following below this CDDL HEADER, with the
17*d14abf15SRobert Mustacchi  * fields enclosed by brackets "[]" replaced with your own identifying
18*d14abf15SRobert Mustacchi  * information: Portions Copyright [yyyy] [name of copyright owner]
19*d14abf15SRobert Mustacchi  *
20*d14abf15SRobert Mustacchi  * CDDL HEADER END
21*d14abf15SRobert Mustacchi  *
22*d14abf15SRobert Mustacchi  * Copyright 2014 QLogic Corporation
23*d14abf15SRobert Mustacchi  * The contents of this file are subject to the terms of the
24*d14abf15SRobert Mustacchi  * QLogic End User License (the "License").
25*d14abf15SRobert Mustacchi  * You may not use this file except in compliance with the License.
26*d14abf15SRobert Mustacchi  *
27*d14abf15SRobert Mustacchi  * You can obtain a copy of the License at
28*d14abf15SRobert Mustacchi  * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/
29*d14abf15SRobert Mustacchi  * QLogic_End_User_Software_License.txt
30*d14abf15SRobert Mustacchi  * See the License for the specific language governing permissions
31*d14abf15SRobert Mustacchi  * and limitations under the License.
32*d14abf15SRobert Mustacchi  *
33*d14abf15SRobert Mustacchi  * Module Description:
34*d14abf15SRobert Mustacchi  *
35*d14abf15SRobert Mustacchi  *
36*d14abf15SRobert Mustacchi  * History:
37*d14abf15SRobert Mustacchi  *    02/05/07 Alon Elhanani    Inception.
38*d14abf15SRobert Mustacchi  ******************************************************************************/
39*d14abf15SRobert Mustacchi 
40*d14abf15SRobert Mustacchi /**@file hw_dmae.h
41*d14abf15SRobert Mustacchi  *
42*d14abf15SRobert Mustacchi  * A module encapsulating the DMAE HW block.
43*d14abf15SRobert Mustacchi  *
44*d14abf15SRobert Mustacchi  * Use cases for this module include:
45*d14abf15SRobert Mustacchi  *
46*d14abf15SRobert Mustacchi  * - 'Single-block' DMA operations
47*d14abf15SRobert Mustacchi  *   Single-block DMA operations are composed of a single HW
48*d14abf15SRobert Mustacchi  *   command that contains a GRC/PCI source, a GRC/PCI
49*d14abf15SRobert Mustacchi  *   destination and length. Single-block DMA operations are
50*d14abf15SRobert Mustacchi  *   locked from before writing the command to the HW registers,
51*d14abf15SRobert Mustacchi  *   until after the DMAE writes the completion word to the
52*d14abf15SRobert Mustacchi  *   appropriate location in host memory. Single-block DMA
53*d14abf15SRobert Mustacchi  *   operations use a single DMAE channel.
54*d14abf15SRobert Mustacchi  *
55*d14abf15SRobert Mustacchi  * - SGL DMA operations
56*d14abf15SRobert Mustacchi  *   SGL DMA operations use two DMAE channels - one called a
57*d14abf15SRobert Mustacchi  *   'loader' and one called an 'executer'. The operation is
58*d14abf15SRobert Mustacchi  *   composed of a single HW command called a 'loader' that
59*d14abf15SRobert Mustacchi  *   uses the loader channel, and multiple HW commands called
60*d14abf15SRobert Mustacchi  *   'executers' that use the executer channel. The loader
61*d14abf15SRobert Mustacchi  *   command is configured so that whenever it is executed,
62*d14abf15SRobert Mustacchi  *   it loads and executes the next pending executer command.
63*d14abf15SRobert Mustacchi  *   Executer commands are configured so that whenever they
64*d14abf15SRobert Mustacchi  *   complete they execute the loader command, except the last
65*d14abf15SRobert Mustacchi  *   executer command that simply writes the completion word
66*d14abf15SRobert Mustacchi  *   to the appropriate location in host memory.
67*d14abf15SRobert Mustacchi  *   SGL DMA operations lock both channels from the time the
68*d14abf15SRobert Mustacchi  *   loader first executes, until the last executer completes.
69*d14abf15SRobert Mustacchi  *
70*d14abf15SRobert Mustacchi  * - SGL DMA operations in asynchronous mode (a.k.a post/poll)
71*d14abf15SRobert Mustacchi  *   SGL DMA operations in asynchronous mode only lock the
72*d14abf15SRobert Mustacchi  *   context for the time required to load the loader command
73*d14abf15SRobert Mustacchi  *   to the HW registers (called the 'post' stage). Afterwords
74*d14abf15SRobert Mustacchi  *   they return immediately and unlock both channels. Then a
75*d14abf15SRobert Mustacchi  *   DMAE user may query the context's state to check if the
76*d14abf15SRobert Mustacchi  *   last executer command has already finished (the 'poll' stage).
77*d14abf15SRobert Mustacchi  *   The context is locked only for the duration of a single
78*d14abf15SRobert Mustacchi  *   query at a time. Note that a DMAE user may not use the
79*d14abf15SRobert Mustacchi  *   context until the query returns with a code that indicates
80*d14abf15SRobert Mustacchi  *   the context is available.
81*d14abf15SRobert Mustacchi  */
82*d14abf15SRobert Mustacchi 
83*d14abf15SRobert Mustacchi #ifndef _LM_DMAE_H
84*d14abf15SRobert Mustacchi #define _LM_DMAE_H
85*d14abf15SRobert Mustacchi 
86*d14abf15SRobert Mustacchi #include "mm.h"
87*d14abf15SRobert Mustacchi 
88*d14abf15SRobert Mustacchi // defines
89*d14abf15SRobert Mustacchi #define DMAE_SGL_MAX_COMMANDS       5         // max number of commands in a DMAE SGL (just as a limit - can be defined other number)
90*d14abf15SRobert Mustacchi #define DMAE_GO_VALUE               0x1         // DMAE spec
91*d14abf15SRobert Mustacchi #define DMAE_SGL_COMPLETION_VAL     0xD0AE      // local completion word value (for SGL)
92*d14abf15SRobert Mustacchi #define DMAE_COMPLETION_VAL         0xD1AE      // local completion word value with edianity mode 2 (for regular command)
93*d14abf15SRobert Mustacchi #define DMAE_COMPLETION_VAL_SWAPPED 0xAED10000  // local completion word value with edianity mode 3
94*d14abf15SRobert Mustacchi 
95*d14abf15SRobert Mustacchi #define DMAE_CMD_SIZE               14          // size of DMAE command structure
96*d14abf15SRobert Mustacchi 
97*d14abf15SRobert Mustacchi #define DMAE_MAX_RW_SIZE_E1        0x0400 // maximun size (in DW) of read/write commands (HW limit) - for  (chip id<=5710)
98*d14abf15SRobert Mustacchi 
99*d14abf15SRobert Mustacchi // up to 0xffff actually limit is 64KB-1 so 0x2000 dwords is 32KB
100*d14abf15SRobert Mustacchi #define DMAE_MAX_RW_SIZE_NEW       0x2000 // maximun size of read/write commands (HW limit) - for E1.5 and above (chip id>5710)
101*d14abf15SRobert Mustacchi #define DMAE_MAX_READ_SIZE         0x80   // due to a HW issue in E1, E1.5 A0, pci to pci and grc to pci operations are limited to 128 DWORDS
102*d14abf15SRobert Mustacchi 
103*d14abf15SRobert Mustacchi // max value for static allocations
104*d14abf15SRobert Mustacchi #define DMAE_MAX_RW_SIZE_STATIC    max(DMAE_MAX_RW_SIZE_E1,DMAE_MAX_RW_SIZE_NEW)
105*d14abf15SRobert Mustacchi 
106*d14abf15SRobert Mustacchi #define DMAE_MAX_RW_SIZE(pdev)    (CHIP_IS_E1(pdev) ?  DMAE_MAX_RW_SIZE_E1 : DMAE_MAX_RW_SIZE_NEW)
107*d14abf15SRobert Mustacchi 
108*d14abf15SRobert Mustacchi 
109*d14abf15SRobert Mustacchi #define DMAE_STATS_GET_PORT_CMD_IDX(port_num,cmd_idx) DMAE_STATS_PORT_##port_num##_CMD_IDX_##cmd_idx
110*d14abf15SRobert Mustacchi 
111*d14abf15SRobert Mustacchi #define DMAE_STATS_PORT_0_CMD_IDX_0       DMAE_CMD_DRV_0
112*d14abf15SRobert Mustacchi #define DMAE_STATS_PORT_0_CMD_IDX_1       DMAE_CMD_DRV_1
113*d14abf15SRobert Mustacchi #define DMAE_STATS_PORT_1_CMD_IDX_0       DMAE_CMD_DRV_2
114*d14abf15SRobert Mustacchi #define DMAE_STATS_PORT_1_CMD_IDX_1       DMAE_CMD_DRV_3
115*d14abf15SRobert Mustacchi #define DMAE_WB_ACCESS_FUNCTION_CMD(_idx) DMAE_CMD_DRV_4+(_idx)
116*d14abf15SRobert Mustacchi #define DMAE_COPY_PCI_PCI_PORT_0_CMD      DMAE_CMD_DRV_12
117*d14abf15SRobert Mustacchi #define DMAE_COPY_PCI_PCI_PORT_1_CMD      DMAE_CMD_DRV_13
118*d14abf15SRobert Mustacchi 
119*d14abf15SRobert Mustacchi #define LM_DMAE_INTERMEDIATE_BUFFER_SIZE DMAE_MAX_RW_SIZE_NEW
120*d14abf15SRobert Mustacchi 
121*d14abf15SRobert Mustacchi #define LM_DMAE_NO_HWLOCK 0
122*d14abf15SRobert Mustacchi 
123*d14abf15SRobert Mustacchi typedef enum _lm_dmae_protected_resource_t
124*d14abf15SRobert Mustacchi {
125*d14abf15SRobert Mustacchi     LM_PROTECTED_RESOURCE_DMAE_STATS = 0,
126*d14abf15SRobert Mustacchi     LM_PROTECTED_RESOURCE_DMAE_TOE,
127*d14abf15SRobert Mustacchi     LM_PROTECTED_RESOURCE_DMAE_DEFAULT,
128*d14abf15SRobert Mustacchi     LM_MAX_PROTECTED_RESOURCE
129*d14abf15SRobert Mustacchi }lm_dmae_protected_resource_t;
130*d14abf15SRobert Mustacchi 
131*d14abf15SRobert Mustacchi typedef enum _lm_dmae_type_t
132*d14abf15SRobert Mustacchi {
133*d14abf15SRobert Mustacchi     LM_DMAE_STATS,
134*d14abf15SRobert Mustacchi     LM_DMAE_TOE,
135*d14abf15SRobert Mustacchi     LM_DMAE_DEFAULT,
136*d14abf15SRobert Mustacchi     LM_DMAE_MAX_TYPE
137*d14abf15SRobert Mustacchi }lm_dmae_type_t;
138*d14abf15SRobert Mustacchi 
139*d14abf15SRobert Mustacchi typedef enum _lm_dmae_address_type_t
140*d14abf15SRobert Mustacchi {
141*d14abf15SRobert Mustacchi     LM_DMAE_ADDRESS_HOST_VIRT,
142*d14abf15SRobert Mustacchi     LM_DMAE_ADDRESS_HOST_PHYS,
143*d14abf15SRobert Mustacchi     LM_DMAE_ADDRESS_GRC
144*d14abf15SRobert Mustacchi }lm_dmae_address_type_t;
145*d14abf15SRobert Mustacchi 
146*d14abf15SRobert Mustacchi typedef enum _lm_dmae_mode_t
147*d14abf15SRobert Mustacchi {
148*d14abf15SRobert Mustacchi     LM_DMAE_MODE_SGL,
149*d14abf15SRobert Mustacchi     LM_DMAE_MODE_SINGLE_BLOCK
150*d14abf15SRobert Mustacchi }lm_dmae_mode_t;
151*d14abf15SRobert Mustacchi 
152*d14abf15SRobert Mustacchi typedef enum _lm_dmae_locking_policy_type_t
153*d14abf15SRobert Mustacchi {
154*d14abf15SRobert Mustacchi     LM_DMAE_LOCKING_POLICY_TYPE_NONE,
155*d14abf15SRobert Mustacchi     LM_DMAE_LOCKING_POLICY_TYPE_PER_PF,
156*d14abf15SRobert Mustacchi     LM_DMAE_LOCKING_POLICY_TYPE_INTER_PF
157*d14abf15SRobert Mustacchi }lm_dmae_locking_policy_type_t;
158*d14abf15SRobert Mustacchi 
159*d14abf15SRobert Mustacchi /**
160*d14abf15SRobert Mustacchi  * An encapsulation of the synchronization method for resource.
161*d14abf15SRobert Mustacchi  * The type of locking policy depends on the synchronization
162*d14abf15SRobert Mustacchi  * requirements for the protected resource (in this design's
163*d14abf15SRobert Mustacchi  * case - the DMAE context)
164*d14abf15SRobert Mustacchi  *
165*d14abf15SRobert Mustacchi  *  - No synchronization
166*d14abf15SRobert Mustacchi  *  Use this type of policy when there is no contention on the
167*d14abf15SRobert Mustacchi  *  protected resource. No locking will take place.
168*d14abf15SRobert Mustacchi  *  - per-PF synchronization
169*d14abf15SRobert Mustacchi  *  synchronizes access to the protected resource among users in
170*d14abf15SRobert Mustacchi  *  the same PF, but not between multiple PFs. Use this type of
171*d14abf15SRobert Mustacchi  *  policy when the protected resource is per-PF.
172*d14abf15SRobert Mustacchi  *  - inter-PF synchronization
173*d14abf15SRobert Mustacchi  *  synchronizes access to the protected resource among multiple
174*d14abf15SRobert Mustacchi  *  users that may be running in the contexts of multiple PFs.
175*d14abf15SRobert Mustacchi  *  Use this type of policy when the protected resource is
176*d14abf15SRobert Mustacchi  *  shared among multiple PFs.
177*d14abf15SRobert Mustacchi  *
178*d14abf15SRobert Mustacchi  *  @ingroup LockingPolicy
179*d14abf15SRobert Mustacchi  */
180*d14abf15SRobert Mustacchi typedef struct _lm_dmae_locking_policy_t
181*d14abf15SRobert Mustacchi {
182*d14abf15SRobert Mustacchi     mm_spin_lock_t spinlock; /**< an opaque context for the spinlock that's used by this locking policy*/
183*d14abf15SRobert Mustacchi     u32_t hwlock; /**< the HW lock used by this locking policy*/
184*d14abf15SRobert Mustacchi }lm_dmae_locking_policy_t;
185*d14abf15SRobert Mustacchi 
186*d14abf15SRobert Mustacchi /**
187*d14abf15SRobert Mustacchi  * A source/target address for a DMA operation.
188*d14abf15SRobert Mustacchi  *
189*d14abf15SRobert Mustacchi  * @ingroup DMAE_Address
190*d14abf15SRobert Mustacchi  */
191*d14abf15SRobert Mustacchi typedef struct _lm_dmae_address_t
192*d14abf15SRobert Mustacchi {
193*d14abf15SRobert Mustacchi     /**The offset of this address (either a virtual address, a
194*d14abf15SRobert Mustacchi     physical address or a GRC offset) */
195*d14abf15SRobert Mustacchi     union {
196*d14abf15SRobert Mustacchi         u32_t grc_offset;
197*d14abf15SRobert Mustacchi         void* host_virt_address;
198*d14abf15SRobert Mustacchi         lm_address_t host_phys_address;
199*d14abf15SRobert Mustacchi     } u;
200*d14abf15SRobert Mustacchi 
201*d14abf15SRobert Mustacchi     /**The type of this address*/
202*d14abf15SRobert Mustacchi     lm_dmae_address_type_t type;
203*d14abf15SRobert Mustacchi }lm_dmae_address_t;
204*d14abf15SRobert Mustacchi 
205*d14abf15SRobert Mustacchi 
206*d14abf15SRobert Mustacchi /**
207*d14abf15SRobert Mustacchi  * @ingroup DMAE_Operation
208*d14abf15SRobert Mustacchi  */
209*d14abf15SRobert Mustacchi typedef struct _lm_dmae_block_t
210*d14abf15SRobert Mustacchi {
211*d14abf15SRobert Mustacchi     lm_dmae_address_t source;
212*d14abf15SRobert Mustacchi     lm_dmae_address_t dest;
213*d14abf15SRobert Mustacchi     u16_t length;
214*d14abf15SRobert Mustacchi }lm_dmae_block_t;
215*d14abf15SRobert Mustacchi 
216*d14abf15SRobert Mustacchi /**
217*d14abf15SRobert Mustacchi  * An aggregation of one or more DMAE channels that are used by
218*d14abf15SRobert Mustacchi  * the driver for the same function with the same configuration.
219*d14abf15SRobert Mustacchi  * A context may be a non-SGL context (in which case it is
220*d14abf15SRobert Mustacchi  * associated with a single DMAE channel) or an SGL context (in
221*d14abf15SRobert Mustacchi  * which case it is associated with two DMAE channels). Every
222*d14abf15SRobert Mustacchi  * context may have one current operation.
223*d14abf15SRobert Mustacchi  *
224*d14abf15SRobert Mustacchi  * @ingroup DMAE_Context
225*d14abf15SRobert Mustacchi  */
226*d14abf15SRobert Mustacchi typedef struct _lm_dmae_context_t
227*d14abf15SRobert Mustacchi {
228*d14abf15SRobert Mustacchi     /**The type of the context (SGL or single-block)   */
229*d14abf15SRobert Mustacchi     lm_dmae_mode_t mode;
230*d14abf15SRobert Mustacchi 
231*d14abf15SRobert Mustacchi     /** - single-block context: the index of the DMAE channel for
232*d14abf15SRobert Mustacchi      *  this context
233*d14abf15SRobert Mustacchi      *  - SGL context: the index of the loader DMAE channel for this
234*d14abf15SRobert Mustacchi      *    context*/
235*d14abf15SRobert Mustacchi     u8_t main_channel;
236*d14abf15SRobert Mustacchi 
237*d14abf15SRobert Mustacchi     /**SGL context: the index of the executer DMAE channel for this
238*d14abf15SRobert Mustacchi      * context.
239*d14abf15SRobert Mustacchi      * This field has no meaning for single-block contexts */
240*d14abf15SRobert Mustacchi     u8_t executer_channel;
241*d14abf15SRobert Mustacchi 
242*d14abf15SRobert Mustacchi     u8_t change_endianity;
243*d14abf15SRobert Mustacchi 
244*d14abf15SRobert Mustacchi     u32_t next_command_id;
245*d14abf15SRobert Mustacchi 
246*d14abf15SRobert Mustacchi     lm_dmae_locking_policy_t* locking_policy;
247*d14abf15SRobert Mustacchi 
248*d14abf15SRobert Mustacchi     /**This physical address of the field completion_word   */
249*d14abf15SRobert Mustacchi     lm_address_t completion_word_paddr;
250*d14abf15SRobert Mustacchi 
251*d14abf15SRobert Mustacchi     /**The memory location where the DMAE writes the completion
252*d14abf15SRobert Mustacchi      * value when an operation is finished on this context.*/
253*d14abf15SRobert Mustacchi     volatile u32_t completion_word;
254*d14abf15SRobert Mustacchi 
255*d14abf15SRobert Mustacchi     /**The value that the DMAE writes to completion_word when an
256*d14abf15SRobert Mustacchi      * operation is finished on this context. Endianess note: The
257*d14abf15SRobert Mustacchi      * completion value that's written as part of the command is
258*d14abf15SRobert Mustacchi      * always the same, but the value that's later written to
259*d14abf15SRobert Mustacchi      * memory depends on the endianness mode of the command, so
260*d14abf15SRobert Mustacchi      * this value represents the value that's written by the DMAE
261*d14abf15SRobert Mustacchi      * and not the value that's used by the VBD. */
262*d14abf15SRobert Mustacchi     u32_t completion_value;
263*d14abf15SRobert Mustacchi 
264*d14abf15SRobert Mustacchi     /**This physical address of the beginnning of
265*d14abf15SRobert Mustacchi      * intermediate_buffer*/
266*d14abf15SRobert Mustacchi     lm_address_t intermediate_buffer_paddr;
267*d14abf15SRobert Mustacchi 
268*d14abf15SRobert Mustacchi     /**An intermediate buffer for DMAE operations that use virtual
269*d14abf15SRobert Mustacchi      * addresses - data is DMA'd to/from this buffer and then
270*d14abf15SRobert Mustacchi      * memcpy'd to/from the virtual address*/
271*d14abf15SRobert Mustacchi     u32_t intermediate_buffer[LM_DMAE_INTERMEDIATE_BUFFER_SIZE];
272*d14abf15SRobert Mustacchi }lm_dmae_context_t;
273*d14abf15SRobert Mustacchi 
274*d14abf15SRobert Mustacchi 
275*d14abf15SRobert Mustacchi /**
276*d14abf15SRobert Mustacchi  * A single logical DMAE transfer, which may be either a
277*d14abf15SRobert Mustacchi  * single-block transfer (in which case it has a single source
278*d14abf15SRobert Mustacchi  * and a single target) or an SGL transfer (in which case it is
279*d14abf15SRobert Mustacchi  * composed of multiple SGEs, each having a single source and a
280*d14abf15SRobert Mustacchi  * single target). An SGL operation may be synchronous or
281*d14abf15SRobert Mustacchi  * asynchronous - executing a synchronous DMAE operation results
282*d14abf15SRobert Mustacchi  * in a wait until the operation completes, while an
283*d14abf15SRobert Mustacchi  * asynchronous operation may be posted to the hardware without
284*d14abf15SRobert Mustacchi  * waiting for its completion.
285*d14abf15SRobert Mustacchi  *
286*d14abf15SRobert Mustacchi  * @ingroup DMAE_Operation
287*d14abf15SRobert Mustacchi  */
288*d14abf15SRobert Mustacchi typedef struct _lm_dmae_operation_t
289*d14abf15SRobert Mustacchi {
290*d14abf15SRobert Mustacchi     /**The type of this operation (SGL or single-block)*/
291*d14abf15SRobert Mustacchi     lm_dmae_mode_t mode;
292*d14abf15SRobert Mustacchi 
293*d14abf15SRobert Mustacchi     /**The context of this operation.*/
294*d14abf15SRobert Mustacchi     lm_dmae_context_t* context;
295*d14abf15SRobert Mustacchi 
296*d14abf15SRobert Mustacchi /**TRUE if the source is a block of length DMAE_MAX_RW_SIZE_E1 /
297*d14abf15SRobert Mustacchi  * DMAE_MAX_RW_SIZE_NEW and the destination is larger. In this
298*d14abf15SRobert Mustacchi  * case the source block will be duplicated as many times as
299*d14abf15SRobert Mustacchi  * required to fill the destination block.*/
300*d14abf15SRobert Mustacchi     u8_t b_replicate_source;
301*d14abf15SRobert Mustacchi 
302*d14abf15SRobert Mustacchi     u8_t le32_swap;
303*d14abf15SRobert Mustacchi 
304*d14abf15SRobert Mustacchi     /**SGL: TRUE if this operation is synchronous. This field has
305*d14abf15SRobert Mustacchi      * no meaning for single-block operations. */
306*d14abf15SRobert Mustacchi     u8_t b_sync;
307*d14abf15SRobert Mustacchi 
308*d14abf15SRobert Mustacchi     u32_t command_id;
309*d14abf15SRobert Mustacchi 
310*d14abf15SRobert Mustacchi     /**SGL: The loader command for this operation
311*d14abf15SRobert Mustacchi      *SINGLE_BLOCK: The command for this operation*/
312*d14abf15SRobert Mustacchi     struct dmae_cmd main_cmd;
313*d14abf15SRobert Mustacchi 
314*d14abf15SRobert Mustacchi     /**The next available entry in blocks[] and executer_cmdp[] */
315*d14abf15SRobert Mustacchi     u8_t next_free_block;
316*d14abf15SRobert Mustacchi 
317*d14abf15SRobert Mustacchi     /**The block/blocks of this operation*/
318*d14abf15SRobert Mustacchi     lm_dmae_block_t blocks[DMAE_SGL_MAX_COMMANDS];
319*d14abf15SRobert Mustacchi 
320*d14abf15SRobert Mustacchi     /**SGL: The physical address of the beginning of executer_cmd.
321*d14abf15SRobert Mustacchi      * This field has no meaning for single-block operations.   */
322*d14abf15SRobert Mustacchi     lm_address_t executer_paddr;
323*d14abf15SRobert Mustacchi 
324*d14abf15SRobert Mustacchi     /**SGL: The executer HSI commands for this operation. This
325*d14abf15SRobert Mustacchi      * field has no meaning for single-block operations. */
326*d14abf15SRobert Mustacchi     struct dmae_cmd executer_cmd[DMAE_SGL_MAX_COMMANDS]; //these must be consecutive, so they can't be a part of the blocks[] array.
327*d14abf15SRobert Mustacchi }lm_dmae_operation_t;
328*d14abf15SRobert Mustacchi 
329*d14abf15SRobert Mustacchi typedef struct _lm_dmae_context_info_t
330*d14abf15SRobert Mustacchi {
331*d14abf15SRobert Mustacchi     lm_dmae_context_t* context;
332*d14abf15SRobert Mustacchi     lm_dmae_locking_policy_t locking_policy;
333*d14abf15SRobert Mustacchi }lm_dmae_context_info_t ;
334*d14abf15SRobert Mustacchi 
335*d14abf15SRobert Mustacchi typedef struct _lm_dmae_info_t
336*d14abf15SRobert Mustacchi {
337*d14abf15SRobert Mustacchi     lm_dmae_context_info_t ctx_arr[LM_DMAE_MAX_TYPE];
338*d14abf15SRobert Mustacchi }lm_dmae_info_t;
339*d14abf15SRobert Mustacchi 
340*d14abf15SRobert Mustacchi //------------------ Locking Policy ------------------//
341*d14abf15SRobert Mustacchi 
342*d14abf15SRobert Mustacchi /**lm_dmae_locking_policy_create
343*d14abf15SRobert Mustacchi  * Create a locking policy
344*d14abf15SRobert Mustacchi  *
345*d14abf15SRobert Mustacchi  * @param resource The ID of the protected resource. This ID is
346*d14abf15SRobert Mustacchi  *                 used to determine which synchronization
347*d14abf15SRobert Mustacchi  *                 objects will be used by the policy.
348*d14abf15SRobert Mustacchi  * @param type the type of this locking policy
349*d14abf15SRobert Mustacchi  * @param policy the policy to initialize.
350*d14abf15SRobert Mustacchi  *
351*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
352*d14abf15SRobert Mustacchi  *         failure value on failure.
353*d14abf15SRobert Mustacchi  */
354*d14abf15SRobert Mustacchi lm_status_t lm_dmae_locking_policy_create(  struct _lm_device_t* pdev,
355*d14abf15SRobert Mustacchi                                             IN const u32_t resource,
356*d14abf15SRobert Mustacchi                                             IN const lm_dmae_locking_policy_type_t type,
357*d14abf15SRobert Mustacchi                                             OUT lm_dmae_locking_policy_t* policy);
358*d14abf15SRobert Mustacchi 
359*d14abf15SRobert Mustacchi /**lm_dmae_locking_policy_lock
360*d14abf15SRobert Mustacchi  * Use a locking policy to lock a resource, acquiring whatever
361*d14abf15SRobert Mustacchi  * spinlock or hardware lock required.
362*d14abf15SRobert Mustacchi  *
363*d14abf15SRobert Mustacchi  * @param locking_policy the policy to use
364*d14abf15SRobert Mustacchi  *
365*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
366*d14abf15SRobert Mustacchi  *         failure code on failure.
367*d14abf15SRobert Mustacchi  */
368*d14abf15SRobert Mustacchi #ifdef _VBD_
369*d14abf15SRobert Mustacchi __drv_maxIRQL(DISPATCH_LEVEL)
370*d14abf15SRobert Mustacchi __drv_at(locking_policy->spinlock.irql, __drv_savesIRQL)
371*d14abf15SRobert Mustacchi __drv_setsIRQL(DISPATCH_LEVEL)
372*d14abf15SRobert Mustacchi #endif
373*d14abf15SRobert Mustacchi lm_status_t lm_dmae_locking_policy_lock(struct _lm_device_t* pdev, lm_dmae_locking_policy_t* locking_policy);
374*d14abf15SRobert Mustacchi 
375*d14abf15SRobert Mustacchi /**lm_dmae_locking_policy_unlock
376*d14abf15SRobert Mustacchi  * Use a locking policy to unlock a resource, releasing
377*d14abf15SRobert Mustacchi  * whatever spinlock or hardware lock required.
378*d14abf15SRobert Mustacchi  *
379*d14abf15SRobert Mustacchi  * @param locking_policy the policy to use
380*d14abf15SRobert Mustacchi  *
381*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
382*d14abf15SRobert Mustacchi  *         failure code on failure
383*d14abf15SRobert Mustacchi  */
384*d14abf15SRobert Mustacchi #ifdef _VBD_
385*d14abf15SRobert Mustacchi #if defined(NTDDI_WIN8)
386*d14abf15SRobert Mustacchi _IRQL_requires_(DISPATCH_LEVEL)
387*d14abf15SRobert Mustacchi __drv_at(locking_policy->spinlock.irql, __drv_restoresIRQL )
388*d14abf15SRobert Mustacchi #endif
389*d14abf15SRobert Mustacchi #endif
390*d14abf15SRobert Mustacchi lm_status_t lm_dmae_locking_policy_unlock(struct _lm_device_t* pdev, lm_dmae_locking_policy_t* locking_policy);
391*d14abf15SRobert Mustacchi 
392*d14abf15SRobert Mustacchi 
393*d14abf15SRobert Mustacchi 
394*d14abf15SRobert Mustacchi //------------------ DMAE Context ------------------//
395*d14abf15SRobert Mustacchi 
396*d14abf15SRobert Mustacchi /**lm_dmae_context_create
397*d14abf15SRobert Mustacchi  * Create a non-SGL DMA context, using the given policy for
398*d14abf15SRobert Mustacchi  * synchronization.
399*d14abf15SRobert Mustacchi  *
400*d14abf15SRobert Mustacchi  * @param channel_idx the DMAE channel index that is used by
401*d14abf15SRobert Mustacchi  *                    this context
402*d14abf15SRobert Mustacchi  * @param locking_policy the synchronization policy used by this
403*d14abf15SRobert Mustacchi  *                       context
404*d14abf15SRobert Mustacchi  * @param change_endianity
405*d14abf15SRobert Mustacchi  *
406*d14abf15SRobert Mustacchi  * @return lm_dmae_context_t* a single-block DMAE context
407*d14abf15SRobert Mustacchi  *                configured according to the supplied
408*d14abf15SRobert Mustacchi  *                parameters.
409*d14abf15SRobert Mustacchi  */
410*d14abf15SRobert Mustacchi lm_dmae_context_t* lm_dmae_context_create(  struct _lm_device_t* pdev,
411*d14abf15SRobert Mustacchi                                             IN const u8_t channel_idx,
412*d14abf15SRobert Mustacchi                                             lm_dmae_locking_policy_t* locking_policy,
413*d14abf15SRobert Mustacchi                                             IN const u8_t change_endianity);
414*d14abf15SRobert Mustacchi 
415*d14abf15SRobert Mustacchi /**lm_dmae_context_create_sgl
416*d14abf15SRobert Mustacchi  * Create an SGL DMA context, using the given policy for
417*d14abf15SRobert Mustacchi  * synchronization.
418*d14abf15SRobert Mustacchi  *
419*d14abf15SRobert Mustacchi  * @param loader_channel_idx the 'loader' DMAE channel index
420*d14abf15SRobert Mustacchi  *                           that is used by this context
421*d14abf15SRobert Mustacchi  * @param executer_channel_idx the 'executer' DMAE channel index
422*d14abf15SRobert Mustacchi  *                             that is used by this context
423*d14abf15SRobert Mustacchi  * @param locking_policy the synchronization policy used by this
424*d14abf15SRobert Mustacchi  *                       context
425*d14abf15SRobert Mustacchi  * @param change_endianity
426*d14abf15SRobert Mustacchi  *
427*d14abf15SRobert Mustacchi  * @return lm_status_t an SGL DMAE context configured according
428*d14abf15SRobert Mustacchi  *                to the supplied parameters.
429*d14abf15SRobert Mustacchi  */
430*d14abf15SRobert Mustacchi lm_dmae_context_t* lm_dmae_context_create_sgl( struct _lm_device_t* pdev,
431*d14abf15SRobert Mustacchi                                                IN const u8_t loader_channel_idx,
432*d14abf15SRobert Mustacchi                                                IN const u8_t executer_channel_idx,
433*d14abf15SRobert Mustacchi                                                lm_dmae_locking_policy_t* locking_policy,
434*d14abf15SRobert Mustacchi                                                IN const u8_t change_endianity);
435*d14abf15SRobert Mustacchi 
436*d14abf15SRobert Mustacchi /**lm_dmae_context_reset
437*d14abf15SRobert Mustacchi  * Bring a DMAE context to a known-good state. This function
438*d14abf15SRobert Mustacchi  * must be used on an acquired context. It should be used if for
439*d14abf15SRobert Mustacchi  * some reason the context is left in an invalid state (e.g an
440*d14abf15SRobert Mustacchi  * error occured during a DMAE transaction using this context).
441*d14abf15SRobert Mustacchi  *
442*d14abf15SRobert Mustacchi  * @param context the context to reset.
443*d14abf15SRobert Mustacchi  *
444*d14abf15SRobert Mustacchi  * @return lm_status LM_STATUS_SUCCESS on success, some other
445*d14abf15SRobert Mustacchi  *         failure code on failure.
446*d14abf15SRobert Mustacchi  */
447*d14abf15SRobert Mustacchi lm_status_t lm_dmae_context_reset(lm_dmae_context_t *context);
448*d14abf15SRobert Mustacchi 
449*d14abf15SRobert Mustacchi /**lm_dmae_context_acquire
450*d14abf15SRobert Mustacchi  * Acquire the context, so that multiple DMAE operations may be
451*d14abf15SRobert Mustacchi  * executed on it without locking the context once for every
452*d14abf15SRobert Mustacchi  * operation. Only after calling this function can
453*d14abf15SRobert Mustacchi  * lm_dmae_context_execute_unsafe be used.
454*d14abf15SRobert Mustacchi  *
455*d14abf15SRobert Mustacchi  * @param context the context to acquire
456*d14abf15SRobert Mustacchi  *
457*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
458*d14abf15SRobert Mustacchi  *         failure value on failure
459*d14abf15SRobert Mustacchi  */
460*d14abf15SRobert Mustacchi #ifdef _VBD_
461*d14abf15SRobert Mustacchi __drv_maxIRQL(DISPATCH_LEVEL)
462*d14abf15SRobert Mustacchi __drv_at(context->locking_policy->spinlock.irql, __drv_savesIRQL)
463*d14abf15SRobert Mustacchi __drv_setsIRQL(DISPATCH_LEVEL)
464*d14abf15SRobert Mustacchi #endif
465*d14abf15SRobert Mustacchi lm_status_t lm_dmae_context_acquire(struct _lm_device_t* pdev, lm_dmae_context_t *context);
466*d14abf15SRobert Mustacchi 
467*d14abf15SRobert Mustacchi /**lm_dmae_context_release
468*d14abf15SRobert Mustacchi  * Release a context that was acquired with
469*d14abf15SRobert Mustacchi  * lm_dmae_context_release. After calling this function,
470*d14abf15SRobert Mustacchi  * lm_dmae_context_execute_unsafe may not be used on the
471*d14abf15SRobert Mustacchi  * context.
472*d14abf15SRobert Mustacchi  *
473*d14abf15SRobert Mustacchi  * @param context the context to release
474*d14abf15SRobert Mustacchi  *
475*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
476*d14abf15SRobert Mustacchi  *         failure value on failure
477*d14abf15SRobert Mustacchi  */
478*d14abf15SRobert Mustacchi #ifdef _VBD_
479*d14abf15SRobert Mustacchi #if defined(NTDDI_WIN8)
480*d14abf15SRobert Mustacchi _IRQL_requires_(DISPATCH_LEVEL)
481*d14abf15SRobert Mustacchi __drv_at(context->locking_policy->spinlock.irql, __drv_restoresIRQL )
482*d14abf15SRobert Mustacchi #endif
483*d14abf15SRobert Mustacchi #endif
484*d14abf15SRobert Mustacchi lm_status_t lm_dmae_context_release(struct _lm_device_t* pdev, lm_dmae_context_t *context);
485*d14abf15SRobert Mustacchi 
486*d14abf15SRobert Mustacchi 
487*d14abf15SRobert Mustacchi /**lm_dmae_context_execute
488*d14abf15SRobert Mustacchi  * Execute a command in a context, using the context's locking
489*d14abf15SRobert Mustacchi  * policy
490*d14abf15SRobert Mustacchi  *
491*d14abf15SRobert Mustacchi  * @param context the context to use
492*d14abf15SRobert Mustacchi  * @param operation the operation to execute
493*d14abf15SRobert Mustacchi  *
494*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
495*d14abf15SRobert Mustacchi  *         LM_STATUS_PENDING if executing an asynchronous
496*d14abf15SRobert Mustacchi  *         operation, LM_STATUS_BUSY if another asyncronous
497*d14abf15SRobert Mustacchi  *         operation is in progress or some other failure code
498*d14abf15SRobert Mustacchi  *         on failure.
499*d14abf15SRobert Mustacchi  */
500*d14abf15SRobert Mustacchi lm_status_t lm_dmae_context_execute(struct _lm_device_t* pdev, lm_dmae_context_t *context, lm_dmae_operation_t *operation);
501*d14abf15SRobert Mustacchi 
502*d14abf15SRobert Mustacchi /**lm_dmae_context_execute_unsafe
503*d14abf15SRobert Mustacchi  * Execute a command in a context, without locking. This
504*d14abf15SRobert Mustacchi  * function must be called between calls to
505*d14abf15SRobert Mustacchi  * lm_dmae_context_acquire and lm_dmae_context_release.
506*d14abf15SRobert Mustacchi  *
507*d14abf15SRobert Mustacchi  * @param context the context to use
508*d14abf15SRobert Mustacchi  * @param operation the operation to execute
509*d14abf15SRobert Mustacchi  *
510*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
511*d14abf15SRobert Mustacchi  *         LM_STATUS_PENDING if executing an asynchronous
512*d14abf15SRobert Mustacchi  *         operation, LM_STATUS_BUSY if another asyncronous
513*d14abf15SRobert Mustacchi  *         operation is in progress or some other failure code
514*d14abf15SRobert Mustacchi  *         on failure.
515*d14abf15SRobert Mustacchi  */
516*d14abf15SRobert Mustacchi lm_status_t lm_dmae_context_execute_unsafe(struct _lm_device_t* pdev, lm_dmae_context_t *context, lm_dmae_operation_t *operation);
517*d14abf15SRobert Mustacchi 
518*d14abf15SRobert Mustacchi 
519*d14abf15SRobert Mustacchi 
520*d14abf15SRobert Mustacchi 
521*d14abf15SRobert Mustacchi //------------------ DMAE Operation ------------------//
522*d14abf15SRobert Mustacchi 
523*d14abf15SRobert Mustacchi /**lm_dmae_operation_create
524*d14abf15SRobert Mustacchi  * Create a single-block DMAE operation and the DMAE command
525*d14abf15SRobert Mustacchi  * that it uses.
526*d14abf15SRobert Mustacchi  *
527*d14abf15SRobert Mustacchi  * @param source the source for this DMAE operation
528*d14abf15SRobert Mustacchi  * @param dest the destination for this DMAE operation
529*d14abf15SRobert Mustacchi  * @param length the length of the block to transfer
530*d14abf15SRobert Mustacchi  * @param replicate_source TRUE if the source is a block of
531*d14abf15SRobert Mustacchi  *                           length DMAE_MAX_RW_SIZE_E1/DMAE_MAX_RW_SIZE_NEW
532*d14abf15SRobert Mustacchi  *                           and the destination is larger. In
533*d14abf15SRobert Mustacchi  *                           this case the source block will be
534*d14abf15SRobert Mustacchi  *                           duplicated as many times as
535*d14abf15SRobert Mustacchi  *                           required to fill the destination
536*d14abf15SRobert Mustacchi  *                           block.
537*d14abf15SRobert Mustacchi  * @param le32_swap should byte-swapping occur before executing
538*d14abf15SRobert Mustacchi  *                  the operation.
539*d14abf15SRobert Mustacchi  * @param context the DMAE context for this operation
540*d14abf15SRobert Mustacchi  * @param operation the operation to initialize. If this function
541*d14abf15SRobert Mustacchi  *                  returns LM_STATUS_SUCCESS, the operation
542*d14abf15SRobert Mustacchi  *                  pointed to by this parameter is initialized
543*d14abf15SRobert Mustacchi  *                  to a single-block DMAE operation configured
544*d14abf15SRobert Mustacchi  *                  according to the supplied parameters.
545*d14abf15SRobert Mustacchi  *
546*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success, some other
547*d14abf15SRobert Mustacchi  *         failure value on failure.
548*d14abf15SRobert Mustacchi  */
549*d14abf15SRobert Mustacchi lm_status_t lm_dmae_operation_create(   struct _lm_device_t* pdev,
550*d14abf15SRobert Mustacchi                                         IN const lm_dmae_address_t source,
551*d14abf15SRobert Mustacchi                                         IN const lm_dmae_address_t dest,
552*d14abf15SRobert Mustacchi                                         IN const u16_t length,
553*d14abf15SRobert Mustacchi                                         IN const u8_t replicate_source,
554*d14abf15SRobert Mustacchi                                         IN const u8_t le32_swap,
555*d14abf15SRobert Mustacchi                                         IN lm_dmae_context_t* context,
556*d14abf15SRobert Mustacchi                                         OUT lm_dmae_operation_t* operation);
557*d14abf15SRobert Mustacchi 
558*d14abf15SRobert Mustacchi /**lm_dmae_operation_create_sgl
559*d14abf15SRobert Mustacchi  * Create an SGL DMAE operation and the DMAE commands that it
560*d14abf15SRobert Mustacchi  * uses.
561*d14abf15SRobert Mustacchi  *
562*d14abf15SRobert Mustacchi  * @param b_sync TRUE if this operation is synchronous, FALSE
563*d14abf15SRobert Mustacchi  *               otherwise.
564*d14abf15SRobert Mustacchi  * @param context the DMAE context for this operation
565*d14abf15SRobert Mustacchi  *
566*d14abf15SRobert Mustacchi  * @return lm_dmae_operation_t* An empty SGL DMAE operation
567*d14abf15SRobert Mustacchi  *         based on the supplied parameters. Use
568*d14abf15SRobert Mustacchi  *         lm_dmae_operation_add_sge to add SGEs to this
569*d14abf15SRobert Mustacchi  *         operation. On failure the function returns NULL.
570*d14abf15SRobert Mustacchi  */
571*d14abf15SRobert Mustacchi lm_dmae_operation_t* lm_dmae_operation_create_sgl(  struct _lm_device_t* pdev,
572*d14abf15SRobert Mustacchi                                                     IN const u8_t b_sync,
573*d14abf15SRobert Mustacchi                                                     IN lm_dmae_context_t* context);
574*d14abf15SRobert Mustacchi 
575*d14abf15SRobert Mustacchi /**lm_dmae_operation_add_sge
576*d14abf15SRobert Mustacchi  * Add an SGE to an SGL operation.
577*d14abf15SRobert Mustacchi  *
578*d14abf15SRobert Mustacchi  * @param operation the operation to add an SGE to.
579*d14abf15SRobert Mustacchi  * @param source the source for this SGE
580*d14abf15SRobert Mustacchi  * @param dest the destination for this SGE
581*d14abf15SRobert Mustacchi  * @param length the length of the block to transfer
582*d14abf15SRobert Mustacchi  *
583*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
584*d14abf15SRobert Mustacchi  *         LM_STATUS_INVALID_PARAMETER if the supplied operation
585*d14abf15SRobert Mustacchi  *         is not an SGL operation, some other failure code on
586*d14abf15SRobert Mustacchi  *         failure.
587*d14abf15SRobert Mustacchi  */
588*d14abf15SRobert Mustacchi lm_status_t lm_dmae_operation_add_sge(  struct _lm_device_t* pdev,
589*d14abf15SRobert Mustacchi                                         lm_dmae_operation_t* operation,
590*d14abf15SRobert Mustacchi                                         IN const lm_dmae_address_t source,
591*d14abf15SRobert Mustacchi                                         IN const lm_dmae_address_t dest,
592*d14abf15SRobert Mustacchi                                         IN const u16_t length);
593*d14abf15SRobert Mustacchi 
594*d14abf15SRobert Mustacchi /**lm_dmae_operation_clear_all_sges
595*d14abf15SRobert Mustacchi  * Remove all SGEs from an SGL DMAE command.
596*d14abf15SRobert Mustacchi  *
597*d14abf15SRobert Mustacchi  * @param operation the operation to clear
598*d14abf15SRobert Mustacchi  *
599*d14abf15SRobert Mustacchi  */
600*d14abf15SRobert Mustacchi void lm_dmae_operation_clear_all_sges(lm_dmae_operation_t* operation);
601*d14abf15SRobert Mustacchi 
602*d14abf15SRobert Mustacchi /**lm_dmae_operation_is_complete
603*d14abf15SRobert Mustacchi  * check if an operation has finished
604*d14abf15SRobert Mustacchi  *
605*d14abf15SRobert Mustacchi  * @param operation the operation to check
606*d14abf15SRobert Mustacchi  *
607*d14abf15SRobert Mustacchi  * @return u8_t TRUE if the given operation is complete
608*d14abf15SRobert Mustacchi  */
609*d14abf15SRobert Mustacchi u8_t lm_dmae_operation_is_complete(IN lm_dmae_operation_t* operation);
610*d14abf15SRobert Mustacchi 
611*d14abf15SRobert Mustacchi 
612*d14abf15SRobert Mustacchi 
613*d14abf15SRobert Mustacchi 
614*d14abf15SRobert Mustacchi //------------------ DMAE Address ------------------//
615*d14abf15SRobert Mustacchi 
616*d14abf15SRobert Mustacchi /**lm_dmae_address_native_offset
617*d14abf15SRobert Mustacchi  * Get a u64_t representation of the address's value which can
618*d14abf15SRobert Mustacchi  * be used as a source/destination address by DMAE hardware (i.e
619*d14abf15SRobert Mustacchi  * byte offset for host memory address,  DWORD offset for GRC
620*d14abf15SRobert Mustacchi  * offsets)
621*d14abf15SRobert Mustacchi  *
622*d14abf15SRobert Mustacchi  * @param address the address to use
623*d14abf15SRobert Mustacchi  *
624*d14abf15SRobert Mustacchi  * @return u64_t see description
625*d14abf15SRobert Mustacchi  */
626*d14abf15SRobert Mustacchi u64_t lm_dmae_address_native_offset(IN const lm_dmae_address_t* address);
627*d14abf15SRobert Mustacchi 
628*d14abf15SRobert Mustacchi /**lm_dmae_address
629*d14abf15SRobert Mustacchi  * create a DMAE address
630*d14abf15SRobert Mustacchi  *
631*d14abf15SRobert Mustacchi  * @param offset the offset of the address (either
632*d14abf15SRobert Mustacchi  *               physical/virtual address or GRC offset)
633*d14abf15SRobert Mustacchi  * @param type the type of the address
634*d14abf15SRobert Mustacchi  *
635*d14abf15SRobert Mustacchi  * @return lm_dmae_address_t a DMAE address initialized
636*d14abf15SRobert Mustacchi  *         according to the supplied parameters
637*d14abf15SRobert Mustacchi  */
638*d14abf15SRobert Mustacchi lm_dmae_address_t lm_dmae_address(IN const u64_t offset, IN const lm_dmae_address_type_t type);
639*d14abf15SRobert Mustacchi 
640*d14abf15SRobert Mustacchi //------------------ DMAE users ------------------//
641*d14abf15SRobert Mustacchi 
642*d14abf15SRobert Mustacchi /**lm_dmae_get
643*d14abf15SRobert Mustacchi  * Return the context info for a given DMAE user.
644*d14abf15SRobert Mustacchi  *
645*d14abf15SRobert Mustacchi  * @param pdev the device to use
646*d14abf15SRobert Mustacchi  * @param type the dmae user
647*d14abf15SRobert Mustacchi  *
648*d14abf15SRobert Mustacchi  * @return lm_dmae_context_info_t* the context info for the given user, or NULL on error.
649*d14abf15SRobert Mustacchi  */
650*d14abf15SRobert Mustacchi lm_dmae_context_info_t* lm_dmae_get(struct _lm_device_t* pdev, IN const lm_dmae_type_t type);
651*d14abf15SRobert Mustacchi 
652*d14abf15SRobert Mustacchi /**lm_dmae_reg_wr
653*d14abf15SRobert Mustacchi  * Write a block of data from host memory (given as a virtual
654*d14abf15SRobert Mustacchi  * address) to GRC.
655*d14abf15SRobert Mustacchi  *
656*d14abf15SRobert Mustacchi  * @param pdev the device to use
657*d14abf15SRobert Mustacchi  * @param context the DMAE context to use
658*d14abf15SRobert Mustacchi  * @param source_vaddr the beginning of the source memory block
659*d14abf15SRobert Mustacchi  * @param dest_offset the GRC offset of the destination block
660*d14abf15SRobert Mustacchi  * @param length the length (in DWORDS) of the block
661*d14abf15SRobert Mustacchi  * @param b_replicate_source TRUE if the source is a block of
662*d14abf15SRobert Mustacchi  *                           length
663*d14abf15SRobert Mustacchi  *                           DMAE_MAX_RW_SIZE_E1/DMAE_MAX_RW_SIZE_NEW
664*d14abf15SRobert Mustacchi  *                           and the destination is larger. In
665*d14abf15SRobert Mustacchi  *                           this case the source block will be
666*d14abf15SRobert Mustacchi  *                           duplicated as many times as
667*d14abf15SRobert Mustacchi  *                           required to fill the destination
668*d14abf15SRobert Mustacchi  *                           block.
669*d14abf15SRobert Mustacchi  * @param le32_swap if TRUE, change all DWORDS in the source
670*d14abf15SRobert Mustacchi  *                  block to little-endian representation before
671*d14abf15SRobert Mustacchi  *                  executing the operation.
672*d14abf15SRobert Mustacchi  *
673*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
674*d14abf15SRobert Mustacchi  *         LM_STATUS_TIMEOUT if the operation did not finish in
675*d14abf15SRobert Mustacchi  *         reasonable time, some other failure value on failure.
676*d14abf15SRobert Mustacchi  */
677*d14abf15SRobert Mustacchi lm_status_t lm_dmae_reg_wr(struct _lm_device_t* pdev, lm_dmae_context_t* context, void* source_vaddr, u32_t dest_offset, u16_t length, u8_t b_replicate_source, u8_t le32_swap);
678*d14abf15SRobert Mustacchi 
679*d14abf15SRobert Mustacchi /**lm_dmae_reg_wr_phys
680*d14abf15SRobert Mustacchi  * Write a block of data from host memory (given as a physical
681*d14abf15SRobert Mustacchi  * address) to GRC.
682*d14abf15SRobert Mustacchi  *
683*d14abf15SRobert Mustacchi  * @param pdev the device to use
684*d14abf15SRobert Mustacchi  * @param context the DMAE context to use
685*d14abf15SRobert Mustacchi  * @param source_paddr the beginning of the source memory block
686*d14abf15SRobert Mustacchi  * @param dest_offset the GRC offset of the destination block
687*d14abf15SRobert Mustacchi  * @param length the length (in DWORDS) of the block
688*d14abf15SRobert Mustacchi  *
689*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
690*d14abf15SRobert Mustacchi  *         LM_STATUS_TIMEOUT if the operation did not finish in
691*d14abf15SRobert Mustacchi  *         reasonable time, some other failure value on failure.
692*d14abf15SRobert Mustacchi  */
693*d14abf15SRobert Mustacchi lm_status_t lm_dmae_reg_wr_phys(struct _lm_device_t* pdev, lm_dmae_context_t* context, lm_address_t source_paddr, u32_t dest_offset, u16_t length);
694*d14abf15SRobert Mustacchi 
695*d14abf15SRobert Mustacchi /**lm_dmae_reg_rd
696*d14abf15SRobert Mustacchi  * Read a block from GRC to host memory(given as a virtual
697*d14abf15SRobert Mustacchi  * address).
698*d14abf15SRobert Mustacchi  *
699*d14abf15SRobert Mustacchi  *
700*d14abf15SRobert Mustacchi  * @param pdev the device to use
701*d14abf15SRobert Mustacchi  * @param context the DMAE context to use
702*d14abf15SRobert Mustacchi  * @param source_offset the GRC offset of the source block
703*d14abf15SRobert Mustacchi  * @param dest_vaddr the beginning of the destination memory
704*d14abf15SRobert Mustacchi  *                   block
705*d14abf15SRobert Mustacchi  * @param length the length (in DWORDS) of the block
706*d14abf15SRobert Mustacchi  * @param le32_swap if TRUE, change all DWORDS in data to
707*d14abf15SRobert Mustacchi  *                  little-endian after it's read from GRC.
708*d14abf15SRobert Mustacchi  *
709*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
710*d14abf15SRobert Mustacchi  *         LM_STATUS_TIMEOUT if the operation did not finish in
711*d14abf15SRobert Mustacchi  *         reasonable time, some other failure value on failure.
712*d14abf15SRobert Mustacchi  */
713*d14abf15SRobert Mustacchi lm_status_t lm_dmae_reg_rd(struct _lm_device_t* pdev, lm_dmae_context_t* context, u32_t source_offset, void* dest_vaddr, u16_t length, u8_t le32_swap);
714*d14abf15SRobert Mustacchi 
715*d14abf15SRobert Mustacchi 
716*d14abf15SRobert Mustacchi /**lm_dmae_copy_phys_buffer_unsafe
717*d14abf15SRobert Mustacchi  * Copy a block from host memory to host memory, both addresses
718*d14abf15SRobert Mustacchi  * given as physical addresses.
719*d14abf15SRobert Mustacchi  *
720*d14abf15SRobert Mustacchi  *
721*d14abf15SRobert Mustacchi  * @param pdev the device to use
722*d14abf15SRobert Mustacchi  * @param context the DMAE context to use
723*d14abf15SRobert Mustacchi  * @param source_paddr the beginning of the source memory block
724*d14abf15SRobert Mustacchi  * @param dest_paddr the beginning of the destination memory
725*d14abf15SRobert Mustacchi  *                   block
726*d14abf15SRobert Mustacchi  * @param length the length (in DWORDS) of the block
727*d14abf15SRobert Mustacchi  *
728*d14abf15SRobert Mustacchi  * @return lm_status_t LM_STATUS_SUCCESS on success,
729*d14abf15SRobert Mustacchi  *         LM_STATUS_TIMEOUT if the operation did not finish in
730*d14abf15SRobert Mustacchi  *         reasonable time, some other failure value on failure.
731*d14abf15SRobert Mustacchi  */
732*d14abf15SRobert Mustacchi lm_status_t lm_dmae_copy_phys_buffer_unsafe(struct _lm_device_t* pdev, lm_dmae_context_t* context, lm_address_t source_paddr, lm_address_t dest_paddr, u16_t length);
733*d14abf15SRobert Mustacchi 
734*d14abf15SRobert Mustacchi #endif// _LM_DMAE_H
735