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