source: svn/newcon3bcm2_21bu/magnum/portinginterface/dma/7552/bdma_mem_priv.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 66.6 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bdma_mem_priv.c $
11 * $brcm_Revision: Hydra_Software_Devel/28 $
12 * $brcm_Date: 4/4/11 11:46p $
13 *
14 * Module Description:
15 *
16 *
17 * Revision History:
18 * $brcm_Log: /magnum/portinginterface/dma/7400/bdma_mem_priv.c $
19 *
20 * Hydra_Software_Devel/28   4/4/11 11:46p vanessah
21 * SWDTV-6186: 35233 DMA support
22 *
23 * Hydra_Software_Devel/27   3/21/11 6:37p vanessah
24 * SW7420-1431: support oflarge DMA descriptor list subset
25 *
26 * Hydra_Software_Devel/26   2/22/11 7:48a vanessah
27 * SW7550-670: add Sharf DMA support
28 *
29 * Hydra_Software_Devel/25   2/2/11 10:27a vanessah
30 * SW7550-670: add Sharf DMA support
31 *
32 * Hydra_Software_Devel/24   1/18/11 4:53p cdisc
33 * SW35125-56: adding 35125 BCHP precompile lines and removing 35125 stub
34 * functions
35 *
36 * Hydra_Software_Devel/23   12/21/10 6:24p vanessah
37 * SWBLURAY-23683:  Add DMA PortingInterface support for Blast (7640) chip
38 *
39 * Hydra_Software_Devel/22   11/22/10 4:01p pntruong
40 * SW7231-18: Fixed 7344 build errors.
41 *
42 * Hydra_Software_Devel/21   11/17/10 4:12p vanessah
43 * SW7231-18:  Add DMA support for 7231 7344 7346
44 *
45 * Hydra_Software_Devel/20   11/4/10 1:42p vanessah
46 * SW7552-14:  Add DMA PI support
47 *
48 * Hydra_Software_Devel/19   11/1/10 1:57p yuxiaz
49 * SW7358-15: Added DMA PI support on 7358.
50 *
51 * Hydra_Software_Devel/18   8/31/10 2:36p tdo
52 * SW7422-62: Add DMA PI
53 *
54 * Hydra_Software_Devel/17   8/17/10 12:16p vanessah
55 * SW7335-791:  After customer verification, problem solved. Merge to main
56 * line
57 *
58 * Hydra_Software_Devel/SW7335-791/1   8/4/10 10:15p vanessah
59 * SW7335-791:  DMA engine hangs when continuous descriptors using
60 * different scram modes
61 *
62 * Hydra_Software_Devel/16   4/6/10 11:46a syang
63 * SW7408-68: adopt new mem dma intr id
64 *
65 * Hydra_Software_Devel/15   2/11/10 11:37a syang
66 * SW35230-50: add 35230
67 *
68 * Hydra_Software_Devel/14   2/2/10 3:25p syang
69 * SW7408-68: remove bad BCHP_INT_ID_ name work around
70 *
71 * Hydra_Software_Devel/13   2/2/10 3:06p syang
72 * SW7408-68: add 7408 support
73 *
74 * Hydra_Software_Devel/12   12/1/09 11:53a rpan
75 * SW7468-19: Added support for 7468.
76 *
77 * Hydra_Software_Devel/11   8/19/09 4:46p syang
78 * PR 55545: add support for 7125.
79 *
80 * Hydra_Software_Devel/10   7/29/09 5:09p syang
81 * PR 55232: add 7340 support
82 *
83 * Hydra_Software_Devel/9   1/27/09 8:36p tdo
84 * PR51627: add VDC 7336 PI support
85 *
86 * Hydra_Software_Devel/8   11/26/08 10:08a syang
87 * PR 47762: add support for 7420
88 *
89 * Hydra_Software_Devel/7   9/26/08 10:51a syang
90 * PR  45212:  fix bus error with scratch reg for sharf dma
91 *
92 * Hydra_Software_Devel/6   8/20/08 4:10p syang
93 * PR 45212: clean up #define
94 *
95 * Hydra_Software_Devel/5   8/20/08 2:07p syang
96 * PR 45212: add msg print for debug
97 *
98 * Hydra_Software_Devel/4   7/31/08 10:45a syang
99 * PR 34606:  turn on auto_pend again
100 *
101 * Hydra_Software_Devel/3   7/30/08 11:53a syang
102 * PR 45128: fix ptr over-run caused by using BDMA_MemDmaEngine_eUnknown
103 * for engine handle array boundary
104 *
105 * Hydra_Software_Devel/2   7/11/08 3:45p syang
106 * PR 43729:  rm code for old crypto hw arch
107 *
108 * Hydra_Software_Devel/70   7/11/08 11:49a syang
109 * PR 43729:  make bdma.h chip independent
110 *
111 * Hydra_Software_Devel/69   5/28/08 5:14p syang
112 * PR 34606:  handle the dyn link failure when AUTO_PEND is supported and
113 * LAST bit in desc is not cleared
114 *
115 * Hydra_Software_Devel/68   5/28/08 12:34p syang
116 * PR 34606: clean LAST bit during dyn link even if AUTO_PEND supported;
117 * clean up
118 *
119 * Hydra_Software_Devel/67   5/19/08 1:59p syang
120 * PR 34606:  clean up
121 *
122 * Hydra_Software_Devel/66   5/19/08 11:48a syang
123 * PR 34606:  add validation for HW reg reading
124 *
125 * Hydra_Software_Devel/65   2/22/08 9:51a rpan
126 * PR39458: Initial work for bcm3556.
127 *
128 * Hydra_Software_Devel/64   2/21/08 1:38p rpan
129 * PR34854: Initial work for bcm3548.
130 *
131 * Hydra_Software_Devel/63   12/12/07 3:40p syang
132 * PR 31923: added auto-append support to PI
133 *
134 * Hydra_Software_Devel/62   12/11/07 10:55a syang
135 * PR 34606: more small clean up after big rewriting
136 *
137 * Hydra_Software_Devel/61   12/10/07 10:11a syang
138 * PR 34606: fix 3563 compile problem
139 *
140 * Hydra_Software_Devel/60   12/7/07 7:02p syang
141 * PR 34606:  fix 7405 compile error
142 *
143 * Hydra_Software_Devel/59   12/7/07 6:38p syang
144 * PR 34606: move SetCrypto to Tran level from Engine level for better
145 * sharing by threads of the same progress
146 *
147 * Hydra_Software_Devel/58   12/7/07 4:09p syang
148 * PR 34606: rewrite more than half of code to support hw sharing for
149 * kernel and user-mode sides
150 *
151 * Hydra_Software_Devel/57   11/20/07 10:50p tdo
152 * PR36882: Add dma PI support for 7335
153 *
154 * Hydra_Software_Devel/56   10/15/07 3:37p syang
155 * PR 35947: add "_isr" to call back func name
156 *
157 * Hydra_Software_Devel/55   10/15/07 11:58a syang
158 * PR 35040: coverity (RESOURCE_LEAK) fix
159 *
160 * Hydra_Software_Devel/54   10/15/07 11:44a yuxiaz
161 * PR35323: Added DMA support for 7325.
162 *
163 * Hydra_Software_Devel/53   5/8/07 3:40p yuxiaz
164 * PR29728: Basic DMA support for 7405-A0
165 *
166 * Hydra_Software_Devel/52   4/26/07 2:45p syang
167 * PR 28173: took off addr validation what is not easy to maintain after
168 * so many chips are added
169 *
170 * Hydra_Software_Devel/50   3/21/07 12:47p syang
171 * PR 28173: dyn link works now after fixing next_desc shift and status
172 * proc  tran loop break. fixed cur hw desc left shift
173 *
174 * Hydra_Software_Devel/49   3/20/07 1:25p syang
175 * PR 28171: clean up
176 *
177 * Hydra_Software_Devel/48   3/19/07 4:18p syang
178 * PR 28171: prepare to add sharf support
179 *
180 * Hydra_Software_Devel/47   3/16/07 3:23p syang
181 * PR 28173: add scatter-gather support
182 *
183 * Hydra_Software_Devel/46   3/16/07 12:31p syang
184 * PR 28173: add dynamic link support (not turn on yet)
185 *
186 * Hydra_Software_Devel/45   3/12/07 11:25a agin
187 * PR28616: Fix boundary conditions.
188 *
189 * Hydra_Software_Devel/44   3/7/07 4:27p tdo
190 * PR 26224:  Add support for 2nd MEM DMA for 7400B0
191 *
192 * Hydra_Software_Devel/43   3/7/07 3:08p yuxiaz
193 * PR 28167: Added DMA support for MEMC_2 on 7400.
194 *
195 * Hydra_Software_Devel/42   2/26/07 3:46p syang
196 * PR 23354: clean up code to get rid of too many #if
197 *
198 * Hydra_Software_Devel/41   2/5/07 4:42p syang
199 * PR 23354: allow mem addr in mem_1; cleanup cip specific code section
200 * macro usage
201 *
202 * Hydra_Software_Devel/40   1/8/07 5:35p syang
203 * PR 16059:  remove some unneeded src/dst overlapped restriction again
204 * (why the old code got back?).
205 *
206 * Hydra_Software_Devel/39   1/8/07 12:53p tdo
207 * PR 26224:  Add second DMA MEM engine support for 7400 B0
208 *
209 * Hydra_Software_Devel/38   11/7/06 12:17p syang
210 * PR 16059:  remove some unneeded src/dst overlapped restriction
211 *
212 * Hydra_Software_Devel/37   10/16/06 12:35p syang
213 * PR 23354: add 3563 support
214 *
215 * Hydra_Software_Devel/36   10/3/06 7:02p albertl
216 * PR23518:  Added 7440 support.
217 *
218 * Hydra_Software_Devel/35   10/3/06 4:00p syang
219 * PR 24634: replace critical section with private mutex for
220 * mem/pci_dma_handle create/destroy.
221 *
222 * Hydra_Software_Devel/34   3/28/06 4:53p syang
223 * PR 20398: remove un-needed blocksize allignment check
224 *
225 * Hydra_Software_Devel/33   3/23/06 12:41p syang
226 * PR 19670: added support for 7438
227 *
228 * Hydra_Software_Devel/32   2/10/06 5:29p syang
229 * PR 19425: fix a typo for 3560 case
230 *
231 * Hydra_Software_Devel/31   2/3/06 3:06p syang
232 * PR 19425: 1). added 7400 support; 2). change to use BCHP_VER
233 *
234 * Hydra_Software_Devel/30   1/23/06 11:52a mphillip
235 * PR18165: Update for C3
236 *
237 * Hydra_Software_Devel/29   7/14/05 5:12p syang
238 * PR 16059: updated 7401 crypto configure
239 *
240 * Hydra_Software_Devel/28   7/8/05 3:43p nissen
241 * PR 15575: Added BDMA_Mem_Transfer() entry point function to do memory
242 * transfers with less function call overhead.
243 *
244 * Hydra_Software_Devel/27   7/8/05 2:28p nissen
245 * PR 15679: Fixed problem with getting dma status.
246 *
247 * Hydra_Software_Devel/26   7/5/05 5:55p nissen
248 * PR 16059: Added support for building for the 7401 A0.
249 *
250 * Hydra_Software_Devel/25   6/24/05 10:37a syang
251 * PR 14720: added c2 support
252 *
253 * Hydra_Software_Devel/24   5/26/05 4:53p syang
254 * PR 15119: a typo in last checkin
255 *
256 * Hydra_Software_Devel/23   5/26/05 4:39p syang
257 * PR 15119: separate CryptAlg def for 7038-Cx from 3560.
258 *
259 * Hydra_Software_Devel/22   5/18/05 10:53p nissen
260 * PR 15107: Removed word alignment check for src and dst addresses for
261 * mem-to-mem DMA.
262 *
263 * Hydra_Software_Devel/21   5/18/05 9:48p nissen
264 * PR 14516: Added support for setting ENC_DEC_INIT and removed word
265 * alignment check of TRANSFER_SIZE.
266 *
267 * Hydra_Software_Devel/20   5/18/05 9:04p nissen
268 * PR 15312: Added support for big endian memory transfers.
269 *
270 * Hydra_Software_Devel/19   4/20/05 1:10p syang
271 * PR 14420: include bchp_int_id_xpt_int.h for 3560, to get mem dma L2
272 * intr id.
273 *
274 * Hydra_Software_Devel/18   8/4/04 4:38p syang
275 * PR 12172: fix warning with release build
276 *
277 * Hydra_Software_Devel/17   7/8/04 10:23a syang
278 * PR 11822: Added support of crypt alg 5
279 *
280 * Hydra_Software_Devel/16   5/24/04 5:59p jasonh
281 * PR 11189: Merge down from B0 to main-line
282 *
283 * Hydra_Software_Devel/Refsw_Devel_7038_B0/3   5/20/04 1:49p syang
284 * PR 11161: avoid to use customer name in crypt alg name
285 *
286 * Hydra_Software_Devel/Refsw_Devel_7038_B0/2   5/6/04 2:23p syang
287 * PR 10685:  In order to support new crypt features of B0, changed DesSel
288 * to CryptAlg,  expanded Key sel, added MODE_SEL and ENC_DEC_INIT
289 * setting (changed to use mode 1, mode 0 is not used again),
290 *
291 * Hydra_Software_Devel/Refsw_Devel_7038_B0/1   4/20/04 11:35a syang
292 * PR 10685: updated HW register reading / setting to B0, added
293 * ClearCallback before EnableCallback.
294 *
295 * Hydra_Software_Devel/15   2/6/04 4:48p syang
296 * PR 9655: added low 4 bits cutting for "next desc" setting
297 *
298 * Hydra_Software_Devel/14   2/4/04 3:03p syang
299 * PR 9608: 1). added init for hMemDma / hPciDma of Channel, hDma of
300 * MemDma / PciDma and hChannel of Queue; 2). split CallBackFunc type def
301 * to mem and pci versions; 3). fixed typo in TranHandle def; 4).leave
302 * critical section before calling BINT func; 5). fixed a bug with
303 * nextDesc in Desc info setting; 6). use wake to start dma as in sleep
304 * mode; 7). corrected typo in the asserts of Queue_CreateTran.
305 *
306 * Hydra_Software_Devel/13   12/29/03 3:59p marcusk
307 * PR9117: Updated with changes required to support interrupt ids rather
308 * than strings.
309 *
310 * Hydra_Software_Devel/12   11/19/03 6:54p syang
311 * added desc addr conv from virtual to mem bus offset
312 *
313 * Hydra_Software_Devel/11   10/23/03 6:17p syang
314 * to make linux comipler silent
315 *
316 * Hydra_Software_Devel/10   10/23/03 4:20p syang
317 * adjusted sub-module implementaion overview
318 *
319 * Hydra_Software_Devel/9   10/23/03 3:15p syang
320 * added real pci dma implementation
321 *
322 * Hydra_Software_Devel/8   10/23/03 11:07a syang
323 * first time checking after resolving comipling errors
324 *
325 * Hydra_Software_Devel/7   10/21/03 4:44p syang
326 * added hMemDma existing check in BDMA_Mem_Create
327 *
328 * Hydra_Software_Devel/6   10/20/03 12:16p syang
329 * added Tran_Reset
330 *
331 * Hydra_Software_Devel/5   10/17/03 4:14p syang
332 * did clean ups (blockinfo set checking is moved to queue, the info
333 * passed in setdescriptor's parameters are further shrinked, some
334 * function descriptions are added.
335 *
336 * Hydra_Software_Devel/4   10/15/03 1:57p syang
337 * added implementation of BDMA_P_Mem_SendToHw, BDMA_P_Mem_ReadHwStatus,
338 * and did clean up for the usage of them.
339 *
340 * Hydra_Software_Devel/3   10/14/03 8:02p syang
341 * updated the implementation to use TranHandle (rather than TranId)
342 *
343 * Hydra_Software_Devel/2   10/10/03 4:10p syang
344 * added function BDMA_P_Mem_Create, BDMA_P_Mem_Destroy,
345 * BDMA_P_Mem_SetSwapMode, BDMA_P_Mem_SetCrypt,
346 * BDMA_P_Mem_MultiBlocks_StartAndWait, BDMA_P_Mem_OneBlock_StartAndWait,
347 * BDMA_P_Mem_DoneCallBack_isr, BDMA_P_Mem_SetBlockDesc
348 *
349 * Hydra_Software_Devel/1   9/25/03 7:01p syang
350 * init version, from scratch
351 *
352 ***************************************************************************/
353
354#include "bdma_mem_priv.h"
355#include "bkni.h"
356#if (BDMA_P_SUPPORT_MEM_DMA_ENGINE > 0)
357#if (BDMA_P_SUPPORT_MEM_DMA_ENGINE>=2)
358#include "bchp_mem_dma_1.h"
359#endif
360#if (BDMA_P_SUPPORT_MEM_DMA_REG_NAME_i!=0)
361#include "bchp_mem_dma_0.h"
362#else
363#include "bchp_mem_dma.h"
364#endif
365#endif
366
367#include "bchp_common.h"
368#include "bchp_hif_intr2.h"
369
370#if (BCHP_CHIP==7400)
371#if (BCHP_VER>=BCHP_VER_B0)
372#include "bchp_int_id_memc16_gfx_l2.h"
373#else
374#include "bchp_int_id_gfx_l2.h"
375#endif
376#elif (BCHP_CHIP==7420) || (BCHP_CHIP==7125) || (BCHP_CHIP==7340) || (BCHP_CHIP==7342) || \
377      (BCHP_CHIP==7468) || (BCHP_CHIP==7422) || (BCHP_CHIP==7425) || \
378      (BCHP_CHIP==7358) || (BCHP_CHIP==7552) || \
379      (BCHP_CHIP==7231) || (BCHP_CHIP==7344) || (BCHP_CHIP==7346) || (BCHP_CHIP==7640)
380#include "bchp_int_id_bsp_control_intr2.h"
381#elif (BCHP_CHIP==7405)
382#include "bchp_int_id_memc16_gfx_l2.h"
383#elif (BCHP_CHIP==7325) || (BCHP_CHIP==7335) || (BCHP_CHIP==7336)
384#include "bchp_int_id_graphics_l2.h"
385#elif (BCHP_CHIP==7440) || (BCHP_CHIP==3563) || (BCHP_CHIP==7408) || (BCHP_CHIP == 35230) || (BCHP_CHIP == 35125) || (BCHP_CHIP == 35233)
386#include "bchp_int_id_xpt_bus_if.h"
387#elif (BCHP_CHIP == 3548) || (BCHP_CHIP == 3556)
388#include "bchp_int_id_gfx_l2.h"
389#else
390#include "bchp_int_id_hif_intr2.h"
391#endif
392
393BDBG_MODULE(BDMA_MEM_PRIV);
394
395
396/***************************************************************************
397 *
398 * Utility functions used by BDMA
399 *
400 ***************************************************************************/
401/*--------------------------------------------------------------------------
402 * To be called by BDMA API func before taking real action, to get dma mutex
403 * WITH block, ideally for user mode
404 */
405BERR_Code BDMA_P_Mem_AcquireMutex(
406        BDMA_Mem_Handle          hMemDma,
407        BKNI_MutexHandle        *phMutex )
408{
409        BDMA_P_Mem_Context  * pMemDma;
410        BERR_Code  eResult = BERR_SUCCESS;
411
412        BDMA_P_MEM_GET_CONTEXT(hMemDma, pMemDma);
413        if ( NULL == pMemDma )
414        {
415                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
416                goto BDMA_P_Done_Mem_AcquireMutex;
417        }
418
419        BDBG_ASSERT( NULL != phMutex );
420        *phMutex = pMemDma->hDma->hMutex;
421
422        /* hMemDma passed the magic check, we trust every thing pointed by it now */
423        eResult = BKNI_AcquireMutex(pMemDma->hDma->hMutex);
424
425  BDMA_P_Done_Mem_AcquireMutex:
426        return BERR_TRACE(eResult);
427}
428
429
430/***************************************************************************
431 *
432 * Static tool functions used in this file
433 *
434 ***************************************************************************/
435
436/*--------------------------------------------------------------------------
437 * To be called to get MemDma context ptr from a Tran ptr. The MemDma handle
438 * from the Tran record is validated by black magic, and the Engine Id is
439 * checked to make sure the Tran was really created with MemDma handle
440 */
441BERR_Code BDMA_P_Mem_GetMemDmaPtrFromTran_isr(
442        BDMA_P_QueueEntry *    pTran,
443        BDMA_P_Mem_Context **  ppMemDma )
444{
445        /* assert para from our private code */
446        BDBG_ASSERT( NULL != pTran );
447        BDBG_ASSERT( NULL != ppMemDma );
448
449        *ppMemDma = (BDMA_P_Mem_Context *) BDMA_P_Queue_GetEngine_isr(pTran->hQueue);
450
451        if (NULL != *ppMemDma)
452                return BERR_SUCCESS;
453        else
454                return BERR_TRACE(BERR_INVALID_PARAMETER);
455}
456
457#if BDMA_P_SUPPORT_MEM_DMA_ENGINE
458/*--------------------------------------------------------------------------
459 * static array for mapping cryptmode enum to HW value
460 */
461static uint32_t s_ulCryptMode[] =
462{
463        0,    /* BDMA_CryptMode_eNoCrypt */
464        1,    /* BDMA_CryptMode_eBlock */
465        2,    /* BDMA_CryptMode_eMpeg */
466        3,    /* BDMA_CryptMode_eDirecTv */
467};
468
469#define BDMA_P_MEM_NUM_WORDS_PER_DESC       8
470#define BDMA_P_MEM_LAST_BLK                 1
471#define BDMA_P_MEM_FIRE_INTR                1
472#define BDMA_P_MEM_MODE_SEL_1               2
473#define BDMA_P_MEM_MODE_1_DES_SEL           0
474#define BDMA_P_MEM_ENC_DEC_INIT_SET         1
475#define BDMA_P_MEM_ENC_DEC_INIT_UNSET       0
476#define BDMA_P_MEM_SG_ENABLE_SET            1
477#define BDMA_P_MEM_SG_ENABLE_UNSET          0
478#define BDMA_P_MEM_KEY_UNIT(a)              (a * BDMA_P_MEM_KEY_SIZE)  /* logic -> HW value */
479#define BDMA_P_MEM_LITTLE_ENDIAN
480#define BDMA_P_MEM_CRYPT_MEM_ALIGN_MASK     0x7
481#define BDMA_P_MEM_WORD_ALIGN_MASK          0x3
482/*--------------------------------------------------------------------------
483 * To be called to set block info for a block, it does validate the block
484 * info provided
485 */
486BERR_Code BDMA_P_Mem_SetBlockDesc_isr(
487        BDMA_P_Mem_Context *        pMemDma,
488        BDMA_P_QueueEntry *         pTran,
489        BDMA_P_QueueEntry *         pBlock,
490        bool                        bCachedDscrp,
491        uint32_t                    ulDstBusAddr,
492        uint32_t                    ulSrcBusAddr,
493        uint32_t                    ulBlockSize,
494        bool                        bCryptInit )
495{
496        BERR_Code  eResult = BERR_SUCCESS;
497        BDMA_CryptMode  eCryptMode;
498        uint32_t *pulDesc;
499        uint32_t  ulCryptMode, ulCryptInit, ulKeyUnit;
500        uint32_t  ulSgEnable, ulSgStartEnd;
501        uint32_t  ulSwapMode, ulReadEndian, ulNextDescAddr;
502
503        /* assert para from our private code */
504        BDBG_ASSERT( NULL != pMemDma );
505        BDBG_ASSERT( NULL != pTran );
506        BDBG_ASSERT( NULL != pBlock );
507
508        if ( ulBlockSize>BDMA_P_MEM_MAX_BLOCK_SIZE )
509        {
510                eResult = BERR_TRACE(BDMA_ERR_SIZE_OUT_RANGE);
511                goto BDMA_P_Done_Mem_SetBlockDesc;
512        }
513        if ( (ulSrcBusAddr < ulDstBusAddr) &&
514                 (ulDstBusAddr < ulSrcBusAddr+ulBlockSize) )
515        {
516                eResult = BERR_TRACE(BDMA_ERR_OVERLAP);
517                goto BDMA_P_Done_Mem_SetBlockDesc;
518        }
519
520        /* set descriptor: only the last block needs to set INTR_ENABLE and LAST bits,
521         * and the INTR_ENABLE is always set, on matter it is a sync or async Tran. */
522
523        pulDesc = (bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
524
525        /* set desc word 0 */
526        *(pulDesc  ) =
527                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD0, READ_ADDR,    ulSrcBusAddr );
528
529        /* set desc word 1 */
530        *(pulDesc+1) =
531                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD1, WRITE_ADDR,     ulDstBusAddr );
532
533        /* set desc word 2 */
534        *(pulDesc+2) =
535                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, TRANSFER_SIZE, ulBlockSize );
536
537        /* set desc word 3 */
538        ulNextDescAddr = (pBlock + 1)->ulDescPhysAddr >>
539                BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT;
540        ulReadEndian = (BDMA_Endian_eLittle == pMemDma->eReadEndian)?
541                BCHP_MEM_DMA_DESC_WORD3_READ_ENDIAN_MODE_LITTLE_ENDIAN:
542                BCHP_MEM_DMA_DESC_WORD3_READ_ENDIAN_MODE_BIG_ENDIAN;
543        ulSwapMode =
544                ( (BDMA_SwapMode_eNoSwap == pMemDma->eSwapMode)?
545                  (BCHP_MEM_DMA_DESC_WORD3_WRITE_ENDIAN_XLATE_MODE_WORD_ALIGNED):
546                  ((BDMA_SwapMode_e0123To2301==pMemDma->eSwapMode)?
547                   (BCHP_MEM_DMA_DESC_WORD3_WRITE_ENDIAN_XLATE_MODE_HALF_WORD_ALIGNED):
548                   (BCHP_MEM_DMA_DESC_WORD3_WRITE_ENDIAN_XLATE_MODE_BYTE_ALIGNED)) );
549        *(pulDesc+3) =
550                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR,          ulNextDescAddr )      |
551                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, READ_ENDIAN_MODE,        ulReadEndian )        |
552                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, WRITE_ENDIAN_XLATE_MODE, ulSwapMode );
553
554        /* set desc word 4 */
555        ulCryptInit = (bCryptInit) ?
556                BDMA_P_MEM_ENC_DEC_INIT_SET : BDMA_P_MEM_ENC_DEC_INIT_UNSET;
557        if (pMemDma->bCryptoSetInEngine)
558        {
559                /* obsolete, for compatibility only */
560                eCryptMode = (pMemDma->eCryptMode < BDMA_CryptMode_eInvalid)?
561                        pMemDma->eCryptMode : BDMA_CryptMode_eNoCrypt;
562                ulCryptMode = s_ulCryptMode[eCryptMode];
563                ulKeyUnit = BDMA_P_MEM_KEY_UNIT(pMemDma->ulKeySlot);
564                ulSgEnable = (pMemDma->bSgEnable) ?
565                        BDMA_P_MEM_SG_ENABLE_SET : BDMA_P_MEM_SG_ENABLE_UNSET;
566        }
567        else
568        {
569                eCryptMode = (pTran->eCryptMode < BDMA_CryptMode_eInvalid)?
570                        pTran->eCryptMode : BDMA_CryptMode_eNoCrypt;
571                ulCryptMode = s_ulCryptMode[eCryptMode];
572                ulKeyUnit = BDMA_P_MEM_KEY_UNIT(pTran->ulKeySlot);
573                ulSgEnable = (pTran->bSgEnable) ?
574                        BDMA_P_MEM_SG_ENABLE_SET : BDMA_P_MEM_SG_ENABLE_UNSET;
575        }
576#if (BDMA_P_SUPPORT_MEM_DMA_SCATTER_GATHER > 0)
577        ulSgStartEnd = *(pulDesc+4) & (
578                BCHP_MASK( MEM_DMA_DESC_WORD4, SG_SCRAM_START ) |
579                BCHP_MASK( MEM_DMA_DESC_WORD4, SG_SCRAM_END ));
580        *(pulDesc+4) =
581                ulSgStartEnd |
582                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, SG_ENABLE,     ulSgEnable )  |
583                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, ENC_DEC_INIT,  ulCryptInit ) |
584                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, MODE_SEL,      ulCryptMode ) |
585                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, KEY_SELECT,    ulKeyUnit );
586#else
587        BSTD_UNUSED(ulSgStartEnd);
588        *(pulDesc+4) =
589                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, ENC_DEC_INIT,  ulCryptInit ) |
590                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, MODE_SEL,      ulCryptMode ) |
591                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, KEY_SELECT,    ulKeyUnit );
592#endif
593
594        /*
595        *(pulDesc+5) = 0;
596        *(pulDesc+6) = 0;
597        *(pulDesc+7) = 0;
598        */
599
600  BDMA_P_Done_Mem_SetBlockDesc:
601        return eResult;
602}
603
604#define BDMA_P_SG_START_SHIFT   0
605#define BDMA_P_SG_END_SHIFT     1
606#define BDMA_P_SG_START_MASK    (1<<BDMA_P_SG_START_SHIFT)
607#define BDMA_P_SG_END_MASK      (1<<BDMA_P_SG_END_SHIFT)
608
609/*--------------------------------------------------------------------------
610 * To be called to mark / unmark a block as scatter-gather start / end point
611 */
612static BERR_Code BDMA_P_Mem_SetSgStartEndDesc_isr(
613        BDMA_P_QueueEntry *         pBlock,
614        bool                        bCachedDscrp,
615        bool                        bSgStart,
616        bool                        bSgEnd )
617{
618#if (BDMA_P_SUPPORT_MEM_DMA_SCATTER_GATHER > 0)
619        uint32_t *pulDesc;
620        uint32_t  ulWord4, ulSgStart, ulSgEnd;
621
622        pulDesc = (bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
623
624        ulWord4 = *(pulDesc+4) & ~(
625                BCHP_MASK( MEM_DMA_DESC_WORD4, SG_SCRAM_START ) |
626                BCHP_MASK( MEM_DMA_DESC_WORD4, SG_SCRAM_END ));
627        ulSgStart = (bSgStart) ? 1 : 0;
628        ulSgEnd = (bSgEnd) ? 1 : 0;
629
630        *(pulDesc+4) =
631                ulWord4 |
632                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, SG_SCRAM_START, ulSgStart ) |
633                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD4, SG_SCRAM_END,   ulSgEnd );
634
635        pBlock->ulSgStartStop =
636                (ulSgStart<<BDMA_P_SG_START_SHIFT) | (ulSgEnd << BDMA_P_SG_END_SHIFT);
637
638#else
639        BSTD_UNUSED(pBlock);
640        BSTD_UNUSED(bCachedDscrp);
641        BSTD_UNUSED(bSgStart);
642        BSTD_UNUSED(bSgEnd);
643#endif
644        return BERR_SUCCESS;
645}
646
647#ifndef BCHP_MEM_DMA_0_FIRST_DESC
648#define BCHP_MEM_DMA_0_FIRST_DESC                BCHP_MEM_DMA_FIRST_DESC
649#define BCHP_MEM_DMA_0_FIRST_DESC_ADDR_SHIFT     BCHP_MEM_DMA_FIRST_DESC_ADDR_SHIFT
650#define BCHP_MEM_DMA_0_CTRL                      BCHP_MEM_DMA_CTRL
651#define BCHP_MEM_DMA_0_CTRL_RUN_SHIFT            BCHP_MEM_DMA_CTRL_RUN_SHIFT
652#define BCHP_MEM_DMA_0_WAKE_CTRL                 BCHP_MEM_DMA_WAKE_CTRL
653#define BCHP_MEM_DMA_0_WAKE_CTRL_WAKE_MODE_SHIFT BCHP_MEM_DMA_WAKE_CTRL_WAKE_MODE_SHIFT
654#define BCHP_MEM_DMA_0_WAKE_CTRL_WAKE_SHIFT      BCHP_MEM_DMA_WAKE_CTRL_WAKE_SHIFT
655#define BCHP_MEM_DMA_0_STATUS                    BCHP_MEM_DMA_STATUS
656#define BCHP_MEM_DMA_0_STATUS_DMA_STATUS_MASK    BCHP_MEM_DMA_STATUS_DMA_STATUS_MASK
657#define BCHP_MEM_DMA_0_STATUS_DMA_STATUS_SHIFT   BCHP_MEM_DMA_STATUS_DMA_STATUS_SHIFT
658#define BCHP_MEM_DMA_0_STATUS_DMA_STATUS_Idle    BCHP_MEM_DMA_STATUS_DMA_STATUS_Idle
659#define BCHP_MEM_DMA_0_STATUS_DMA_STATUS_Busy    BCHP_MEM_DMA_STATUS_DMA_STATUS_Busy
660#define BCHP_MEM_DMA_0_STATUS_DMA_STATUS_Sleep   BCHP_MEM_DMA_STATUS_DMA_STATUS_Sleep
661#define BCHP_MEM_DMA_0_CUR_DESC                  BCHP_MEM_DMA_CUR_DESC
662#define BCHP_MEM_DMA_0_CUR_DESC_ADDR_MASK        BCHP_MEM_DMA_CUR_DESC_ADDR_MASK
663#define BCHP_MEM_DMA_0_CUR_DESC_ADDR_SHIFT       BCHP_MEM_DMA_CUR_DESC_ADDR_SHIFT
664#define BCHP_MEM_DMA_0_SCRATCH                   BCHP_MEM_DMA_SCRATCH
665#endif
666
667#ifndef BCHP_INT_ID_MEM_DMA_0_INTR
668#ifdef BCHP_INT_ID_MEM_DMA_INTR
669#define BCHP_INT_ID_MEM_DMA_0_INTR               BCHP_INT_ID_MEM_DMA_INTR
670#elif defined BCHP_INT_ID_XPT_BUS_IF_MEM_DMA_INTR
671#define BCHP_INT_ID_MEM_DMA_0_INTR               BCHP_INT_ID_XPT_BUS_IF_MEM_DMA_INTR
672#elif defined BCHP_INT_ID_BSP_CONTROL_INTR2_MEM_DMA_0_INTR
673#define BCHP_INT_ID_MEM_DMA_0_INTR               BCHP_INT_ID_BSP_CONTROL_INTR2_MEM_DMA_0_INTR
674#else
675#define BCHP_INT_ID_MEM_DMA_0_INTR               BCHP_INT_ID_MEM_DMA_INT
676#endif
677#endif
678
679#define BDMA_P_MEM_STATUS_IDLE            BCHP_MEM_DMA_0_STATUS_DMA_STATUS_Idle
680#define BDMA_P_MEM_STATUS_BUSY            BCHP_MEM_DMA_0_STATUS_DMA_STATUS_Busy
681#define BDMA_P_MEM_STATUS_SLEEP           BCHP_MEM_DMA_0_STATUS_DMA_STATUS_Sleep
682#define BDMA_P_MEM_WAKE_FROM_1ST_DESC     1
683#define BDMA_P_MEM_WAKE_FROM_LAST_DESC    0
684#define BDMA_P_MEM_WAKE_UP                1
685#define BDMA_P_MEM_RUN_START              1
686
687/*--------------------------------------------------------------------------
688 * To be called to modify the last act block's desc to work as last block,
689 * and to flush cached descriptors
690 */
691static BERR_Code BDMA_P_Mem_Tran_PrepareStart_isr(
692        BDMA_P_QueueEntry *      pTran,
693        BDMA_P_QueueHandle       hQueue,
694        BMEM_Handle              hMemory,
695        uint32_t                 ulNumActBlocks,  /* new NumActBlocks */
696        bool  *                  pbSgOpen )
697{
698        BDMA_P_QueueContext * pQueue;
699        BDMA_P_QueueEntry *pBlock;
700        uint32_t *pulDesc;
701        uint32_t  ulNextOffset;
702        uint32_t  ulWord;
703        volatile uint32_t  ulCheck;
704#if ((BDMA_P_CHECK_NEXT_DESC) && (BDBG_DEBUG_BUILD)) || \
705        ((BDMA_P_CHECK_SCATTER_GATHER) && (BDBG_DEBUG_BUILD))
706        int iLoopCntr;
707#endif
708
709        BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue );
710        BDBG_ASSERT( NULL != pQueue );
711
712        /* in the case of re-use, the previous "last act block" might have wrong NEXT_DESC */
713        if ((ulNumActBlocks != pTran->ulNumActBlocks) &&
714                (0 < pTran->ulNumActBlocks))
715        {
716                pBlock = pTran + (pTran->ulNumActBlocks - 1);
717                pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
718
719                *(pulDesc+2) &= ~(
720#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
721                        BCHP_MASK(MEM_DMA_DESC_WORD2, AUTO_APPEND) |
722#endif
723                        BCHP_MASK(MEM_DMA_DESC_WORD2, INTR_ENABLE) |
724                        BCHP_MASK(MEM_DMA_DESC_WORD2, LAST));
725
726                ulNextOffset =
727                        (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT;
728                ulWord = *(pulDesc+3) & ~(BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR));
729                *(pulDesc+3) = ulWord |
730                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR, ulNextOffset );
731        }
732
733        /* modify new "last act block" desc */
734        pBlock = pTran + (ulNumActBlocks - 1);
735        pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
736#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
737        ulWord = *(pulDesc+2) & ~(
738                BCHP_MASK(MEM_DMA_DESC_WORD2, AUTO_APPEND));
739        *(pulDesc+2) = ulWord | (
740                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, INTR_ENABLE,   BDMA_P_MEM_FIRE_INTR ) |
741                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, LAST,          BDMA_P_MEM_LAST_BLK ));
742#else
743        *(pulDesc+2) |= (
744                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, INTR_ENABLE,   BDMA_P_MEM_FIRE_INTR ) |
745                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, LAST,          BDMA_P_MEM_LAST_BLK ));
746#endif
747        *(pulDesc+3) &= ~(
748                BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR));
749
750        *pbSgOpen = ((pTran->bSgEnable) &&
751                                 (0 == (BDMA_P_SG_END_MASK & pBlock->ulSgStartStop)));
752
753#if (BDMA_P_CHECK_NEXT_DESC) && (BDBG_DEBUG_BUILD)
754        pBlock = pTran;
755        for ( iLoopCntr = 0; iLoopCntr < (int) ulNumActBlocks; iLoopCntr++ )
756        {
757                uint32_t ulSeeNextOffset;
758
759                ulNextOffset =
760                        (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT;
761                pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
762                ulSeeNextOffset = BCHP_GET_FIELD_DATA(*(pulDesc+3), MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR);
763
764                if ((ulNextOffset != ulSeeNextOffset) ||
765                        (false == pBlock->bBlockInfoSet))
766                {
767                        BDBG_ASSERT((ulNextOffset == ulSeeNextOffset) ||
768                                                (false == pBlock->bBlockInfoSet));
769                        return BERR_TRACE(BDMA_ERR_BLOCK_INFO_UNSET);
770                }
771        }
772#endif
773
774#if (BDMA_P_CHECK_SCATTER_GATHER) && (BDBG_DEBUG_BUILD)
775        /* check scatter-gather setting */
776        if (pQueue->bSgOpenInQ || pTran->bSgEnable)
777        {
778                bool  bSgOpen;
779
780                /* we must be doing scatter-gather if we get in here */
781                bSgOpen = pQueue->bSgOpenInQ;
782                if ((false == pTran->bSgEnable) ||
783                        ((false == bSgOpen) && (false == pTran->bSgStartStopSet)))
784                {
785                        BDBG_ASSERT((false == pTran->bSgEnable) ||
786                                                ((false == bSgOpen) && (false == pTran->bSgStartStopSet)));
787                        return BERR_TRACE(BDMA_ERR_SG_MISMATCH);
788                }
789
790                pBlock = pTran;
791                for ( iLoopCntr = 0; iLoopCntr < (int) ulNumActBlocks; iLoopCntr++ )
792                {
793                        if (((false == bSgOpen) && (0 == (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))) ||
794                                ((true  == bSgOpen) && (0 != (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))))
795                        {
796                                BDBG_ASSERT(((false == bSgOpen) && (0 == (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))) ||
797                                                        ((true  == bSgOpen) && (0 != (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))));
798                                return BERR_TRACE(BDMA_ERR_SG_MISMATCH);
799                        }
800                        bSgOpen = (0 == (BDMA_P_SG_END_MASK & pBlock->ulSgStartStop));
801                        pBlock += 1;
802                }
803        }
804#endif
805
806        /* flush cached desc mem */
807        if (pTran->bCachedDscrp)
808                BMEM_FlushCache_isr(hMemory, pTran->pulCachedDescAddr,
809                                                        ulNumActBlocks * BDMA_P_MEM_NUM_WORDS_PER_DESC * 4);
810
811        /* read back with un-cached addr to ensure previous writing completes */
812        ulCheck = *((pTran + (ulNumActBlocks - 1))->pulDescAddr + 3);
813        if ((ulCheck & BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR)) != 0)
814        {
815                BDBG_ERR(("desc writing error with preparing start"));
816        }
817
818        return BERR_SUCCESS;
819}
820/*--------------------------------------------------------------------------
821 * To be called to modify the last act block's desc to work as last block,
822 * and to flush cached descriptors
823 */
824static BERR_Code BDMA_P_Mem_Tran_PrepareStartSubset_isr(
825        BDMA_P_QueueEntry *      pTran,
826        BDMA_P_QueueHandle       hQueue,
827        BMEM_Handle              hMemory,
828        uint32_t                 ulFirstBlock,
829        uint32_t                 ulNumActBlocks,  /* new NumActBlocks */
830        bool  *                  pbSgOpen )
831{
832        BDMA_P_QueueContext * pQueue;
833        BDMA_P_QueueEntry *pBlock;
834        uint32_t *pulDesc;
835        uint32_t  ulNextOffset, i=0;
836        uint32_t  ulWord;
837        volatile uint32_t  ulCheck;
838#if ((BDMA_P_CHECK_NEXT_DESC) && (BDBG_DEBUG_BUILD)) || \
839        ((BDMA_P_CHECK_SCATTER_GATHER) && (BDBG_DEBUG_BUILD))
840        int iLoopCntr;
841#endif
842        BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue );
843        BDBG_ASSERT( NULL != pQueue );
844
845        /* in the case of re-use, the previous "last act block" might have wrong NEXT_DESC */
846        if ((ulNumActBlocks != pTran->ulNumActBlocks) &&
847                (0 < pTran->ulNumActBlocks))
848        {
849                pBlock = pTran + pTran->ulFirstBlock + (pTran->ulNumActBlocks - 1);
850                pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
851
852                *(pulDesc+2) &= ~(
853#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
854                        BCHP_MASK(MEM_DMA_DESC_WORD2, AUTO_APPEND) |
855#endif
856                        BCHP_MASK(MEM_DMA_DESC_WORD2, INTR_ENABLE) |
857                        BCHP_MASK(MEM_DMA_DESC_WORD2, LAST));
858
859                ulNextOffset =
860                        (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT;
861                ulWord = *(pulDesc+3) & ~(BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR));
862                *(pulDesc+3) = ulWord |
863                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR, ulNextOffset );
864        }
865
866    pTran->ulFirstBlock = ulFirstBlock;
867        /* if re-use, the previous descriptor might have wrong setting */
868        pBlock = pTran + ulFirstBlock;
869        while (i<(ulNumActBlocks - 1))
870        {
871                pBlock = pTran + ulFirstBlock + i;
872                pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
873
874#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
875        ulWord = *(pulDesc+2) & ~(
876                BCHP_MASK(MEM_DMA_DESC_WORD2, AUTO_APPEND));
877
878                *(pulDesc+2) = ulWord & (
879                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, INTR_ENABLE,       BDMA_P_MEM_FIRE_INTR ) |
880                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, LAST,                      BDMA_P_MEM_LAST_BLK ));
881#else
882                *(pulDesc+2) &=~(
883                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, INTR_ENABLE,       BDMA_P_MEM_FIRE_INTR ) |
884                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, LAST,                      BDMA_P_MEM_LAST_BLK ));
885#endif
886
887                ulNextOffset = (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT;
888
889                *(pulDesc+3) |= BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR, ulNextOffset );
890                i++;
891        }
892
893        /* modify new "last act block" desc */
894        pBlock = pTran + ulFirstBlock + (ulNumActBlocks - 1);
895        pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
896#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
897        ulWord = *(pulDesc+2) & ~(
898                BCHP_MASK(MEM_DMA_DESC_WORD2, AUTO_APPEND));
899        *(pulDesc+2) = ulWord | (
900                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, INTR_ENABLE,   BDMA_P_MEM_FIRE_INTR ) |
901                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, LAST,          BDMA_P_MEM_LAST_BLK ));
902#else
903        *(pulDesc+2) |= (
904                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, INTR_ENABLE,   BDMA_P_MEM_FIRE_INTR ) |
905                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD2, LAST,          BDMA_P_MEM_LAST_BLK ));
906#endif
907        *(pulDesc+3) &= ~(
908                BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR));
909
910        *pbSgOpen = ((pTran->bSgEnable) &&
911                                 (0 == (BDMA_P_SG_END_MASK & pBlock->ulSgStartStop)));
912
913#if (BDMA_P_CHECK_NEXT_DESC) && (BDBG_DEBUG_BUILD)
914        pBlock = pTran;
915        for ( iLoopCntr = 0; iLoopCntr < (int) ulNumActBlocks; iLoopCntr++ )
916        {
917                uint32_t ulSeeNextOffset;
918
919                ulNextOffset =
920                        (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT;
921                pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr;
922                ulSeeNextOffset = BCHP_GET_FIELD_DATA(*(pulDesc+3), MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR);
923
924                if ((ulNextOffset != ulSeeNextOffset) ||
925                        (false == pBlock->bBlockInfoSet))
926                {
927                        BDBG_ASSERT((ulNextOffset == ulSeeNextOffset) ||
928                                                (false == pBlock->bBlockInfoSet));
929                        return BERR_TRACE(BDMA_ERR_BLOCK_INFO_UNSET);
930                }
931        }
932#endif
933
934#if (BDMA_P_CHECK_SCATTER_GATHER) && (BDBG_DEBUG_BUILD)
935        /* check scatter-gather setting */
936        if (pQueue->bSgOpenInQ || pTran->bSgEnable)
937        {
938                bool  bSgOpen;
939
940                /* we must be doing scatter-gather if we get in here */
941                bSgOpen = pQueue->bSgOpenInQ;
942                if ((false == pTran->bSgEnable) ||
943                        ((false == bSgOpen) && (false == pTran->bSgStartStopSet)))
944                {
945                        BDBG_ASSERT((false == pTran->bSgEnable) ||
946                                                ((false == bSgOpen) && (false == pTran->bSgStartStopSet)));
947                        return BERR_TRACE(BDMA_ERR_SG_MISMATCH);
948                }
949
950                pBlock = pTran;
951                for ( iLoopCntr = 0; iLoopCntr < (int) ulNumActBlocks; iLoopCntr++ )
952                {
953                        if (((false == bSgOpen) && (0 == (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))) ||
954                                ((true  == bSgOpen) && (0 != (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))))
955                        {
956                                BDBG_ASSERT(((false == bSgOpen) && (0 == (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))) ||
957                                                        ((true  == bSgOpen) && (0 != (BDMA_P_SG_START_MASK & pBlock->ulSgStartStop))));
958                                return BERR_TRACE(BDMA_ERR_SG_MISMATCH);
959                        }
960                        bSgOpen = (0 == (BDMA_P_SG_END_MASK & pBlock->ulSgStartStop));
961                        pBlock += 1;
962                }
963        }
964#endif
965
966        /* flush cached desc mem */
967        if (pTran->bCachedDscrp)
968                BMEM_FlushCache_isr(hMemory, pTran->pulCachedDescAddr,
969                                                        ulNumActBlocks * BDMA_P_MEM_NUM_WORDS_PER_DESC * 4);
970
971        /* read back with un-cached addr to ensure previous writing completes */
972        ulCheck = *((pTran + ulFirstBlock + (ulNumActBlocks - 1))->pulDescAddr + 3);
973        if ((ulCheck & BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR)) != 0)
974        {
975                BDBG_ERR(("desc writing error with preparing start"));
976        }
977
978        return BERR_SUCCESS;
979}
980/*--------------------------------------------------------------------------
981Callback from base-module queue to wait till next descriptor safe to send to HW
982*/
983static void BDMA_P_Mem_SafeSendToHw_isr(
984                                                                                BDMA_P_QueueHandle      hQueue,
985                                                                                BDMA_P_HwStatus*        peHwStatus
986                                                                                )
987{
988        BDMA_P_QueueEntry * pLastTran;
989        bool  bAppendable = true;
990        uint32_t   *pulNewDesc;
991        uint32_t  ulNewDescPhysAddr;
992        uint32_t  *pulLastDesc;
993        uint32_t  eStatus = (uint32_t)(*peHwStatus);
994        BDMA_P_Mem_Context *pMemDma;
995        BREG_Handle  hRegister;
996        uint32_t   ulRegValue;
997        uint32_t ulNewDesc4   = 0, ulLastDesc4   = 0;
998        uint32_t ulNewEncry   = 0, ulLastEncry   = 0;
999        uint32_t ulNewModeSel = 0, ulLastModeSel = 0;
1000        uint32_t ulNewKeySel  = 0, ulLastKeySel  = 0;
1001        BDMA_P_QueueContext * pQueue;
1002
1003
1004        BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue );
1005
1006
1007        if (NULL == pQueue->pHeadTranInQ)
1008                return;
1009
1010        /* 1: Compare whether the descriptor in HW is different from the one to send*/
1011
1012        /* send Trans queued in SW into HW */
1013        pLastTran = pQueue->pTailTranInHw;
1014        ulNewDescPhysAddr = pQueue->pHeadTranInQ->ulDescPhysAddr;
1015
1016    pulNewDesc = pQueue->pHeadTranInQ->pulDescAddr;
1017
1018        ulNewDesc4 = *(pulNewDesc+4);
1019
1020        ulNewEncry      = BCHP_GET_FIELD_DATA(ulNewDesc4, MEM_DMA_DESC_WORD4, SG_SCRAM_START);
1021        ulNewModeSel = BCHP_GET_FIELD_DATA(ulNewDesc4, MEM_DMA_DESC_WORD4, MODE_SEL);
1022        ulNewKeySel     = BCHP_GET_FIELD_DATA(ulNewDesc4, MEM_DMA_DESC_WORD4, KEY_SELECT);
1023
1024
1025
1026
1027
1028        if(pLastTran)
1029        {
1030                pulLastDesc = (pLastTran + (pLastTran->ulNumActBlocks - 1))->pulDescAddr;
1031                ulLastDesc4 = *(pulLastDesc + 4);
1032                ulLastEncry      = BCHP_GET_FIELD_DATA(ulLastDesc4, MEM_DMA_DESC_WORD4, SG_SCRAM_START);
1033                ulLastModeSel = BCHP_GET_FIELD_DATA(ulLastDesc4, MEM_DMA_DESC_WORD4, MODE_SEL);
1034                ulLastKeySel  = BCHP_GET_FIELD_DATA(ulLastDesc4, MEM_DMA_DESC_WORD4, KEY_SELECT);
1035                bAppendable = (ulLastEncry == ulNewEncry)&&
1036                        (ulLastModeSel==ulNewModeSel)&&
1037                        (ulLastKeySel==ulNewKeySel);
1038
1039        }
1040
1041        /* 2: Safe to send the next descriptor if the continuous two are the same*/
1042        if(bAppendable)
1043                return;
1044
1045        /* 3: Safe to send the next descriptor or the previous in HW is done*/
1046
1047        pMemDma = (BDMA_P_Mem_Context *)(pQueue->hEngine);
1048        hRegister = BDMA_P_GetRegisterHandle(pMemDma->hDma);
1049        while (eStatus ==BDMA_P_MEM_STATUS_BUSY)
1050        {
1051                /* read CUR_DESC after STATUS, --> less chance to get wrong CUR_DESC?  */
1052                ulRegValue = BREG_Read32( hRegister, BCHP_MEM_DMA_0_STATUS + pMemDma->ulRegOffset );
1053                eStatus    = BCHP_GET_FIELD_DATA( ulRegValue, MEM_DMA_0_STATUS, DMA_STATUS );
1054        }
1055
1056        switch (eStatus){
1057                   case (BDMA_P_MEM_STATUS_IDLE):
1058                           *peHwStatus = BDMA_P_HwStatus_eIdle;
1059                           break;
1060                   case (BDMA_P_MEM_STATUS_SLEEP):
1061                           *peHwStatus = BDMA_P_HwStatus_eSleep;
1062                           break;
1063        }
1064
1065}
1066
1067
1068/*--------------------------------------------------------------------------
1069* Callback from base-module queue to read the HW status
1070 */
1071static void BDMA_P_Mem_ReadHwRegs_isr(
1072        void  *               pvEngine,
1073        BDMA_P_HwStatus  *    peHwStatus,
1074        uint32_t  *           pulCurrDesc,
1075        uint32_t  *           pulScratchReg )
1076{
1077        BDMA_P_Mem_Context *pMemDma;
1078        BREG_Handle  hRegister;
1079        uint32_t   ulRegValue;
1080        uint32_t   ulStatus;
1081
1082        /* assert para from our private code */
1083        BDBG_ASSERT( NULL != pvEngine);
1084        BDBG_ASSERT( NULL != peHwStatus );
1085        BDBG_ASSERT( NULL != pulCurrDesc );
1086        BDBG_ASSERT( NULL != pulScratchReg );
1087
1088        pMemDma = (BDMA_P_Mem_Context *)(pvEngine);
1089        hRegister = BDMA_P_GetRegisterHandle(pMemDma->hDma);
1090
1091        /* read CUR_DESC after STATUS, --> less chance to get wrong CUR_DESC?  */
1092        ulRegValue = BREG_Read32( hRegister, BCHP_MEM_DMA_0_STATUS + pMemDma->ulRegOffset );
1093        ulStatus  = BCHP_GET_FIELD_DATA( ulRegValue, MEM_DMA_0_STATUS, DMA_STATUS );
1094
1095        ulRegValue = BREG_Read32( hRegister, BCHP_MEM_DMA_0_CUR_DESC + pMemDma->ulRegOffset );
1096        *pulCurrDesc = BCHP_GET_FIELD_DATA( ulRegValue, MEM_DMA_0_CUR_DESC, ADDR );
1097
1098#ifdef BDMA_P_SUPPORT_SHARF_DMA_ENGINE
1099        if (NULL != pMemDma->hSharf)
1100                *pulScratchReg = BREG_Read32( hRegister, BCHP_MEM_DMA_0_SCRATCH + pMemDma->ulRegOffset - 4);
1101        else
1102                *pulScratchReg = BREG_Read32( hRegister, BCHP_MEM_DMA_0_SCRATCH + pMemDma->ulRegOffset );
1103#else
1104        *pulScratchReg = BREG_Read32( hRegister, BCHP_MEM_DMA_0_SCRATCH + pMemDma->ulRegOffset );
1105#endif
1106
1107        if ( BDMA_P_MEM_STATUS_IDLE == ulStatus )
1108        {
1109                BDBG_MSG(( "Mem DMA engine in idle state!" ));
1110                *peHwStatus = BDMA_P_HwStatus_eIdle;
1111        }
1112        else if ( BDMA_P_MEM_STATUS_BUSY == ulStatus )
1113        {
1114                *peHwStatus = BDMA_P_HwStatus_eBusy;
1115        }
1116        else if ( BDMA_P_MEM_STATUS_SLEEP == ulStatus )
1117        {
1118                *peHwStatus = BDMA_P_HwStatus_eSleep;
1119        }
1120        else
1121        {
1122                BDBG_ERR(( "Mem DMA engine in Reservered state!!!" ));
1123                *peHwStatus = BDMA_P_HwStatus_eUnknown;
1124                BDBG_ASSERT(0);
1125        }
1126}
1127
1128/*--------------------------------------------------------------------------
1129 * Callback from base-module queue to append two Trans' descriptors
1130 */
1131static void BDMA_P_Mem_AppendTranDesc_isr(
1132        BDMA_P_QueueEntry *      pCurrTran,
1133        BDMA_P_QueueEntry *      pNextTran )
1134{
1135        uint32_t  *pulLastDesc ;
1136        uint32_t  ulNewDescPhysAddr;
1137        uint32_t  ulWord3;
1138
1139        BDBG_ASSERT( NULL != pCurrTran );
1140        BDBG_ASSERT( NULL != pNextTran );
1141
1142        ulNewDescPhysAddr = pNextTran->ulDescPhysAddr;
1143        pulLastDesc = (pCurrTran + (pCurrTran->ulNumActBlocks - 1))->pulDescAddr;
1144#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
1145        *(pulLastDesc+2) |=
1146                BCHP_FIELD_DATA(MEM_DMA_DESC_WORD2, AUTO_APPEND, 1);
1147#else
1148        *(pulLastDesc+2) &= ~(
1149                BCHP_MASK(MEM_DMA_DESC_WORD2, LAST));
1150#endif
1151        ulWord3 = *(pulLastDesc+3) & ~(BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR));
1152        *(pulLastDesc+3) = ulWord3 |
1153                BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR,
1154                        ulNewDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT );
1155}
1156
1157/*--------------------------------------------------------------------------
1158 * Callback from base-module queue to send one Tran to HW.
1159 *
1160 * Note: It assume block info is already set for all blocks in this Tran
1161 */
1162static void BDMA_P_Mem_SendToHw_isr(
1163        BDMA_P_QueueHandle       hQueue,
1164        BDMA_P_HwStatus          eHwStatus,
1165        bool                     bAppendInHw )
1166{
1167        BDMA_P_Mem_Context *pMemDma;
1168        BDMA_P_QueueContext * pQueue;
1169        BDMA_P_QueueEntry * p1stTran;
1170        BDMA_P_QueueEntry * pLastTran;
1171        BREG_Handle  hRegister;
1172        uint32_t  ulNewDescPhysAddr;
1173        uint32_t  *pulNewDesc;
1174        uint32_t  ulDescWord;
1175        uint32_t  *pulLastDesc;
1176        uint32_t  ulScratchReg;
1177        volatile uint32_t  ulCheck;
1178
1179        BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue );
1180        BDBG_ASSERT( NULL != pQueue );
1181
1182        pMemDma = (BDMA_P_Mem_Context *)(pQueue->hEngine);
1183        hRegister = BDMA_P_GetRegisterHandle(pMemDma->hDma);
1184
1185        p1stTran = pQueue->pHeadTranInQ;
1186        if (NULL == p1stTran)
1187        {
1188                BDBG_ASSERT( p1stTran );
1189                return;
1190        }
1191        ulNewDescPhysAddr = pQueue->pHeadTranInQ->ulDescPhysAddr;
1192        pulNewDesc        = pQueue->pHeadTranInQ->pulDescAddr;
1193
1194        /* write scratch reg so that other BDMA instance could check our status */
1195        ulScratchReg = ((pQueue->bSgOpenInQ)?
1196                                        (pQueue->ul1stDescPhysAddr | BDMA_P_WATER_MARK_SG_OPEN) :
1197                                        (pQueue->ul1stDescPhysAddr | BDMA_P_WATER_MARK_SG_CLOSE));
1198#ifdef BDMA_P_SUPPORT_SHARF_DMA_ENGINE
1199        if (NULL != pMemDma->hSharf)
1200                BREG_Write32( hRegister, BCHP_MEM_DMA_0_SCRATCH + pMemDma->ulRegOffset - 4,
1201                                          ulScratchReg );
1202        else
1203                BREG_Write32( hRegister, BCHP_MEM_DMA_0_SCRATCH + pMemDma->ulRegOffset,
1204                                          ulScratchReg );
1205#else
1206        BREG_Write32( hRegister, BCHP_MEM_DMA_0_SCRATCH + pMemDma->ulRegOffset,
1207                                  ulScratchReg );
1208#endif
1209
1210        /* send Trans queued in SW into HW */
1211        pLastTran = pQueue->pTailTranInHw;
1212        if (bAppendInHw && (NULL != pLastTran))
1213        {
1214                pulLastDesc = (pLastTran + (pLastTran->ulNumActBlocks - 1))->pulDescAddr;
1215
1216                ulDescWord = *(pulLastDesc+3) & ~(BCHP_MASK(MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR));
1217                *(pulLastDesc+3) = ulDescWord |
1218                        BCHP_FIELD_DATA( MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR,
1219                                ulNewDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT );
1220
1221#if BDMA_P_SUPPORT_MEM_DMA_AUTO_APPEND
1222                /* auto-append to last Tran in hw, which might and might not finished
1223                 * OK to mix scatter-gather with no-scatter-gather linked-lists  */
1224                *(pulLastDesc+2) |=
1225                        BCHP_FIELD_DATA(MEM_DMA_DESC_WORD2, AUTO_APPEND, 1);
1226#else
1227                /* sw dynamically link to last Tran in hw, which might and might not finished,
1228                 * must not mix scatter-gather with no-scatter-gather linked-lists  */
1229                *(pulLastDesc+2) &= ~(BCHP_MASK(MEM_DMA_DESC_WORD2, LAST));
1230#endif
1231
1232                /* read back to force that mem writing completes before reg writing */
1233                ulCheck = *(pulLastDesc+2) | *(pulLastDesc+3);
1234
1235#if (1 == BDMA_P_SHOW_DYN_LINK_FAIL)
1236                BDBG_ERR(("append to 0x%08lx by new tran 0x%08lx",
1237                                  (pLastTran + (pLastTran->ulNumActBlocks - 1))->ulDescPhysAddr,
1238                                  ulNewDescPhysAddr));
1239#endif
1240
1241                /* in case HW already in sleep mode */
1242                BREG_Write32( hRegister, BCHP_MEM_DMA_0_WAKE_CTRL + pMemDma->ulRegOffset,
1243                        BCHP_FIELD_DATA(MEM_DMA_0_WAKE_CTRL, WAKE_MODE, BDMA_P_MEM_WAKE_FROM_LAST_DESC) |
1244                        BCHP_FIELD_DATA(MEM_DMA_0_WAKE_CTRL, WAKE,      BDMA_P_MEM_WAKE_UP) );
1245        }
1246        else
1247        {
1248        ulNewDescPhysAddr = pQueue->pHeadTranInQ->ulDescPhysAddr
1249                        + ( pQueue->pHeadTranInQ->ulFirstBlock * 4 * BDMA_P_MEM_NUM_WORDS_PER_DESC);
1250#if (1 == BDMA_P_SHOW_DYN_LINK_FAIL)
1251                BDBG_ERR(("start new tran 0x%08lx", ulNewDescPhysAddr));
1252#endif
1253                /* must start from FIRST_DESC */
1254                BREG_Write32( hRegister, BCHP_MEM_DMA_0_FIRST_DESC + pMemDma->ulRegOffset,
1255                        BCHP_FIELD_DATA(MEM_DMA_0_FIRST_DESC, ADDR, ulNewDescPhysAddr) );
1256
1257                if ( BDMA_P_HwStatus_eIdle != eHwStatus )
1258                {
1259                        /* mem dma started, but last Tran might be destroyed */
1260                        BREG_Write32( hRegister, BCHP_MEM_DMA_0_WAKE_CTRL + pMemDma->ulRegOffset,
1261                                BCHP_FIELD_DATA(MEM_DMA_0_WAKE_CTRL, WAKE_MODE, BDMA_P_MEM_WAKE_FROM_1ST_DESC) |
1262                                BCHP_FIELD_DATA(MEM_DMA_0_WAKE_CTRL, WAKE,      BDMA_P_MEM_WAKE_UP) );
1263                }
1264                else
1265                {
1266                        /* mem dma has never started */
1267                        BREG_Write32( hRegister, BCHP_MEM_DMA_0_CTRL + pMemDma->ulRegOffset,
1268                                BCHP_FIELD_DATA(MEM_DMA_0_CTRL, RUN, BDMA_P_MEM_RUN_START) );
1269                }
1270        }
1271}
1272
1273/*--------------------------------------------------------------------------
1274 * Callback from base-module queue to check NEXT_DESC_ADDR and print err msg
1275 * dma engine reg read error happens
1276 */
1277static void BDMA_P_Mem_CheckNextDesc_isr(
1278        BDMA_P_QueueEntry *      pCurrTran,
1279        BDMA_P_QueueEntry *      pNextTran )
1280{
1281        BDMA_P_QueueEntry *pBlock;
1282        uint32_t  *pulDesc;
1283        uint32_t  ulSeeNextOffset, ulNextOffset;
1284        int  iLoopCntr;
1285
1286        BDBG_ASSERT( NULL != pCurrTran );
1287
1288        pBlock = pCurrTran;
1289        for ( iLoopCntr = 0; iLoopCntr < (int) pCurrTran->ulNumActBlocks; iLoopCntr++ )
1290        {
1291                if (NULL != pNextTran)
1292                        ulNextOffset = ((iLoopCntr < (int) (pCurrTran->ulNumActBlocks - 1))?
1293                                                        (pBlock + 1)->ulDescPhysAddr : pNextTran->ulDescPhysAddr);
1294                else
1295                        ulNextOffset = ((iLoopCntr < (int) (pCurrTran->ulNumActBlocks - 1))?
1296                                                        (pBlock + 1)->ulDescPhysAddr : 0);
1297                pulDesc = pBlock->pulDescAddr;
1298                ulSeeNextOffset = (BCHP_GET_FIELD_DATA(*(pulDesc+3), MEM_DMA_DESC_WORD3, NEXT_DESC_ADDR) <<
1299                                                   BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT);
1300
1301                if (ulNextOffset != ulSeeNextOffset)
1302                {
1303                        BDBG_ERR(("Bad next_desc: desc 0x%08lx, next_desc 0x%08lx (should be 0x%08lx)",
1304                                          pBlock->ulDescPhysAddr, ulSeeNextOffset, ulNextOffset));
1305                        BDBG_ERR(("tran_desc 0x%08lx, NumActBlk %d, Blck %d",
1306                                          pCurrTran->ulDescPhysAddr, pCurrTran->ulNumActBlocks, iLoopCntr));
1307
1308                        /*BDBG_ASSERT(ulNextOffset != ulSeeNextOffset);*/
1309                }
1310
1311#if (1 == BDMA_P_SHOW_DYN_LINK_FAIL)
1312                else if (iLoopCntr == (int) (pCurrTran->ulNumActBlocks - 1))
1313                {
1314                        /* XXX extra print make system busy, and shows HW reg reading problem */
1315                        BDBG_ERR(("good next_desc: desc 0x%08lx (blck %d), next_desc 0x%08lx",
1316                                          pBlock->ulDescPhysAddr, iLoopCntr, ulSeeNextOffset));
1317                }
1318#endif
1319
1320#if (1 == BDMA_P_SHOW_DESC)
1321                do {
1322                        uint32_t *pulDesc;
1323
1324                        pulDesc = pBlock->pulDescAddr;
1325                        if (iLoopCntr == 0)
1326                                BDBG_ERR(("   first desc 0x%08lx: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx",
1327                                        pBlock->ulDescPhysAddr, *pulDesc, *(pulDesc+1), *(pulDesc+2), *(pulDesc+3), *(pulDesc+4)));
1328                        else if (iLoopCntr == (int) (pCurrTran->ulNumActBlocks - 1))
1329                                BDBG_ERR(("   last  desc 0x%08lx: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx",
1330                                        pBlock->ulDescPhysAddr, *pulDesc, *(pulDesc+1), *(pulDesc+2), *(pulDesc+3), *(pulDesc+4)));
1331                        else
1332                                BDBG_ERR(("         desc 0x%08lx: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx",
1333                                        pBlock->ulDescPhysAddr, *pulDesc, *(pulDesc+1), *(pulDesc+2), *(pulDesc+3), *(pulDesc+4)));
1334                } while (0);
1335#endif
1336
1337                pBlock++;
1338        }
1339}
1340
1341/***************************************************************************
1342 *
1343 * "Dma Done" interrupt handler (call back ) function
1344 *
1345 ***************************************************************************/
1346
1347/***************************************************************************
1348 * To be called by the BINT module as the "dma done" interrupt handler (call
1349 * back func). It records the just completed Tran's result, calls the user's
1350 * call back function to futher process the DMA result if the Tran is async,
1351 * (i.e. if it has a user's call back func).
1352 */
1353static void BDMA_P_Mem_DoneCallBack_isr(
1354        void *                pParm1,  /* pMemDma */
1355        int                   parm2 )  /* not used */
1356{
1357        BERR_Code  eResult = BERR_SUCCESS;
1358        BDMA_P_Mem_Context *  pMemDma;
1359
1360        BSTD_UNUSED(parm2);
1361        BDMA_P_MEM_GET_CONTEXT(pParm1, pMemDma);
1362        if ( NULL == pMemDma )
1363        {
1364                eResult = BERR_TRACE( BERR_INVALID_PARAMETER );
1365                BDBG_ERR(( "Invaid pParm1 to BDMA_P_Mem_DoneCallBack_isr!" ));
1366                goto BDMA_P_Done_Mem_DoneCallBack_isr;
1367        }
1368
1369        /* read status from HW and update records */
1370        BDMA_P_Queue_CheckHwAndSendNewReq_isr( pMemDma->hQueue );
1371
1372  BDMA_P_Done_Mem_DoneCallBack_isr:
1373        return;
1374}
1375
1376
1377/***************************************************************************
1378 *
1379 * API support functions
1380 *
1381 ***************************************************************************/
1382
1383/*--------------------------------------------------------------------------
1384 * To be called to init mem dma engine: 1). init Hw, 2). create queue, 3).
1385 * create call-back, 4). init crpto setting.
1386 */
1387BERR_Code BDMA_P_Mem_Init(
1388        BDMA_P_Mem_Context  * pMemDma,
1389        const BDMA_Mem_Settings *pSettings,
1390        uint32_t              ulL2IntrBintId )
1391{
1392        BERR_Code  eResult = BERR_SUCCESS;
1393        BDMA_Handle  hDma;
1394        BMEM_Handle  hMemory = NULL;  /* init to silence linux comipler */
1395        BDMA_P_QueueHandle  hQueue = NULL;
1396        BINT_CallbackHandle  hCallBack = NULL;
1397
1398        BDBG_ASSERT( NULL != pMemDma);
1399
1400        BDMA_P_MEM_SET_BLACK_MAGIC( pMemDma );
1401
1402        /* init HW */
1403        hDma = pMemDma->hDma;
1404
1405        /* create Tran queue */
1406        hMemory = BDMA_P_GetMemoryHandle( hDma );
1407        eResult = BDMA_P_Queue_Create(
1408                &hQueue, (void *) pMemDma, hMemory, BDMA_P_MEM_NUM_WORDS_PER_DESC,
1409                (BDMA_P_CmnSettings *)pSettings, BDMA_P_Mem_ReadHwRegs_isr,
1410                BDMA_P_Mem_AppendTranDesc_isr, BDMA_P_Mem_SendToHw_isr,
1411                BDMA_P_Mem_CheckNextDesc_isr, BDMA_P_Mem_SafeSendToHw_isr);
1412        BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Mem_Init );
1413        pMemDma->hQueue = hQueue;
1414
1415        if (pSettings->bSupportCallBack)
1416        {
1417                /* create done-interrupt call back
1418                 * no need to create call back for BCHP_INT_ID_MEM_DMA_ERR_INTR,
1419                 * since PI already checks size / error without sending HW ??? */
1420                /* BCHP_INT_ID_MEM_DMA_0_INTR, or BCHP_INT_ID_MEM_DMA_1_INTR */
1421                eResult = BINT_CreateCallback(
1422                        &hCallBack, BDMA_P_GetInterruptHandle( hDma ),
1423                        ulL2IntrBintId, BDMA_P_Mem_DoneCallBack_isr,
1424                        (void *)pMemDma, 0 );
1425                BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Mem_Init );
1426                pMemDma->hCallBack = hCallBack;
1427
1428                eResult = BINT_ClearCallback( hCallBack );
1429                BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Mem_Init );
1430                eResult = BINT_EnableCallback( hCallBack );
1431                BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Mem_Init );
1432        }
1433
1434        /* init op */
1435        pMemDma->eReadEndian = BDMA_Endian_eLittle;
1436        pMemDma->eSwapMode = BDMA_SwapMode_eNoSwap;
1437        pMemDma->eCryptMode = BDMA_CryptMode_eNoCrypt;
1438        pMemDma->ulKeySlot = 0;
1439
1440        return eResult;
1441
1442  BDMA_P_Err_Mem_Init:
1443        BDMA_P_Mem_UnInit( pMemDma );
1444
1445        return BERR_TRACE(eResult);
1446}
1447
1448
1449/*--------------------------------------------------------------------------
1450 * To be called to uninit mem dma engine: destroy queue and call-back
1451 */
1452BERR_Code BDMA_P_Mem_UnInit(
1453        BDMA_P_Mem_Context  * pMemDma )
1454{
1455        BDBG_ASSERT( NULL != pMemDma);
1456
1457        if ( NULL != pMemDma->hCallBack )
1458        {
1459                BINT_DisableCallback( pMemDma->hCallBack );
1460                BINT_DestroyCallback( pMemDma->hCallBack );
1461        }
1462        if ( NULL != pMemDma->hQueue )
1463                BDMA_P_Queue_Destroy( pMemDma->hQueue, BDMA_P_GetMemoryHandle(pMemDma->hDma) );
1464
1465        return BERR_SUCCESS;
1466}
1467
1468/***************************************************************************
1469 *
1470 */
1471BERR_Code BDMA_P_Mem_Create(
1472        BDMA_Handle           hDma,
1473        BDMA_MemDmaEngine     eEngine,
1474        const BDMA_Mem_Settings *pSettings,
1475        BDMA_Mem_Handle *     phMemDma )
1476{
1477        BERR_Code  eResult = BERR_SUCCESS;
1478        BDMA_P_Context *  pDma;
1479        BDMA_P_Mem_Context  *pMemDma = NULL;
1480        uint32_t  ulL2IntrBintId;
1481
1482        if ( NULL != phMemDma )
1483                *phMemDma = NULL;
1484
1485        BDMA_P_MAIN_GET_CONTEXT( hDma, pDma );
1486        if ( (NULL == phMemDma) || (NULL == pDma) || (eEngine >= BDMA_MemDmaEngine_eUnknown))
1487        {
1488                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1489                goto BDMA_P_Err_Mem_Create;
1490        }
1491        if (BDMA_P_SUPPORT_MEM_DMA_ENGINE <= eEngine)
1492        {
1493                eResult = BERR_TRACE(BDMA_ERR_ENGINE_NOT_SUPPORTED);
1494                goto BDMA_P_Err_Mem_Create;
1495        }
1496        if ( NULL != BDMA_P_GetMemDmaHandle(hDma, eEngine) )
1497        {
1498                /* memeory dma engine sub-module is already created */
1499                eResult = BERR_TRACE(BDMA_ERR_ENGINE_OCCUPIED);
1500                goto BDMA_P_Err_Mem_Create;
1501        }
1502
1503        /* allocate mem dma sub-module's main context */
1504        pMemDma = (BDMA_P_Mem_Context *)BKNI_Malloc( sizeof(BDMA_P_Mem_Context) );
1505        if ( NULL == pMemDma )
1506        {
1507                eResult = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
1508                goto BDMA_P_Err_Mem_Create;
1509        }
1510        BKNI_Memset((void*)pMemDma, 0x0, sizeof(BDMA_P_Mem_Context));
1511
1512#if (BDMA_P_SUPPORT_MEM_DMA_ENGINE>=2)
1513        if (BDMA_MemDmaEngine_e0 == eEngine)
1514        {
1515                ulL2IntrBintId = BCHP_INT_ID_MEM_DMA_0_INTR;
1516                pMemDma->ulRegOffset = 0;
1517        }
1518        else
1519        {
1520                ulL2IntrBintId = BCHP_INT_ID_MEM_DMA_1_INTR;
1521                pMemDma->ulRegOffset = BCHP_MEM_DMA_1_REG_START - BCHP_MEM_DMA_0_REG_START;
1522        }
1523#else
1524                ulL2IntrBintId = BCHP_INT_ID_MEM_DMA_0_INTR;
1525                pMemDma->ulRegOffset = 0;
1526#endif
1527
1528        /* init mem dma */
1529        pMemDma->hDma = hDma;
1530        pMemDma->eEngine = eEngine;
1531        eResult = BDMA_P_Mem_Init( pMemDma, pSettings, ulL2IntrBintId );
1532        BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Mem_Create );
1533
1534        /* connect mem dma sub-module to dma module's main context */
1535        BDMA_P_SetMemDmaHandle( hDma, eEngine, pMemDma );
1536
1537        *phMemDma = pMemDma;
1538        return eResult;
1539
1540  BDMA_P_Err_Mem_Create:
1541
1542        if ( NULL != pMemDma )
1543                BDMA_P_MEM_DESTROY_CONTEXT( pMemDma );
1544
1545        return BERR_TRACE(eResult);
1546}
1547
1548/***************************************************************************
1549 *
1550 */
1551BERR_Code BDMA_P_Mem_Destroy(
1552        BDMA_Mem_Handle       hMemDma )
1553{
1554        BERR_Code  eResult = BERR_SUCCESS;
1555        BDMA_P_Mem_Context *  pMemDma;
1556
1557        BDMA_P_MEM_GET_CONTEXT(hMemDma, pMemDma);
1558        if ( NULL == pMemDma )
1559        {
1560                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1561                goto BDMA_P_Done_Mem_Destroy;
1562        }
1563
1564        /* disconnect mem dma sub-module to dma module's main context */
1565        BDMA_P_SetMemDmaHandle( pMemDma->hDma, pMemDma->eEngine, NULL );
1566
1567        /* destroy callBack and queue */
1568        BDMA_P_Mem_UnInit( pMemDma );
1569
1570        BDMA_P_MEM_DESTROY_CONTEXT( pMemDma );
1571
1572  BDMA_P_Done_Mem_Destroy:
1573        return eResult;
1574}
1575
1576/***************************************************************************
1577 *
1578 */
1579BERR_Code BDMA_P_Mem_Tran_SetCrypto_isr(
1580        BDMA_Mem_Tran_Handle     hTran,
1581        BDMA_CryptMode           eCryptMode,
1582        uint32_t                 ulKeySlot,
1583        bool                     bSgEnable )
1584{
1585        BDMA_P_QueueEntry * pTran;
1586        BERR_Code  eResult = BERR_SUCCESS;
1587        BDMA_P_Mem_Context *  pMemDma;
1588
1589        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1590        if ((NULL == pTran) ||
1591                (eCryptMode >= BDMA_CryptMode_eInvalid) ||
1592                (ulKeySlot > BDMA_P_MEM_KEY_SLOT_MAX))
1593        {
1594                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1595                goto BDMA_P_Done_Mem_Tran_SetCrypt;
1596        }
1597
1598        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
1599        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_SetCrypt );
1600        if (pMemDma->bCryptoSetInEngine)
1601        {
1602                eResult = BERR_TRACE(BDMA_ERR_OBSOLETE_API_MIX);
1603                goto BDMA_P_Done_Mem_Tran_SetCrypt;
1604        }
1605
1606        pMemDma->bCryptoSetInTran = true;
1607        pTran->eCryptMode = eCryptMode;
1608        pTran->ulKeySlot = ulKeySlot;
1609        pTran->bSgEnable = bSgEnable;
1610
1611  BDMA_P_Done_Mem_Tran_SetCrypt:
1612        return eResult;
1613}
1614
1615/* obsolete, for back compatibility only */
1616BERR_Code BDMA_P_Mem_SetCrypto_isr(
1617        BDMA_Mem_Handle          hMemDma,
1618        BDMA_CryptMode           eCryptMode,
1619        uint32_t                 ulKeySlot,
1620        bool                     bSgEnable )
1621{
1622        BERR_Code  eResult = BERR_SUCCESS;
1623        BDMA_P_Mem_Context *  pMemDma;
1624
1625        BDMA_P_MEM_GET_CONTEXT(hMemDma, pMemDma);
1626        if ( (NULL == pMemDma) ||
1627                 (eCryptMode >= BDMA_CryptMode_eInvalid) ||
1628                 (ulKeySlot > BDMA_P_MEM_KEY_SLOT_MAX))
1629        {
1630                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1631                goto BDMA_P_Done_Mem_SetCrypt;
1632        }
1633
1634        if (pMemDma->bCryptoSetInTran)
1635        {
1636                eResult = BERR_TRACE(BDMA_ERR_OBSOLETE_API_MIX);
1637                goto BDMA_P_Done_Mem_SetCrypt;
1638        }
1639
1640        pMemDma->bCryptoSetInEngine = true;
1641        pMemDma->eCryptMode = eCryptMode;
1642        pMemDma->ulKeySlot = ulKeySlot;
1643        pMemDma->bSgEnable = bSgEnable;
1644
1645  BDMA_P_Done_Mem_SetCrypt:
1646        return eResult;
1647}
1648
1649/***************************************************************************
1650 * To be called to set the block info for a Tran block. Input block info are
1651 * validated against the current engine state.
1652 */
1653BERR_Code BDMA_P_Mem_Tran_SetDmaBlockInfo_isr(
1654        BDMA_Mem_Tran_Handle     hTran,
1655        uint32_t                 ulBlockId,
1656        uint32_t                 ulDstBusAddr,
1657        uint32_t                 ulSrcBusAddr,
1658        uint32_t                 ulBlockSize,
1659        bool                     bCryptInit )
1660{
1661        BERR_Code  eResult = BERR_SUCCESS;
1662        BDMA_P_Mem_Context *  pMemDma;
1663        BDMA_P_QueueEntry * pTran;
1664        BDMA_P_QueueEntry * pBlock;
1665
1666        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1667        if ( NULL == pTran )
1668        {
1669                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1670                goto BDMA_P_Done_Mem_Tran_SetDmaBlockInfo;
1671        }
1672
1673        if ( pTran->ulNumTranBlocks <= ulBlockId )
1674        {
1675                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1676                goto BDMA_P_Done_Mem_Tran_SetDmaBlockInfo;
1677        }
1678
1679        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
1680        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_SetDmaBlockInfo );
1681
1682        /* validate addr, size and set desc */
1683        pBlock = pTran + ulBlockId;
1684        eResult = BDMA_P_Mem_SetBlockDesc_isr( pMemDma,
1685                                                                                   pTran, pBlock,
1686                                                                                   pTran->bCachedDscrp,
1687                                                                                   ulDstBusAddr, ulSrcBusAddr,
1688                                                                                   ulBlockSize, bCryptInit );
1689        if ( BERR_SUCCESS == eResult )
1690                pBlock->bBlockInfoSet = true;
1691
1692  BDMA_P_Done_Mem_Tran_SetDmaBlockInfo:
1693        return BERR_TRACE( eResult );
1694}
1695
1696
1697/***************************************************************************
1698 * To be called to mark / unmark the block as scatter-gather start /end point
1699 * validated against the current engine state.
1700 */
1701BERR_Code BDMA_P_Mem_Tran_SetSgStartEnd_isr(
1702        BDMA_Mem_Tran_Handle     hTran,
1703        uint32_t                 ulBlockId,
1704        bool                     bSgStart,
1705        bool                     bSgEnd )
1706{
1707#if (BDMA_P_SUPPORT_MEM_DMA_SCATTER_GATHER)
1708        BERR_Code  eResult = BERR_SUCCESS;
1709        BDMA_P_QueueEntry * pTran;
1710        BDMA_P_QueueEntry * pBlock;
1711
1712        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1713        if ( NULL == pTran )
1714        {
1715                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1716                goto BDMA_P_Done_Mem_Tran_SetSgStartEnd;
1717        }
1718
1719        if ( pTran->ulNumTranBlocks <= ulBlockId )
1720        {
1721                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1722                goto BDMA_P_Done_Mem_Tran_SetSgStartEnd;
1723        }
1724
1725        pTran->bSgStartStopSet = true;
1726
1727        pBlock = pTran + ulBlockId;
1728        eResult = BDMA_P_Mem_SetSgStartEndDesc_isr(
1729                pBlock, pTran->bCachedDscrp, bSgStart, bSgEnd );
1730
1731  BDMA_P_Done_Mem_Tran_SetSgStartEnd:
1732        return BERR_TRACE( eResult );
1733#else
1734        BSTD_UNUSED(hTran);
1735        BSTD_UNUSED(ulBlockId);
1736        BSTD_UNUSED(bSgStart);
1737        BSTD_UNUSED(bSgEnd);
1738
1739        return BERR_TRACE(BDMA_ERR_FEATURE_NOT_SUPPORTED);
1740#endif
1741}
1742
1743/***************************************************************************
1744 */
1745
1746BERR_Code BDMA_P_Mem_Tran_StartSubset_isr(
1747        BDMA_Mem_Tran_Handle     hTran,
1748        uint32_t                 ulFirstBlock,
1749        uint32_t                 ulNumActBlocks,
1750        BDMA_Mem_CallbackFunc    pCallBackFunc_isr,
1751        void *                   pUserCallBackParam )
1752{
1753        BERR_Code  eResult = BERR_SUCCESS;
1754        BDMA_P_Mem_Context *  pMemDma;
1755        BDMA_P_QueueEntry * pTran;
1756        bool  bSgOpen;
1757
1758        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1759        if ( NULL == pTran )
1760        {
1761                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1762                goto BDMA_P_Done_Mem_Tran_Start;
1763        }
1764
1765        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
1766        BDBG_ERR(("\n BDMA_P_Mem_GetMemDmaPtrFromTran_isr"));
1767        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Start );
1768
1769        eResult = BDMA_P_Mem_Tran_PrepareStartSubset_isr( pTran, pMemDma->hQueue,
1770                BDMA_P_GetMemoryHandle(pMemDma->hDma), ulFirstBlock, ulNumActBlocks, &bSgOpen );
1771        BDBG_ERR(("\n BDMA_P_Mem_Tran_PrepareStartSubset_isr"));
1772        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Start );
1773
1774        eResult = BDMA_P_Queue_StartTran_isr (
1775                pMemDma->hQueue, pTran, ulNumActBlocks, bSgOpen,
1776                (BDMA_P_CallbackFunc) pCallBackFunc_isr, pUserCallBackParam );
1777
1778  BDMA_P_Done_Mem_Tran_Start:
1779        return BERR_TRACE(eResult);
1780}
1781
1782/***************************************************************************
1783 */
1784BERR_Code BDMA_P_Mem_Transfer_isr(
1785        BDMA_Mem_Tran_Handle     hTran,
1786        uint32_t                 ulBlockId,
1787        uint32_t                 ulDstBusAddr,
1788        uint32_t                 ulSrcBusAddr,
1789        uint32_t                 ulBlockSize,
1790        bool                     bCryptInit,
1791        BDMA_Mem_CallbackFunc    pCallBackFunc_isr,
1792        void *                   pUserCallBackParam )
1793{
1794        BERR_Code  eResult = BERR_SUCCESS;
1795        BDMA_P_Mem_Context *  pMemDma;
1796        BDMA_P_QueueEntry * pTran;
1797        BDMA_P_QueueEntry * pBlock;
1798        bool bLastBlock;
1799        bool  bSgOpen;
1800
1801        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1802        if ( NULL == pTran )
1803        {
1804                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1805                goto BDMA_P_Done_Mem_Transfer;
1806        }
1807
1808        if ( pTran->ulNumTranBlocks <= ulBlockId )
1809        {
1810                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1811                goto BDMA_P_Done_Mem_Transfer;
1812        }
1813
1814        /* get mem dma pointer */
1815        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
1816        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Transfer );
1817
1818        /* tell queue module to reset this Tran into initially created state */
1819        eResult = BDMA_P_Queue_ResetTran_isr ( pMemDma->hQueue, pTran );
1820        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Transfer );
1821
1822        /* set transfer information */
1823        /* validate addr, size and set desc */
1824        bLastBlock = (pTran->ulNumTranBlocks == (ulBlockId+1));
1825        pBlock = pTran + ulBlockId;
1826        eResult = BDMA_P_Mem_SetBlockDesc_isr( pMemDma,
1827                                                                                   pTran, pBlock,
1828                                                                                   bLastBlock,
1829                                                                                   ulDstBusAddr, ulSrcBusAddr,
1830                                                                                   ulBlockSize, bCryptInit );
1831        if ( BERR_SUCCESS == eResult )
1832                pBlock->bBlockInfoSet = true;
1833
1834        eResult = BDMA_P_Mem_Tran_PrepareStart_isr( pTran, pMemDma->hQueue,
1835                BDMA_P_GetMemoryHandle(pMemDma->hDma), 1, &bSgOpen );
1836        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Transfer );
1837
1838        eResult = BDMA_P_Queue_StartTran_isr ( pMemDma->hQueue,
1839                                                                                   pTran, 1, bSgOpen,
1840                                                                                   (BDMA_P_CallbackFunc) pCallBackFunc_isr,
1841                                                                                   pUserCallBackParam );
1842
1843  BDMA_P_Done_Mem_Transfer:
1844        return BERR_TRACE(eResult);
1845}
1846
1847/***************************************************************************
1848 * To be called by both BDMA_P_Mem_Tran_Start_isrAndCallBack and
1849 * BDMA_P_Mem_Tran_Start_isr. BDMA_P_Mem_Tran_Start_isr should pass NULL for
1850 * pCallBackFunc_isr and pUserCallBackParam
1851 *
1852 * Note: when a Tran is sent to HW, interrupt is alwayas enabled. If the
1853 * Tran is async, the module's interrupt handler BDMA_P_Mem_DoneCallBack_isr
1854 * will call user's callback function. In the sync case, there is no user's
1855 * call back function to call, BDMA_P_Mem_DoneCallBack_isr only sets the
1856 * internal record of the status, the ideal is that the user will check the
1857 * Tran's status in a waiting loop and process the Tran result synchronously.
1858 */
1859BERR_Code BDMA_P_Mem_Tran_Start_isr(
1860        BDMA_Mem_Tran_Handle     hTran,
1861        uint32_t                 ulNumActBlocks,
1862        BDMA_Mem_CallbackFunc    pCallBackFunc_isr,
1863        void *                   pUserCallBackParam )
1864{
1865        BERR_Code  eResult = BERR_SUCCESS;
1866        BDMA_P_Mem_Context *  pMemDma;
1867        BDMA_P_QueueEntry * pTran;
1868        bool  bSgOpen;
1869
1870        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1871        if ( NULL == pTran )
1872        {
1873                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1874                goto BDMA_P_Done_Mem_Tran_Start;
1875        }
1876
1877        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
1878        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Start );
1879
1880        eResult = BDMA_P_Mem_Tran_PrepareStart_isr( pTran, pMemDma->hQueue,
1881                BDMA_P_GetMemoryHandle(pMemDma->hDma), ulNumActBlocks, &bSgOpen );
1882        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Start );
1883
1884        eResult = BDMA_P_Queue_StartTran_isr (
1885                pMemDma->hQueue, pTran, ulNumActBlocks, bSgOpen,
1886                (BDMA_P_CallbackFunc) pCallBackFunc_isr, pUserCallBackParam );
1887
1888  BDMA_P_Done_Mem_Tran_Start:
1889        return BERR_TRACE(eResult);
1890}
1891
1892
1893#endif
1894
1895/***************************************************************************
1896 *
1897 */
1898BERR_Code BDMA_P_Mem_SetByteSwapMode_isr(
1899        BDMA_Mem_Handle          hMemDma,
1900        BDMA_Endian              eReadEndian,
1901        BDMA_SwapMode            eSwapMode )
1902{
1903        BERR_Code  eResult = BERR_SUCCESS;
1904        BDMA_P_Mem_Context *  pMemDma;
1905
1906        BDMA_P_MEM_GET_CONTEXT(hMemDma, pMemDma);
1907        if ( (NULL == pMemDma) ||
1908                 (eReadEndian >= BDMA_Endian_eInvalid) ||
1909                 (eSwapMode >= BDMA_SwapMode_eInvalid) )
1910        {
1911                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1912                goto BDMA_P_Done_Mem_SetByteSwapMode;
1913        }
1914
1915        pMemDma->eReadEndian = eReadEndian;
1916        pMemDma->eSwapMode = eSwapMode;
1917
1918  BDMA_P_Done_Mem_SetByteSwapMode:
1919        return eResult;
1920}
1921
1922/***************************************************************************
1923 * To be called to created a new Tran
1924 */
1925BERR_Code BDMA_P_Mem_Tran_Create_isr(
1926        BDMA_Mem_Handle          hMemDma,
1927        uint32_t                 ulNumBlocks,
1928        bool                     bCachedDesc,
1929        BDMA_Mem_Tran_Handle  *  phTran )
1930{
1931        BERR_Code  eResult = BERR_SUCCESS;
1932        BDMA_P_Mem_Context *  pMemDma;
1933        BDMA_P_QueueEntry * pTran;
1934
1935        if ( NULL != phTran )
1936                *phTran = NULL;
1937
1938        BDMA_P_MEM_GET_CONTEXT( hMemDma, pMemDma );
1939        if ( (NULL == pMemDma) || (NULL == phTran) )
1940        {
1941                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1942                goto BDMA_P_Done_Mem_Tran_Create;
1943        }
1944
1945        eResult = BDMA_P_Queue_CreateTran_isr(
1946                pMemDma->hQueue, ulNumBlocks, bCachedDesc, &pTran );
1947        if ( BERR_SUCCESS == eResult )
1948                *phTran = (BDMA_Mem_Tran_Handle ) pTran;
1949
1950  BDMA_P_Done_Mem_Tran_Create:
1951        return BERR_TRACE(eResult);
1952}
1953
1954
1955
1956
1957
1958
1959/***************************************************************************
1960 * To be called by BDMA_Mem_Tran_GetStatus. It outputs the internal records
1961 * of the Tran directly.
1962 */
1963BERR_Code BDMA_P_Mem_Tran_GetStatus_isr(
1964        BDMA_Mem_Tran_Handle     hTran,
1965        BDMA_TranStatus *        peTranStatus )
1966{
1967        BERR_Code  eResult = BERR_SUCCESS;
1968        BDMA_P_Mem_Context *  pMemDma;
1969        BDMA_P_QueueEntry * pTran;
1970
1971        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
1972        if ( NULL == pTran )
1973        {
1974                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
1975                goto BDMA_P_Done_Mem_Tran_GetStatus;
1976        }
1977
1978        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
1979        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_GetStatus );
1980
1981        /* read status from HW and update Trans' records */
1982        BDMA_P_Queue_CheckHwAndSendNewReq_isr( pMemDma->hQueue );
1983
1984        *peTranStatus = pTran->eStatus;
1985        return BERR_SUCCESS;
1986
1987  BDMA_P_Done_Mem_Tran_GetStatus:
1988        return BERR_TRACE(eResult);
1989}
1990
1991/***************************************************************************
1992 * To be called by BDMA_Mem_Tran_Destroy. It free the queue entries occupied
1993 * this Tran
1994 */
1995BERR_Code BDMA_P_Mem_Tran_Destroy_isr(
1996        BDMA_Mem_Tran_Handle     hTran )
1997{
1998        BERR_Code  eResult = BERR_SUCCESS;
1999        BDMA_P_Mem_Context *  pMemDma;
2000        BDMA_P_QueueEntry * pTran;
2001
2002        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
2003        if ( NULL == pTran )
2004        {
2005                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
2006                goto BDMA_P_Done_Mem_Tran_Destroy;
2007        }
2008
2009        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
2010        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Destroy );
2011
2012        /* tell queue module to free the queue entries of this */
2013        eResult = BDMA_P_Queue_DestroyTran_isr ( pMemDma->hQueue,
2014                                                                                 pTran );
2015        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Destroy );
2016
2017        return BERR_SUCCESS;
2018
2019  BDMA_P_Done_Mem_Tran_Destroy:
2020        return BERR_TRACE(eResult);
2021}
2022
2023/***************************************************************************
2024 * To be called by BDMA_Mem_Tran_Reset. It resets the Tran into its
2025 * initially created state
2026 */
2027BERR_Code BDMA_P_Mem_Tran_Reset_isr(
2028        BDMA_Mem_Tran_Handle     hTran )
2029{
2030        BERR_Code  eResult = BERR_SUCCESS;
2031        BDMA_P_Mem_Context *  pMemDma;
2032        BDMA_P_QueueEntry * pTran;
2033
2034        BDMA_P_TRAN_GET_CONTEXT( hTran, pTran );
2035        if ( NULL == pTran )
2036        {
2037                eResult = BERR_TRACE(BERR_INVALID_PARAMETER);
2038                goto BDMA_P_Done_Mem_Tran_Reset;
2039        }
2040
2041        eResult = BDMA_P_Mem_GetMemDmaPtrFromTran_isr( pTran, &pMemDma );
2042        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Reset );
2043
2044        /* tell queue module to reset this Tran into initially created state */
2045        eResult = BDMA_P_Queue_ResetTran_isr ( pMemDma->hQueue,
2046                                                                           pTran );
2047        BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Mem_Tran_Reset );
2048
2049        return BERR_SUCCESS;
2050
2051  BDMA_P_Done_Mem_Tran_Reset:
2052        return BERR_TRACE(eResult);
2053}
2054
2055/* End of File */
Note: See TracBrowser for help on using the repository browser.