| 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_pci_priv.c $ |
|---|
| 11 | * $brcm_Revision: Hydra_Software_Devel/7 $ |
|---|
| 12 | * $brcm_Date: 3/22/11 10:04a $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * |
|---|
| 17 | * Revision History: |
|---|
| 18 | * $brcm_Log: /magnum/portinginterface/dma/7400/bdma_pci_priv.c $ |
|---|
| 19 | * |
|---|
| 20 | * Hydra_Software_Devel/7 3/22/11 10:04a vanessah |
|---|
| 21 | * SW7420-1431: get rid of further warning msg |
|---|
| 22 | * |
|---|
| 23 | * Hydra_Software_Devel/6 3/22/11 9:45a vanessah |
|---|
| 24 | * SW7420-1431: fix pci compile error |
|---|
| 25 | * |
|---|
| 26 | * Hydra_Software_Devel/5 3/21/11 6:38p vanessah |
|---|
| 27 | * SW7420-1431: support oflarge DMA descriptor list subset |
|---|
| 28 | * |
|---|
| 29 | * Hydra_Software_Devel/4 11/9/10 5:11p vanessah |
|---|
| 30 | * SW35125-11: DMA PI support for 35125 |
|---|
| 31 | * |
|---|
| 32 | * Hydra_Software_Devel/3 8/17/10 12:16p vanessah |
|---|
| 33 | * SW7335-791: After customer verification, merged into main |
|---|
| 34 | * |
|---|
| 35 | * Hydra_Software_Devel/SW7335-791/1 8/4/10 10:17p vanessah |
|---|
| 36 | * SW7335-791: DMA engine hangs when continuous descriptors using |
|---|
| 37 | * different scram modes |
|---|
| 38 | * |
|---|
| 39 | * Hydra_Software_Devel/2 9/23/08 10:38a syang |
|---|
| 40 | * PR 34606: left shift 4 bits for curr_desc reading |
|---|
| 41 | * |
|---|
| 42 | * Hydra_Software_Devel/28 5/28/08 12:33p syang |
|---|
| 43 | * PR 34606: clean LAST bit during dyn link even if AUTO_PEND supported; |
|---|
| 44 | * clean up |
|---|
| 45 | * |
|---|
| 46 | * Hydra_Software_Devel/27 5/19/08 1:58p syang |
|---|
| 47 | * PR 34606: clean up |
|---|
| 48 | * |
|---|
| 49 | * Hydra_Software_Devel/26 5/19/08 11:48a syang |
|---|
| 50 | * PR 34606: add validation for HW reg reading |
|---|
| 51 | * |
|---|
| 52 | * Hydra_Software_Devel/25 12/12/07 3:40p syang |
|---|
| 53 | * PR 31923: added auto-append support to PI |
|---|
| 54 | * |
|---|
| 55 | * Hydra_Software_Devel/24 12/11/07 10:54a syang |
|---|
| 56 | * PR 34606: more small clean up after big rewriting |
|---|
| 57 | * |
|---|
| 58 | * Hydra_Software_Devel/23 12/7/07 4:09p syang |
|---|
| 59 | * PR 34606: rewrite more than half of code to support hw sharing for |
|---|
| 60 | * kernel and user-mode sides |
|---|
| 61 | * |
|---|
| 62 | * Hydra_Software_Devel/22 10/15/07 3:38p syang |
|---|
| 63 | * PR 35947: add "_isr" to call back func name |
|---|
| 64 | * |
|---|
| 65 | * Hydra_Software_Devel/21 3/21/07 12:47p syang |
|---|
| 66 | * PR 28173: dyn link works now after fixing next_desc shift and status |
|---|
| 67 | * proc tran loop break. fixed cur hw desc left shift |
|---|
| 68 | * |
|---|
| 69 | * Hydra_Software_Devel/20 3/16/07 12:52p syang |
|---|
| 70 | * PR 28173: add dynamic link support (not turn on yet) |
|---|
| 71 | * |
|---|
| 72 | * Hydra_Software_Devel/18 2/5/07 4:43p syang |
|---|
| 73 | * PR 23354: allow mem addr in mem_1; cleanup cip specific code section |
|---|
| 74 | * macro usage |
|---|
| 75 | * |
|---|
| 76 | * Hydra_Software_Devel/17 1/16/07 4:44p syang |
|---|
| 77 | * PR 26224: cleanup |
|---|
| 78 | * |
|---|
| 79 | * Hydra_Software_Devel/16 1/8/07 12:53p tdo |
|---|
| 80 | * PR 26224: Add second DMA MEM engine support for 7400 B0 |
|---|
| 81 | * |
|---|
| 82 | * Hydra_Software_Devel/15 12/28/06 6:24p syang |
|---|
| 83 | * PR 26618: update to use BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_SINGLE/BURST |
|---|
| 84 | * for 7403 |
|---|
| 85 | * |
|---|
| 86 | * Hydra_Software_Devel/14 10/3/06 4:01p syang |
|---|
| 87 | * PR 24634: replace critical section with private mutex for |
|---|
| 88 | * mem/pci_dma_handle create/destroy. |
|---|
| 89 | * |
|---|
| 90 | * Hydra_Software_Devel/13 8/4/04 4:38p syang |
|---|
| 91 | * PR 12172: fix warning with release build |
|---|
| 92 | * |
|---|
| 93 | * Hydra_Software_Devel/12 5/24/04 6:00p jasonh |
|---|
| 94 | * PR 11189: Merge down from B0 to main-line |
|---|
| 95 | * |
|---|
| 96 | * Hydra_Software_Devel/Refsw_Devel_7038_B0/1 4/20/04 11:35a syang |
|---|
| 97 | * PR 10685: updated HW register reading / setting to B0, added |
|---|
| 98 | * ClearCallback before EnableCallback. |
|---|
| 99 | * |
|---|
| 100 | * Hydra_Software_Devel/11 3/8/04 6:17p syang |
|---|
| 101 | * PR 10012: added shift to "Next Desc Addr" in desc word 3 |
|---|
| 102 | * |
|---|
| 103 | * Hydra_Software_Devel/10 3/8/04 3:18p syang |
|---|
| 104 | * PR 10012: Added 4 bits shift for Desc offset |
|---|
| 105 | * |
|---|
| 106 | * Hydra_Software_Devel/9 2/6/04 4:48p syang |
|---|
| 107 | * PR 9655: added low 4 bits cutting for "next desc" setting |
|---|
| 108 | * |
|---|
| 109 | * Hydra_Software_Devel/8 2/4/04 3:01p syang |
|---|
| 110 | * PR 9608: 1). added init for hMemDma / hPciDma of Channel, hDma of |
|---|
| 111 | * MemDma / PciDma and hChannel of Queue; 2). split CallBackFunc type def |
|---|
| 112 | * to mem and pci versions; 3). fixed typo in TranHandle def; 4).leave |
|---|
| 113 | * critical section before calling BINT func; 5). fixed a bug with |
|---|
| 114 | * nextDesc in Desc info setting; 6). use wake to start dma as in sleep |
|---|
| 115 | * mode; 7). corrected typo in the asserts of Queue_CreateTran. |
|---|
| 116 | * |
|---|
| 117 | * Hydra_Software_Devel/7 12/29/03 3:59p marcusk |
|---|
| 118 | * PR9117: Updated with changes required to support interrupt ids rather |
|---|
| 119 | * than strings. |
|---|
| 120 | * |
|---|
| 121 | * Hydra_Software_Devel/6 11/19/03 6:54p syang |
|---|
| 122 | * added desc addr conv from virtual to mem bus offset |
|---|
| 123 | * |
|---|
| 124 | * Hydra_Software_Devel/5 10/24/03 2:53p syang |
|---|
| 125 | * changed to use PciBusAddr and MemBusAddr from SrcBusAddr and |
|---|
| 126 | * DstBusAddr. I think the new addr model is more natural to the way how |
|---|
| 127 | * user gets the addr |
|---|
| 128 | * |
|---|
| 129 | * Hydra_Software_Devel/4 10/23/03 6:18p syang |
|---|
| 130 | * to make linux comipler silent |
|---|
| 131 | * |
|---|
| 132 | * Hydra_Software_Devel/3 10/23/03 4:20p syang |
|---|
| 133 | * adjusted sub-module implementaion overview |
|---|
| 134 | * |
|---|
| 135 | * Hydra_Software_Devel/2 10/23/03 3:16p syang |
|---|
| 136 | * added real pci dma implementation |
|---|
| 137 | * |
|---|
| 138 | * Hydra_Software_Devel/1 9/25/03 7:01p syang |
|---|
| 139 | * init version, from scratch |
|---|
| 140 | * |
|---|
| 141 | ***************************************************************************/ |
|---|
| 142 | |
|---|
| 143 | #include "bdma_pci_priv.h" |
|---|
| 144 | #include "bkni.h" |
|---|
| 145 | #include "bchp_pci_dma.h" |
|---|
| 146 | #include "bchp_common.h" |
|---|
| 147 | #include "bchp_hif_intr2.h" |
|---|
| 148 | #include "bchp_int_id_hif_intr2.h" |
|---|
| 149 | |
|---|
| 150 | BDBG_MODULE(BDMA_PCI_PRIV); |
|---|
| 151 | |
|---|
| 152 | #define BDMA_P_PCI_LAST_BLK 1 |
|---|
| 153 | #define BDMA_P_PCI_FIRE_INTR 1 |
|---|
| 154 | |
|---|
| 155 | /*************************************************************************** |
|---|
| 156 | * |
|---|
| 157 | * Utility functions used by BDMA |
|---|
| 158 | * |
|---|
| 159 | ***************************************************************************/ |
|---|
| 160 | /*-------------------------------------------------------------------------- |
|---|
| 161 | * To be called by BDMA API func before taking real action, to get dma mutex |
|---|
| 162 | * WITH block, ideally for user mode |
|---|
| 163 | */ |
|---|
| 164 | BERR_Code BDMA_P_Pci_AcquireMutex( |
|---|
| 165 | BDMA_Pci_Handle hPciDma, |
|---|
| 166 | BKNI_MutexHandle *phMutex ) |
|---|
| 167 | { |
|---|
| 168 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 169 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 170 | |
|---|
| 171 | BDMA_P_PCI_GET_CONTEXT(hPciDma, pPciDma); |
|---|
| 172 | if ( NULL == pPciDma ) |
|---|
| 173 | { |
|---|
| 174 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 175 | goto BDMA_P_Done_Pci_AcquireMutex; |
|---|
| 176 | } |
|---|
| 177 | |
|---|
| 178 | BDBG_ASSERT( NULL != phMutex ); |
|---|
| 179 | *phMutex = pPciDma->hDma->hMutex; |
|---|
| 180 | |
|---|
| 181 | /* hPciDma passed the magic check, we trust every thing pointed by it now */ |
|---|
| 182 | eResult = BKNI_AcquireMutex(pPciDma->hDma->hMutex); |
|---|
| 183 | |
|---|
| 184 | BDMA_P_Done_Pci_AcquireMutex: |
|---|
| 185 | return BERR_TRACE(eResult); |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | |
|---|
| 189 | /*************************************************************************** |
|---|
| 190 | * |
|---|
| 191 | * Static tool functions used in this file |
|---|
| 192 | * |
|---|
| 193 | ***************************************************************************/ |
|---|
| 194 | |
|---|
| 195 | /*-------------------------------------------------------------------------- |
|---|
| 196 | * To be called to get PciDma context ptr from a Tran ptr. The PciDma handle |
|---|
| 197 | * from the Tran record is validated by black magic, and the Engine Id is |
|---|
| 198 | * checked to make sure the Tran was really created with PciDma handle |
|---|
| 199 | */ |
|---|
| 200 | static BERR_Code BDMA_P_Pci_GetPciDmaPtrFromTran_isr( |
|---|
| 201 | BDMA_P_QueueEntry * pTran, |
|---|
| 202 | BDMA_P_Pci_Context ** ppPciDma ) |
|---|
| 203 | { |
|---|
| 204 | /* assert para from our private code */ |
|---|
| 205 | BDBG_ASSERT( NULL != pTran ); |
|---|
| 206 | BDBG_ASSERT( NULL != ppPciDma ); |
|---|
| 207 | |
|---|
| 208 | *ppPciDma = (BDMA_P_Pci_Context *) BDMA_P_Queue_GetEngine_isr( pTran->hQueue ); |
|---|
| 209 | |
|---|
| 210 | if (NULL != *ppPciDma) |
|---|
| 211 | return BERR_SUCCESS; |
|---|
| 212 | else |
|---|
| 213 | return BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 214 | } |
|---|
| 215 | |
|---|
| 216 | #define BDMA_P_PCI_WORD_ALIGN_MASK 0x3 |
|---|
| 217 | /*-------------------------------------------------------------------------- |
|---|
| 218 | * To be called to set block info for a block, it does validate the block |
|---|
| 219 | * info provided |
|---|
| 220 | */ |
|---|
| 221 | static BERR_Code BDMA_P_Pci_SetBlockDesc_isr( |
|---|
| 222 | BDMA_P_Pci_Context * pPciDma, |
|---|
| 223 | BDMA_P_QueueEntry * pBlock, |
|---|
| 224 | bool bCachedDscrp, |
|---|
| 225 | uint32_t ulMemBusAddr, |
|---|
| 226 | uint32_t ulPciBusAddr, |
|---|
| 227 | uint32_t ulBlockSize, |
|---|
| 228 | BDMA_TranDir eTranDirection ) |
|---|
| 229 | { |
|---|
| 230 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 231 | uint32_t *pulDesc; |
|---|
| 232 | uint32_t ulTranDir; |
|---|
| 233 | uint32_t ulSwapMode; |
|---|
| 234 | |
|---|
| 235 | /* assert para from our private code */ |
|---|
| 236 | BDBG_ASSERT( NULL != pPciDma ); |
|---|
| 237 | BDBG_ASSERT( NULL != pBlock ); |
|---|
| 238 | |
|---|
| 239 | /* validate the parameters passed in from user */ |
|---|
| 240 | if ( eTranDirection >= BDMA_TranDir_eInvalid ) |
|---|
| 241 | { |
|---|
| 242 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 243 | goto BDMA_P_Done_Pci_SetBlockDesc; |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | if ( (ulPciBusAddr | ulMemBusAddr | ulBlockSize) & |
|---|
| 247 | BDMA_P_PCI_WORD_ALIGN_MASK ) |
|---|
| 248 | { |
|---|
| 249 | eResult = BERR_TRACE(BDMA_ERR_NOT_WORD_ALIGNED); |
|---|
| 250 | goto BDMA_P_Done_Pci_SetBlockDesc; |
|---|
| 251 | } |
|---|
| 252 | if ( (4>ulBlockSize) || (ulBlockSize>BDMA_P_PCI_MAX_BLOCK_SIZE) ) |
|---|
| 253 | { |
|---|
| 254 | eResult = BERR_TRACE(BDMA_ERR_SIZE_OUT_RANGE); |
|---|
| 255 | goto BDMA_P_Done_Pci_SetBlockDesc; |
|---|
| 256 | } |
|---|
| 257 | |
|---|
| 258 | /* calc HW value for tran dir and swap mode */ |
|---|
| 259 | ulTranDir = ( (BDMA_TranDir_ePciDeviceToSdram == eTranDirection)? |
|---|
| 260 | (BCHP_PCI_DMA_DESC_WORD2_DMA_DIRECTION_PCI_TO_MEMORY) : |
|---|
| 261 | (BCHP_PCI_DMA_DESC_WORD2_DMA_DIRECTION_MEMORY_TO_PCI) ); |
|---|
| 262 | if ( BDMA_SwapMode_eNoSwap == pPciDma->eSwapMode ) |
|---|
| 263 | { |
|---|
| 264 | ulSwapMode = BCHP_PCI_DMA_DESC_WORD3_ENDIAN_XLATE_MODE_NO_SWAP; |
|---|
| 265 | } |
|---|
| 266 | else if ( BDMA_SwapMode_e0123To3210 == pPciDma->eSwapMode ) |
|---|
| 267 | { |
|---|
| 268 | ulSwapMode = BCHP_PCI_DMA_DESC_WORD3_ENDIAN_XLATE_MODE_SWAP_32; |
|---|
| 269 | } |
|---|
| 270 | else |
|---|
| 271 | { |
|---|
| 272 | ulSwapMode = BCHP_PCI_DMA_DESC_WORD3_ENDIAN_XLATE_MODE_SWAP_16_IN_32; |
|---|
| 273 | } |
|---|
| 274 | |
|---|
| 275 | pulDesc = (bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 276 | |
|---|
| 277 | /* set descriptor: only the last block needs to set INTR_ENABLE and LAST bits, |
|---|
| 278 | * and the INTR_ENABLE is always set, on matter it is a sync or async Tran. */ |
|---|
| 279 | *(pulDesc ) = BCHP_FIELD_DATA( PCI_DMA_DESC_WORD0, MEMORY_ADDRESS, ulMemBusAddr ); |
|---|
| 280 | *(pulDesc+1) = BCHP_FIELD_DATA( PCI_DMA_DESC_WORD1, PCI_ADDRESS, ulPciBusAddr ); |
|---|
| 281 | *(pulDesc+2) = |
|---|
| 282 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD2, DMA_DIRECTION, ulTranDir ) | |
|---|
| 283 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD2, DMA_TRANSFER_SIZE, ulBlockSize ); |
|---|
| 284 | *(pulDesc+3) = |
|---|
| 285 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR, |
|---|
| 286 | (pBlock + 1)->ulDescPhysAddr >> |
|---|
| 287 | BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT ) | |
|---|
| 288 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, ENDIAN_XLATE_MODE, ulSwapMode ); |
|---|
| 289 | |
|---|
| 290 | BDMA_P_Done_Pci_SetBlockDesc: |
|---|
| 291 | return eResult; |
|---|
| 292 | } |
|---|
| 293 | |
|---|
| 294 | #define BDMA_P_PCI_STATUS_IDLE BCHP_PCI_DMA_STATUS_DMA_STATUS_IDLE_STATE |
|---|
| 295 | #define BDMA_P_PCI_STATUS_BUSY BCHP_PCI_DMA_STATUS_DMA_STATUS_BUSY_STATE |
|---|
| 296 | #define BDMA_P_PCI_STATUS_SLEEP BCHP_PCI_DMA_STATUS_DMA_STATUS_SLEEP_STATE |
|---|
| 297 | #define BDMA_P_PCI_WAKE_1ST_DESC 1 |
|---|
| 298 | #define BDMA_P_PCI_WAKE_LAST_DESC 0 |
|---|
| 299 | |
|---|
| 300 | #ifndef BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_SINGLE |
|---|
| 301 | #define BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_SINGLE BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_BURST_1 |
|---|
| 302 | #endif |
|---|
| 303 | #ifndef BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_BURST |
|---|
| 304 | #define BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_BURST BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_BURST_16 |
|---|
| 305 | #endif |
|---|
| 306 | |
|---|
| 307 | /*-------------------------------------------------------------------------- |
|---|
| 308 | * To be called to modify the last act block's desc to work as last block, |
|---|
| 309 | * and to flush cached descriptors |
|---|
| 310 | */ |
|---|
| 311 | static BERR_Code BDMA_P_Pci_Tran_PrepareStart_isr( |
|---|
| 312 | BDMA_P_QueueEntry * pTran, |
|---|
| 313 | BDMA_P_QueueHandle hQueue, |
|---|
| 314 | BMEM_Handle hMemory, |
|---|
| 315 | uint32_t ulNumActBlocks ) /* new NumActBlocks */ |
|---|
| 316 | { |
|---|
| 317 | BDMA_P_QueueContext * pQueue; |
|---|
| 318 | BDMA_P_QueueEntry *pBlock; |
|---|
| 319 | uint32_t *pulDesc; |
|---|
| 320 | uint32_t ulNextOffset; |
|---|
| 321 | uint32_t ulWord3; |
|---|
| 322 | volatile uint32_t ulCheck; |
|---|
| 323 | #if BDMA_P_CHECK_NEXT_DESC |
|---|
| 324 | int iLoopCntr; |
|---|
| 325 | #endif |
|---|
| 326 | |
|---|
| 327 | BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue ); |
|---|
| 328 | BDBG_ASSERT( NULL != pQueue ); |
|---|
| 329 | |
|---|
| 330 | /* in the case of re-use, the previous "last act block" might have wrong NEXT_DESC */ |
|---|
| 331 | pBlock = pTran + (pTran->ulNumActBlocks - 1); |
|---|
| 332 | if ((ulNumActBlocks != pTran->ulNumActBlocks) && |
|---|
| 333 | (0 < pTran->ulNumActBlocks)) |
|---|
| 334 | { |
|---|
| 335 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 336 | |
|---|
| 337 | *(pulDesc+2) &= ~( |
|---|
| 338 | BCHP_MASK(PCI_DMA_DESC_WORD2, INTERRUPT_ENABLE)); |
|---|
| 339 | ulWord3 = *(pulDesc+3) & ~( |
|---|
| 340 | BCHP_MASK(PCI_DMA_DESC_WORD3, LAST_RECORD_INDICATOR) | |
|---|
| 341 | BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)); |
|---|
| 342 | |
|---|
| 343 | ulNextOffset = |
|---|
| 344 | (pBlock + 1)->ulDescPhysAddr >> BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT; |
|---|
| 345 | |
|---|
| 346 | *(pulDesc+3) = ulWord3 | |
|---|
| 347 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR, ulNextOffset); |
|---|
| 348 | } |
|---|
| 349 | |
|---|
| 350 | /* modify new "last act block" desc */ |
|---|
| 351 | pBlock = pTran + (ulNumActBlocks - 1); |
|---|
| 352 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 353 | *(pulDesc+2) |= |
|---|
| 354 | BCHP_FIELD_DATA(PCI_DMA_DESC_WORD2, INTERRUPT_ENABLE, BDMA_P_PCI_FIRE_INTR); |
|---|
| 355 | ulWord3 = *(pulDesc+3) & ~( |
|---|
| 356 | BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)); |
|---|
| 357 | *(pulDesc+3) = ulWord3 | |
|---|
| 358 | BCHP_FIELD_DATA(PCI_DMA_DESC_WORD3, LAST_RECORD_INDICATOR, BDMA_P_PCI_LAST_BLK); |
|---|
| 359 | |
|---|
| 360 | /* check block setting */ |
|---|
| 361 | #if BDMA_P_CHECK_NEXT_DESC |
|---|
| 362 | pBlock = pTran; |
|---|
| 363 | for ( iLoopCntr = 0; iLoopCntr < (int) ulNumActBlocks; iLoopCntr++ ) |
|---|
| 364 | { |
|---|
| 365 | uint32_t ulSeeNextOffset; |
|---|
| 366 | |
|---|
| 367 | ulNextOffset = |
|---|
| 368 | (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT; |
|---|
| 369 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 370 | ulSeeNextOffset = BCHP_GET_FIELD_DATA(*(pulDesc+3), PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR); |
|---|
| 371 | if ((false == pBlock->bBlockInfoSet) || |
|---|
| 372 | (ulNextOffset != ulSeeNextOffset)) |
|---|
| 373 | { |
|---|
| 374 | BDBG_ASSERT((false == pBlock->bBlockInfoSet) || |
|---|
| 375 | (ulNextOffset == ulSeeNextOffset)); |
|---|
| 376 | return BERR_TRACE(BDMA_ERR_BLOCK_INFO_UNSET); |
|---|
| 377 | } |
|---|
| 378 | |
|---|
| 379 | pBlock += 1; |
|---|
| 380 | } |
|---|
| 381 | #endif |
|---|
| 382 | |
|---|
| 383 | if (pTran->bCachedDscrp) |
|---|
| 384 | BMEM_FlushCache_isr(hMemory, pTran->pulCachedDescAddr, |
|---|
| 385 | ulNumActBlocks * BDMA_P_PCI_NUM_WORDS_PER_DESC * 4); |
|---|
| 386 | |
|---|
| 387 | /* read back with un-cached addr to ensure previous writing completes */ |
|---|
| 388 | ulCheck = *((pTran + (ulNumActBlocks - 1))->pulDescAddr + 3); |
|---|
| 389 | if ((ulCheck & BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)) != 0) |
|---|
| 390 | { |
|---|
| 391 | BDBG_ERR(("desc writing error with preparing start")); |
|---|
| 392 | } |
|---|
| 393 | |
|---|
| 394 | return BERR_SUCCESS; |
|---|
| 395 | } |
|---|
| 396 | /*-------------------------------------------------------------------------- |
|---|
| 397 | * To be called to modify the last act block's desc to work as last block, |
|---|
| 398 | * and to flush cached descriptors |
|---|
| 399 | */ |
|---|
| 400 | static BERR_Code BDMA_P_Pci_Tran_PrepareStartSubset_isr( |
|---|
| 401 | BDMA_P_QueueEntry * pTran, |
|---|
| 402 | BDMA_P_QueueHandle hQueue, |
|---|
| 403 | BMEM_Handle hMemory, |
|---|
| 404 | uint32_t ulFirstBlock, |
|---|
| 405 | uint32_t ulNumActBlocks) /* new NumActBlocks */ |
|---|
| 406 | |
|---|
| 407 | { |
|---|
| 408 | BDMA_P_QueueContext * pQueue; |
|---|
| 409 | BDMA_P_QueueEntry *pBlock; |
|---|
| 410 | uint32_t *pulDesc; |
|---|
| 411 | uint32_t ulNextOffset, i=0; |
|---|
| 412 | uint32_t ulWord3; |
|---|
| 413 | volatile uint32_t ulCheck; |
|---|
| 414 | #if ((BDMA_P_CHECK_NEXT_DESC) && (BDBG_DEBUG_BUILD)) || \ |
|---|
| 415 | ((BDMA_P_CHECK_SCATTER_GATHER) && (BDBG_DEBUG_BUILD)) |
|---|
| 416 | int iLoopCntr; |
|---|
| 417 | #endif |
|---|
| 418 | BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue ); |
|---|
| 419 | BDBG_ASSERT( NULL != pQueue ); |
|---|
| 420 | |
|---|
| 421 | /* in the case of re-use, the previous "last act block" might have wrong NEXT_DESC */ |
|---|
| 422 | if ((ulNumActBlocks != pTran->ulNumActBlocks) && |
|---|
| 423 | (0 < pTran->ulNumActBlocks)) |
|---|
| 424 | { |
|---|
| 425 | pBlock = pTran + pTran->ulFirstBlock + (pTran->ulNumActBlocks - 1); |
|---|
| 426 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 427 | |
|---|
| 428 | *(pulDesc+2) &= ~( |
|---|
| 429 | BCHP_MASK(PCI_DMA_DESC_WORD2, INTERRUPT_ENABLE)); |
|---|
| 430 | ulWord3 = *(pulDesc+3) & ~( |
|---|
| 431 | BCHP_MASK(PCI_DMA_DESC_WORD3, LAST_RECORD_INDICATOR) | |
|---|
| 432 | BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)); |
|---|
| 433 | |
|---|
| 434 | ulNextOffset = |
|---|
| 435 | (pBlock + 1)->ulDescPhysAddr >> BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT; |
|---|
| 436 | |
|---|
| 437 | *(pulDesc+3) = ulWord3 | |
|---|
| 438 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR, ulNextOffset); |
|---|
| 439 | } |
|---|
| 440 | |
|---|
| 441 | pTran->ulFirstBlock = ulFirstBlock; |
|---|
| 442 | pBlock = pTran + ulFirstBlock; |
|---|
| 443 | while (i<(ulNumActBlocks - 1)) |
|---|
| 444 | { |
|---|
| 445 | pBlock = pTran + ulFirstBlock + i; |
|---|
| 446 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 447 | |
|---|
| 448 | *(pulDesc+2) &=~ |
|---|
| 449 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD2, INTERRUPT_ENABLE, BDMA_P_PCI_FIRE_INTR ); |
|---|
| 450 | |
|---|
| 451 | |
|---|
| 452 | ulNextOffset = (pBlock + 1)->ulDescPhysAddr >> BCHP_MEM_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT; |
|---|
| 453 | |
|---|
| 454 | *(pulDesc+3) |= BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR, ulNextOffset ); |
|---|
| 455 | i++; |
|---|
| 456 | } |
|---|
| 457 | /* modify new "last act block" desc */ |
|---|
| 458 | pBlock = pTran + ulFirstBlock + (ulNumActBlocks - 1); |
|---|
| 459 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 460 | *(pulDesc+2) |= |
|---|
| 461 | BCHP_FIELD_DATA(PCI_DMA_DESC_WORD2, INTERRUPT_ENABLE, BDMA_P_PCI_FIRE_INTR); |
|---|
| 462 | ulWord3 = *(pulDesc+3) & ~( |
|---|
| 463 | BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)); |
|---|
| 464 | *(pulDesc+3) = ulWord3 | |
|---|
| 465 | BCHP_FIELD_DATA(PCI_DMA_DESC_WORD3, LAST_RECORD_INDICATOR, BDMA_P_PCI_LAST_BLK); |
|---|
| 466 | |
|---|
| 467 | #if (BDMA_P_CHECK_NEXT_DESC) && (BDBG_DEBUG_BUILD) |
|---|
| 468 | pBlock = pTran; |
|---|
| 469 | for ( iLoopCntr = 0; iLoopCntr < (int) ulNumActBlocks; iLoopCntr++ ) |
|---|
| 470 | { |
|---|
| 471 | uint32_t ulSeeNextOffset; |
|---|
| 472 | |
|---|
| 473 | ulNextOffset = |
|---|
| 474 | (pBlock + 1)->ulDescPhysAddr >> BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT; |
|---|
| 475 | pulDesc = (pTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 476 | ulSeeNextOffset = BCHP_GET_FIELD_DATA(*(pulDesc+3), PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR); |
|---|
| 477 | |
|---|
| 478 | if ((ulNextOffset != ulSeeNextOffset) || |
|---|
| 479 | (false == pBlock->bBlockInfoSet)) |
|---|
| 480 | { |
|---|
| 481 | BDBG_ASSERT((ulNextOffset == ulSeeNextOffset) || |
|---|
| 482 | (false == pBlock->bBlockInfoSet)); |
|---|
| 483 | return BERR_TRACE(BDMA_ERR_BLOCK_INFO_UNSET); |
|---|
| 484 | } |
|---|
| 485 | } |
|---|
| 486 | #endif |
|---|
| 487 | |
|---|
| 488 | /* flush cached desc mem */ |
|---|
| 489 | if (pTran->bCachedDscrp) |
|---|
| 490 | BMEM_FlushCache_isr(hMemory, pTran->pulCachedDescAddr, |
|---|
| 491 | ulNumActBlocks * BDMA_P_PCI_NUM_WORDS_PER_DESC * 4); |
|---|
| 492 | |
|---|
| 493 | /* read back with un-cached addr to ensure previous writing completes */ |
|---|
| 494 | ulCheck = *((pTran + ulFirstBlock + (ulNumActBlocks - 1))->pulDescAddr + 3); |
|---|
| 495 | if ((ulCheck & BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)) != 0) |
|---|
| 496 | { |
|---|
| 497 | BDBG_ERR(("desc writing error with preparing start")); |
|---|
| 498 | } |
|---|
| 499 | |
|---|
| 500 | return BERR_SUCCESS; |
|---|
| 501 | } |
|---|
| 502 | |
|---|
| 503 | #ifndef BCHP_PCI_DMA_SCRATCH0 |
|---|
| 504 | #define BCHP_PCI_DMA_SCRATCH0 BCHP_PCI_DMA_DMA_SCRATCH0 |
|---|
| 505 | #endif |
|---|
| 506 | /*-------------------------------------------------------------------------- |
|---|
| 507 | Callback from base-module queue to wait till next descriptor safe to send to HW |
|---|
| 508 | */ |
|---|
| 509 | static void BDMA_P_Pci_SafeSendToHw_isr( |
|---|
| 510 | BDMA_P_QueueHandle hQueue, |
|---|
| 511 | BDMA_P_HwStatus* peHwStatus |
|---|
| 512 | ) |
|---|
| 513 | { |
|---|
| 514 | |
|---|
| 515 | uint32_t eStatus = (uint32_t)(*peHwStatus); |
|---|
| 516 | BDMA_P_Pci_Context *pPciDma; |
|---|
| 517 | BREG_Handle hRegister; |
|---|
| 518 | uint32_t ulRegValue; |
|---|
| 519 | BDMA_P_QueueContext * pQueue; |
|---|
| 520 | |
|---|
| 521 | |
|---|
| 522 | |
|---|
| 523 | BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue ); |
|---|
| 524 | |
|---|
| 525 | if (NULL == pQueue->pHeadTranInQ) |
|---|
| 526 | return; |
|---|
| 527 | |
|---|
| 528 | |
|---|
| 529 | pPciDma = (BDMA_P_Pci_Context *)(pQueue->hEngine); |
|---|
| 530 | hRegister = BDMA_P_GetRegisterHandle(pPciDma->hDma); |
|---|
| 531 | while (eStatus ==BDMA_P_PCI_STATUS_BUSY) |
|---|
| 532 | { |
|---|
| 533 | /* read CUR_DESC after STATUS, --> less chance to get wrong CUR_DESC? */ |
|---|
| 534 | ulRegValue = BREG_Read32( hRegister, BCHP_PCI_DMA_STATUS); |
|---|
| 535 | eStatus = BCHP_GET_FIELD_DATA( ulRegValue, PCI_DMA_STATUS, DMA_STATUS ); |
|---|
| 536 | } |
|---|
| 537 | |
|---|
| 538 | switch (eStatus){ |
|---|
| 539 | case (BDMA_P_PCI_STATUS_IDLE): |
|---|
| 540 | *peHwStatus = BDMA_P_HwStatus_eIdle; |
|---|
| 541 | break; |
|---|
| 542 | case (BDMA_P_PCI_STATUS_SLEEP): |
|---|
| 543 | *peHwStatus = BDMA_P_HwStatus_eSleep; |
|---|
| 544 | break; |
|---|
| 545 | } |
|---|
| 546 | } |
|---|
| 547 | |
|---|
| 548 | /*-------------------------------------------------------------------------- |
|---|
| 549 | * Callback from base-module queue to read the HW status |
|---|
| 550 | */ |
|---|
| 551 | static void BDMA_P_Pci_ReadHwRegs_isr( |
|---|
| 552 | void * pvEngine, |
|---|
| 553 | BDMA_P_HwStatus * peHwStatus, |
|---|
| 554 | uint32_t * pulCurrDesc, |
|---|
| 555 | uint32_t * pulScratchReg ) |
|---|
| 556 | { |
|---|
| 557 | BDMA_P_Pci_Context *pPciDma; |
|---|
| 558 | BREG_Handle hRegister; |
|---|
| 559 | uint32_t ulRegValue; |
|---|
| 560 | uint32_t ulStatus; |
|---|
| 561 | |
|---|
| 562 | /* assert para from our private code */ |
|---|
| 563 | BDBG_ASSERT( NULL != pvEngine); |
|---|
| 564 | BDBG_ASSERT( NULL != peHwStatus ); |
|---|
| 565 | BDBG_ASSERT( NULL != pulCurrDesc ); |
|---|
| 566 | BDBG_ASSERT( NULL != pulScratchReg ); |
|---|
| 567 | |
|---|
| 568 | pPciDma = (BDMA_P_Pci_Context *)(pvEngine); |
|---|
| 569 | hRegister = BDMA_P_GetRegisterHandle(pPciDma->hDma); |
|---|
| 570 | |
|---|
| 571 | /* read CUR_DESC after STATUS, --> less chance to get wrong CUR_DESC? */ |
|---|
| 572 | ulRegValue = BREG_Read32( hRegister, BCHP_PCI_DMA_STATUS ); |
|---|
| 573 | ulStatus = BCHP_GET_FIELD_DATA( ulRegValue, PCI_DMA_STATUS, DMA_STATUS ); |
|---|
| 574 | |
|---|
| 575 | ulRegValue = BREG_Read32( hRegister, BCHP_PCI_DMA_CUR_DESC_ADDR ); |
|---|
| 576 | *pulCurrDesc = |
|---|
| 577 | BCHP_GET_FIELD_DATA( ulRegValue, PCI_DMA_CUR_DESC_ADDR, DMA_CUR_DESC ) << 4; |
|---|
| 578 | |
|---|
| 579 | *pulScratchReg = BREG_Read32( hRegister, BCHP_PCI_DMA_SCRATCH0 ); |
|---|
| 580 | |
|---|
| 581 | if ( BDMA_P_PCI_STATUS_IDLE == ulStatus ) |
|---|
| 582 | { |
|---|
| 583 | BDBG_MSG(( "Pci DMA engine in idle state!" )); |
|---|
| 584 | *peHwStatus = BDMA_P_HwStatus_eIdle; |
|---|
| 585 | } |
|---|
| 586 | else if ( BDMA_P_PCI_STATUS_BUSY == ulStatus ) |
|---|
| 587 | { |
|---|
| 588 | *peHwStatus = BDMA_P_HwStatus_eBusy; |
|---|
| 589 | } |
|---|
| 590 | else if ( BDMA_P_PCI_STATUS_SLEEP == ulStatus ) |
|---|
| 591 | { |
|---|
| 592 | *peHwStatus = BDMA_P_HwStatus_eSleep; |
|---|
| 593 | } |
|---|
| 594 | else |
|---|
| 595 | { |
|---|
| 596 | BDBG_ERR(( "PCI DMA engine in Reservered state!!!" )); |
|---|
| 597 | *peHwStatus = BDMA_P_HwStatus_eUnknown; |
|---|
| 598 | BDBG_ASSERT(0); |
|---|
| 599 | } |
|---|
| 600 | } |
|---|
| 601 | |
|---|
| 602 | /*-------------------------------------------------------------------------- |
|---|
| 603 | * Callback from base-module queue to append two Trans' descriptors |
|---|
| 604 | */ |
|---|
| 605 | static void BDMA_P_Pci_AppendTranDesc_isr( |
|---|
| 606 | BDMA_P_QueueEntry * pCurrTran, |
|---|
| 607 | BDMA_P_QueueEntry * pNextTran ) |
|---|
| 608 | { |
|---|
| 609 | uint32_t *pulLastDesc ; |
|---|
| 610 | uint32_t ulNewDescPhysAddr; |
|---|
| 611 | uint32_t ulWord3; |
|---|
| 612 | |
|---|
| 613 | BDBG_ASSERT( NULL != pCurrTran ); |
|---|
| 614 | BDBG_ASSERT( NULL != pNextTran ); |
|---|
| 615 | |
|---|
| 616 | ulNewDescPhysAddr = pNextTran->ulDescPhysAddr; |
|---|
| 617 | pulLastDesc = (pCurrTran + (pCurrTran->ulNumActBlocks - 1))->pulDescAddr; |
|---|
| 618 | ulWord3 = *(pulLastDesc+3) & ~( |
|---|
| 619 | BCHP_MASK(PCI_DMA_DESC_WORD3, LAST_RECORD_INDICATOR) | |
|---|
| 620 | BCHP_MASK(PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)); |
|---|
| 621 | *(pulLastDesc+3) = ulWord3 | |
|---|
| 622 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR, |
|---|
| 623 | ulNewDescPhysAddr >> BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT ); |
|---|
| 624 | } |
|---|
| 625 | |
|---|
| 626 | /*-------------------------------------------------------------------------- |
|---|
| 627 | * Callback from base-module queue to send one Tran to HW. |
|---|
| 628 | * |
|---|
| 629 | * Note: It assume block info is already set for all blocks in this Tran |
|---|
| 630 | */ |
|---|
| 631 | static void BDMA_P_Pci_SendToHw_isr( |
|---|
| 632 | BDMA_P_QueueHandle hQueue, |
|---|
| 633 | BDMA_P_HwStatus eHwStatus, |
|---|
| 634 | bool bAppendInHw ) |
|---|
| 635 | { |
|---|
| 636 | BDMA_P_Pci_Context *pPciDma; |
|---|
| 637 | BDMA_P_QueueContext * pQueue; |
|---|
| 638 | BDMA_P_QueueEntry * p1stTran; |
|---|
| 639 | BDMA_P_QueueEntry * pLastTran; |
|---|
| 640 | BREG_Handle hRegister; |
|---|
| 641 | uint32_t ulNewDescPhysAddr; |
|---|
| 642 | uint32_t ulWord3; |
|---|
| 643 | uint32_t *pulLastDesc; |
|---|
| 644 | uint32_t ulMaxBurstSize; |
|---|
| 645 | volatile uint32_t ulCheck; |
|---|
| 646 | |
|---|
| 647 | BDMA_P_QUEUE_GET_CONTEXT( hQueue, pQueue ); |
|---|
| 648 | BDBG_ASSERT( NULL != pQueue ); |
|---|
| 649 | |
|---|
| 650 | pPciDma = (BDMA_P_Pci_Context *)(pQueue->hEngine); |
|---|
| 651 | hRegister = BDMA_P_GetRegisterHandle(pPciDma->hDma); |
|---|
| 652 | |
|---|
| 653 | p1stTran = pQueue->pHeadTranInQ; |
|---|
| 654 | if (NULL == p1stTran) |
|---|
| 655 | { |
|---|
| 656 | BDBG_ASSERT( p1stTran ); |
|---|
| 657 | return; |
|---|
| 658 | } |
|---|
| 659 | ulNewDescPhysAddr = pQueue->pHeadTranInQ->ulDescPhysAddr; |
|---|
| 660 | |
|---|
| 661 | /* write scratch reg so that other BDMA instance could check our status */ |
|---|
| 662 | pLastTran = pQueue->pTailTranInQ; |
|---|
| 663 | BDBG_ASSERT( pLastTran ); |
|---|
| 664 | BREG_Write32( hRegister, BCHP_PCI_DMA_SCRATCH0, |
|---|
| 665 | pQueue->ul1stDescPhysAddr | BDMA_P_WATER_MARK_SG_CLOSE ); |
|---|
| 666 | |
|---|
| 667 | /* send Trans queued in SW into HW */ |
|---|
| 668 | pLastTran = pQueue->pTailTranInHw; |
|---|
| 669 | if (bAppendInHw && (NULL != pLastTran)) |
|---|
| 670 | { |
|---|
| 671 | /* dynamically link to last tran in hw, which might and might not finished */ |
|---|
| 672 | pulLastDesc = (pLastTran + (pLastTran->ulNumActBlocks - 1))->pulDescAddr; |
|---|
| 673 | ulWord3 = *(pulLastDesc+3) & ~( |
|---|
| 674 | BCHP_MASK( PCI_DMA_DESC_WORD3, LAST_RECORD_INDICATOR) | |
|---|
| 675 | BCHP_MASK( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR)); |
|---|
| 676 | *(pulLastDesc+3) = ulWord3 | |
|---|
| 677 | BCHP_FIELD_DATA( PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR, |
|---|
| 678 | ulNewDescPhysAddr >> BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT); |
|---|
| 679 | |
|---|
| 680 | /* read back to force that mem writing completes before reg writing */ |
|---|
| 681 | ulCheck = *(pulLastDesc+3); |
|---|
| 682 | |
|---|
| 683 | BREG_Write32( hRegister, BCHP_PCI_DMA_LIST_CTRL, |
|---|
| 684 | BCHP_FIELD_DATA(PCI_DMA_LIST_CTRL, WAKE_MODE, BDMA_P_PCI_WAKE_LAST_DESC) | |
|---|
| 685 | BCHP_FIELD_DATA(PCI_DMA_LIST_CTRL, WAKE, 1) ); |
|---|
| 686 | } |
|---|
| 687 | else |
|---|
| 688 | { |
|---|
| 689 | ulNewDescPhysAddr = pQueue->pHeadTranInQ->ulDescPhysAddr |
|---|
| 690 | + ( pQueue->pHeadTranInQ->ulFirstBlock * 4 * BDMA_P_PCI_NUM_WORDS_PER_DESC); |
|---|
| 691 | /* must start from FIRST_DESC now */ |
|---|
| 692 | BREG_Write32( hRegister, BCHP_PCI_DMA_FIRST_DESC_ADRS, |
|---|
| 693 | BCHP_FIELD_DATA(PCI_DMA_FIRST_DESC_ADRS, DESC_ADRS, |
|---|
| 694 | ulNewDescPhysAddr >> BCHP_PCI_DMA_FIRST_DESC_ADRS_DESC_ADRS_SHIFT) ); |
|---|
| 695 | |
|---|
| 696 | ulMaxBurstSize = ( (BDMA_MaxBurstSize_eBurst1 == pPciDma->eMaxBurstSize )? |
|---|
| 697 | (BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_SINGLE) : |
|---|
| 698 | (BCHP_PCI_DMA_CTRL_DMA_BURST_SIZE_BURST) ); |
|---|
| 699 | |
|---|
| 700 | if ( BDMA_P_HwStatus_eIdle != eHwStatus ) |
|---|
| 701 | { |
|---|
| 702 | BREG_Write32( hRegister, BCHP_PCI_DMA_CTRL, |
|---|
| 703 | BCHP_FIELD_DATA( PCI_DMA_CTRL, DMA_BURST_SIZE, ulMaxBurstSize ) | |
|---|
| 704 | BCHP_FIELD_DATA( PCI_DMA_CTRL, DMA_RUN_STOP, |
|---|
| 705 | BCHP_PCI_DMA_CTRL_DMA_RUN_STOP_RUN ) ); |
|---|
| 706 | |
|---|
| 707 | BREG_Write32( hRegister, BCHP_PCI_DMA_LIST_CTRL, |
|---|
| 708 | BCHP_FIELD_DATA(PCI_DMA_LIST_CTRL, WAKE_MODE, BDMA_P_PCI_WAKE_1ST_DESC) | |
|---|
| 709 | BCHP_FIELD_DATA(PCI_DMA_LIST_CTRL, WAKE, 1) ); |
|---|
| 710 | } |
|---|
| 711 | else /* never started */ |
|---|
| 712 | { |
|---|
| 713 | BREG_Write32( hRegister, BCHP_PCI_DMA_CTRL, |
|---|
| 714 | BCHP_FIELD_DATA( PCI_DMA_CTRL, DMA_BURST_SIZE, ulMaxBurstSize ) | |
|---|
| 715 | BCHP_FIELD_DATA( PCI_DMA_CTRL, DMA_RUN_STOP, |
|---|
| 716 | BCHP_PCI_DMA_CTRL_DMA_RUN_STOP_RUN ) ); |
|---|
| 717 | } |
|---|
| 718 | } |
|---|
| 719 | } |
|---|
| 720 | |
|---|
| 721 | /*-------------------------------------------------------------------------- |
|---|
| 722 | * Callback from base-module queue to check NEXT_DESC_ADDR and print err msg |
|---|
| 723 | * dma engine reg read error happens |
|---|
| 724 | */ |
|---|
| 725 | static void BDMA_P_Pci_CheckNextDesc_isr( |
|---|
| 726 | BDMA_P_QueueEntry * pCurrTran, |
|---|
| 727 | BDMA_P_QueueEntry * pNextTran ) |
|---|
| 728 | { |
|---|
| 729 | BDMA_P_QueueEntry *pBlock; |
|---|
| 730 | uint32_t *pulDesc; |
|---|
| 731 | uint32_t ulSeeNextOffset, ulNextOffset; |
|---|
| 732 | int iLoopCntr; |
|---|
| 733 | |
|---|
| 734 | BDBG_ASSERT( NULL != pCurrTran ); |
|---|
| 735 | |
|---|
| 736 | pBlock = pCurrTran; |
|---|
| 737 | for ( iLoopCntr = 0; iLoopCntr < (int) pCurrTran->ulNumActBlocks; iLoopCntr++ ) |
|---|
| 738 | { |
|---|
| 739 | { |
|---|
| 740 | if (NULL != pNextTran) |
|---|
| 741 | ulNextOffset = ((iLoopCntr < (int) (pCurrTran->ulNumActBlocks - 1))? |
|---|
| 742 | (pBlock + 1)->ulDescPhysAddr : pNextTran->ulDescPhysAddr); |
|---|
| 743 | else |
|---|
| 744 | ulNextOffset = ((iLoopCntr < (int) (pCurrTran->ulNumActBlocks - 1))? |
|---|
| 745 | (pBlock + 1)->ulDescPhysAddr : 0); |
|---|
| 746 | pulDesc = pBlock->pulDescAddr; |
|---|
| 747 | ulSeeNextOffset = (BCHP_GET_FIELD_DATA(*(pulDesc+3), PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR) << |
|---|
| 748 | BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT); |
|---|
| 749 | |
|---|
| 750 | if (ulNextOffset != ulSeeNextOffset) |
|---|
| 751 | { |
|---|
| 752 | BDBG_ERR(("Bad next_desc: desc 0x%08lx, next_desc 0x%08lx (should be 0x%08lx)", |
|---|
| 753 | pBlock->ulDescPhysAddr, ulSeeNextOffset, ulNextOffset)); |
|---|
| 754 | BDBG_ERR(("tran_desc 0x%08lx, NumActBlk %d, Blck %d", |
|---|
| 755 | pCurrTran->ulDescPhysAddr, pCurrTran->ulNumActBlocks, iLoopCntr)); |
|---|
| 756 | |
|---|
| 757 | /*BDBG_ASSERT(ulNextOffset != ulSeeNextOffset);*/ |
|---|
| 758 | } |
|---|
| 759 | #if 0 |
|---|
| 760 | else if (iLoopCntr == (int) (pCurrTran->ulNumActBlocks - 1)) |
|---|
| 761 | { |
|---|
| 762 | /* XXX extra print make system busy, and shows HW reg reading problem */ |
|---|
| 763 | BDBG_MSG(("good next_desc: desc 0x%08lx (blck %d), next_desc 0x%08lx", |
|---|
| 764 | pBlock->ulDescPhysAddr, iLoopCntr, ulSeeNextOffset)); |
|---|
| 765 | } |
|---|
| 766 | #endif |
|---|
| 767 | pBlock++; |
|---|
| 768 | } |
|---|
| 769 | |
|---|
| 770 | |
|---|
| 771 | |
|---|
| 772 | |
|---|
| 773 | ulNextOffset = ((iLoopCntr == (int) (pCurrTran->ulNumActBlocks - 1)) && |
|---|
| 774 | (NULL != pNextTran))? |
|---|
| 775 | pNextTran->ulDescPhysAddr : (pBlock + 1)->ulDescPhysAddr; |
|---|
| 776 | pulDesc = (pCurrTran->bCachedDscrp)? pBlock->pulCachedDescAddr : pBlock->pulDescAddr; |
|---|
| 777 | ulSeeNextOffset = (BCHP_GET_FIELD_DATA(*(pulDesc+3), PCI_DMA_DESC_WORD3, NEXT_DESC_ADDR) << |
|---|
| 778 | BCHP_PCI_DMA_DESC_WORD3_NEXT_DESC_ADDR_SHIFT); |
|---|
| 779 | |
|---|
| 780 | if (ulNextOffset != ulSeeNextOffset) |
|---|
| 781 | { |
|---|
| 782 | BDBG_ERR(("Bad next_desc: desc 0x%80x, next_desc 0x%80x (should be 0x%80x)", |
|---|
| 783 | pulDesc, ulSeeNextOffset, ulNextOffset)); |
|---|
| 784 | /*BDBG_ASSERT(ulNextOffset != ulSeeNextOffset);*/ |
|---|
| 785 | } |
|---|
| 786 | } |
|---|
| 787 | } |
|---|
| 788 | |
|---|
| 789 | |
|---|
| 790 | /*************************************************************************** |
|---|
| 791 | * |
|---|
| 792 | * "Dma Done" interrupt handler (call back ) function |
|---|
| 793 | * |
|---|
| 794 | ***************************************************************************/ |
|---|
| 795 | |
|---|
| 796 | /*************************************************************************** |
|---|
| 797 | * To be called by the BINT module as the "dma done" interrupt handler (call |
|---|
| 798 | * back func). It records the just completed Tran's result, calls the user's |
|---|
| 799 | * call back function to futher process the DMA result if the Tran is async, |
|---|
| 800 | * (i.e. if it has a user's call back func). |
|---|
| 801 | */ |
|---|
| 802 | static void BDMA_P_Pci_DoneCallBack_isr( |
|---|
| 803 | void * pParm1, /* pPciDma */ |
|---|
| 804 | int parm2 ) /* not used */ |
|---|
| 805 | { |
|---|
| 806 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 807 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 808 | |
|---|
| 809 | BSTD_UNUSED(parm2); |
|---|
| 810 | BDMA_P_PCI_GET_CONTEXT(pParm1, pPciDma); |
|---|
| 811 | if ( NULL == pPciDma ) |
|---|
| 812 | { |
|---|
| 813 | eResult = BERR_TRACE( BERR_INVALID_PARAMETER ); |
|---|
| 814 | BDBG_ERR(( "Invaid pParm1 to BDMA_P_Pci_DoneCallBack_isr_isr!" )); |
|---|
| 815 | goto BDMA_P_Done_Pci_DoneCallBack_isr; |
|---|
| 816 | } |
|---|
| 817 | |
|---|
| 818 | /* read status from HW and update records */ |
|---|
| 819 | BDMA_P_Queue_CheckHwAndSendNewReq_isr( pPciDma->hQueue ); |
|---|
| 820 | |
|---|
| 821 | BDMA_P_Done_Pci_DoneCallBack_isr: |
|---|
| 822 | return; |
|---|
| 823 | } |
|---|
| 824 | |
|---|
| 825 | |
|---|
| 826 | /*************************************************************************** |
|---|
| 827 | * |
|---|
| 828 | * API support functions |
|---|
| 829 | * |
|---|
| 830 | ***************************************************************************/ |
|---|
| 831 | |
|---|
| 832 | /*-------------------------------------------------------------------------- |
|---|
| 833 | * To be called to init pci dma engine: 1). init Hw, 2). create queue, 3). |
|---|
| 834 | * create call-back, 4). init crpto setting. |
|---|
| 835 | */ |
|---|
| 836 | BERR_Code BDMA_P_Pci_Init( |
|---|
| 837 | BDMA_P_Pci_Context * pPciDma, |
|---|
| 838 | const BDMA_Pci_Settings *pSettings, |
|---|
| 839 | uint32_t ulL2IntrBintId ) |
|---|
| 840 | { |
|---|
| 841 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 842 | BDMA_Handle hDma; |
|---|
| 843 | BMEM_Handle hMemory = NULL; /* init to silence linux comipler */ |
|---|
| 844 | BDMA_P_QueueHandle hQueue = NULL; |
|---|
| 845 | BINT_CallbackHandle hCallBack = NULL; |
|---|
| 846 | |
|---|
| 847 | BDBG_ASSERT( NULL != pPciDma); |
|---|
| 848 | |
|---|
| 849 | BDMA_P_PCI_SET_BLACK_MAGIC( pPciDma ); |
|---|
| 850 | |
|---|
| 851 | /* init HW */ |
|---|
| 852 | hDma = pPciDma->hDma; |
|---|
| 853 | |
|---|
| 854 | /* create Tran queue */ |
|---|
| 855 | hMemory = BDMA_P_GetMemoryHandle( hDma ); |
|---|
| 856 | eResult = BDMA_P_Queue_Create( |
|---|
| 857 | &hQueue, (void *) pPciDma, hMemory, BDMA_P_PCI_NUM_WORDS_PER_DESC, |
|---|
| 858 | (BDMA_P_CmnSettings *)pSettings, BDMA_P_Pci_ReadHwRegs_isr, |
|---|
| 859 | BDMA_P_Pci_AppendTranDesc_isr, BDMA_P_Pci_SendToHw_isr, |
|---|
| 860 | BDMA_P_Pci_CheckNextDesc_isr, BDMA_P_Pci_SafeSendToHw_isr); |
|---|
| 861 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Pci_Init ); |
|---|
| 862 | pPciDma->hQueue = hQueue; |
|---|
| 863 | |
|---|
| 864 | if (pSettings->bSupportCallBack) |
|---|
| 865 | { |
|---|
| 866 | /* create done-interrupt call back |
|---|
| 867 | * no need to create call back for BCHP_INT_ID_PCI_DMA_ERR_INTR, |
|---|
| 868 | * since PI already checks size / error without sending HW ??? */ |
|---|
| 869 | /* BCHP_INT_ID_PCI_DMA_0_INTR, or BCHP_INT_ID_PCI_DMA_1_INTR */ |
|---|
| 870 | eResult = BINT_CreateCallback( |
|---|
| 871 | &hCallBack, BDMA_P_GetInterruptHandle( hDma ), |
|---|
| 872 | ulL2IntrBintId, BDMA_P_Pci_DoneCallBack_isr, |
|---|
| 873 | (void *)pPciDma, 0 ); |
|---|
| 874 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Pci_Init ); |
|---|
| 875 | pPciDma->hCallBack = hCallBack; |
|---|
| 876 | |
|---|
| 877 | eResult = BINT_ClearCallback( hCallBack ); |
|---|
| 878 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Pci_Init ); |
|---|
| 879 | eResult = BINT_EnableCallback( hCallBack ); |
|---|
| 880 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Pci_Init ); |
|---|
| 881 | } |
|---|
| 882 | |
|---|
| 883 | /* init op */ |
|---|
| 884 | pPciDma->eSwapMode = BDMA_SwapMode_eNoSwap; |
|---|
| 885 | pPciDma->eMaxBurstSize = BDMA_MaxBurstSize_eBurst16; |
|---|
| 886 | |
|---|
| 887 | return eResult; |
|---|
| 888 | |
|---|
| 889 | BDMA_P_Err_Pci_Init: |
|---|
| 890 | BDMA_P_Pci_UnInit( pPciDma ); |
|---|
| 891 | |
|---|
| 892 | return BERR_TRACE(eResult); |
|---|
| 893 | } |
|---|
| 894 | |
|---|
| 895 | /*-------------------------------------------------------------------------- |
|---|
| 896 | * To be called to uninit pci dma engine: destroy queue and call-back |
|---|
| 897 | */ |
|---|
| 898 | BERR_Code BDMA_P_Pci_UnInit( |
|---|
| 899 | BDMA_P_Pci_Context * pPciDma ) |
|---|
| 900 | { |
|---|
| 901 | BDBG_ASSERT( NULL != pPciDma); |
|---|
| 902 | |
|---|
| 903 | if ( NULL != pPciDma->hCallBack ) |
|---|
| 904 | { |
|---|
| 905 | BINT_DisableCallback( pPciDma->hCallBack ); |
|---|
| 906 | BINT_DestroyCallback( pPciDma->hCallBack ); |
|---|
| 907 | } |
|---|
| 908 | if ( NULL != pPciDma->hQueue ) |
|---|
| 909 | BDMA_P_Queue_Destroy( pPciDma->hQueue, BDMA_P_GetMemoryHandle(pPciDma->hDma) ); |
|---|
| 910 | |
|---|
| 911 | return BERR_SUCCESS; |
|---|
| 912 | } |
|---|
| 913 | |
|---|
| 914 | |
|---|
| 915 | /*************************************************************************** |
|---|
| 916 | * |
|---|
| 917 | */ |
|---|
| 918 | BERR_Code BDMA_P_Pci_Create( |
|---|
| 919 | BDMA_Handle hDma, |
|---|
| 920 | BDMA_PciDmaEngine eEngine, |
|---|
| 921 | const BDMA_Pci_Settings *pSettings, |
|---|
| 922 | BDMA_Pci_Handle * phPciDma ) |
|---|
| 923 | { |
|---|
| 924 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 925 | BDMA_P_Context * pDma; |
|---|
| 926 | BDMA_P_Pci_Context *pPciDma = NULL; |
|---|
| 927 | |
|---|
| 928 | uint32_t ulL2IntrBintId; |
|---|
| 929 | |
|---|
| 930 | if ( NULL != phPciDma ) |
|---|
| 931 | *phPciDma = NULL; |
|---|
| 932 | |
|---|
| 933 | BDMA_P_MAIN_GET_CONTEXT( hDma, pDma ); |
|---|
| 934 | if ( (NULL == phPciDma) || (NULL == pDma) || (eEngine >= BDMA_PciDmaEngine_eUnknown)) |
|---|
| 935 | { |
|---|
| 936 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 937 | goto BDMA_P_Err_Pci_Create; |
|---|
| 938 | } |
|---|
| 939 | |
|---|
| 940 | if ( NULL != BDMA_P_GetPciDmaHandle(hDma, eEngine) ) |
|---|
| 941 | { |
|---|
| 942 | /* memeory dma engine sub-module is already created */ |
|---|
| 943 | eResult = BERR_TRACE(BDMA_ERR_ENGINE_OCCUPIED); |
|---|
| 944 | goto BDMA_P_Err_Pci_Create; |
|---|
| 945 | } |
|---|
| 946 | |
|---|
| 947 | /* allocate pci dma sub-module's main context */ |
|---|
| 948 | pPciDma = (BDMA_P_Pci_Context *)BKNI_Malloc( sizeof(BDMA_P_Pci_Context) ); |
|---|
| 949 | if ( NULL == pPciDma ) |
|---|
| 950 | { |
|---|
| 951 | eResult = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY); |
|---|
| 952 | goto BDMA_P_Err_Pci_Create; |
|---|
| 953 | } |
|---|
| 954 | BKNI_Memset((void*)pPciDma, 0x0, sizeof(BDMA_P_Pci_Context)); |
|---|
| 955 | |
|---|
| 956 | ulL2IntrBintId = BCHP_INT_ID_PCI_DMA_DONE; |
|---|
| 957 | |
|---|
| 958 | /* init pci dma */ |
|---|
| 959 | pPciDma->hDma = hDma; |
|---|
| 960 | pPciDma->eEngine = eEngine; |
|---|
| 961 | eResult = BDMA_P_Pci_Init( pPciDma, pSettings, ulL2IntrBintId ); |
|---|
| 962 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Err_Pci_Create ); |
|---|
| 963 | |
|---|
| 964 | /* connect pci dma sub-module to dma module's main context */ |
|---|
| 965 | BDMA_P_SetPciDmaHandle( hDma, eEngine, pPciDma ); |
|---|
| 966 | |
|---|
| 967 | *phPciDma = pPciDma; |
|---|
| 968 | return eResult; |
|---|
| 969 | |
|---|
| 970 | BDMA_P_Err_Pci_Create: |
|---|
| 971 | |
|---|
| 972 | if ( NULL != pPciDma ) |
|---|
| 973 | BDMA_P_PCI_DESTROY_CONTEXT( pPciDma ); |
|---|
| 974 | |
|---|
| 975 | return BERR_TRACE(eResult); |
|---|
| 976 | } |
|---|
| 977 | |
|---|
| 978 | /*************************************************************************** |
|---|
| 979 | * |
|---|
| 980 | */ |
|---|
| 981 | BERR_Code BDMA_P_Pci_Destroy( |
|---|
| 982 | BDMA_Pci_Handle hPciDma ) |
|---|
| 983 | { |
|---|
| 984 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 985 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 986 | |
|---|
| 987 | BDMA_P_PCI_GET_CONTEXT(hPciDma, pPciDma); |
|---|
| 988 | if ( NULL == pPciDma ) |
|---|
| 989 | { |
|---|
| 990 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 991 | goto BDMA_P_Done_Pci_Destroy; |
|---|
| 992 | } |
|---|
| 993 | |
|---|
| 994 | /* disconnect pci dma sub-module to dma module's main context */ |
|---|
| 995 | BDMA_P_SetPciDmaHandle( pPciDma->hDma, pPciDma->eEngine, NULL ); |
|---|
| 996 | |
|---|
| 997 | /* destroy callBack and queue */ |
|---|
| 998 | BDMA_P_Pci_UnInit( pPciDma ); |
|---|
| 999 | BDMA_P_PCI_DESTROY_CONTEXT( pPciDma ); |
|---|
| 1000 | |
|---|
| 1001 | BDMA_P_Done_Pci_Destroy: |
|---|
| 1002 | return eResult; |
|---|
| 1003 | } |
|---|
| 1004 | |
|---|
| 1005 | /*************************************************************************** |
|---|
| 1006 | * |
|---|
| 1007 | */ |
|---|
| 1008 | BERR_Code BDMA_P_Pci_SetSwapMode_isr( |
|---|
| 1009 | BDMA_Pci_Handle hPciDma, |
|---|
| 1010 | BDMA_SwapMode eSwapMode ) |
|---|
| 1011 | { |
|---|
| 1012 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1013 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1014 | |
|---|
| 1015 | BDMA_P_PCI_GET_CONTEXT(hPciDma, pPciDma); |
|---|
| 1016 | if ( (NULL == pPciDma) || |
|---|
| 1017 | (eSwapMode >= BDMA_SwapMode_eInvalid) ) |
|---|
| 1018 | { |
|---|
| 1019 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1020 | goto BDMA_P_Done_Pci_SetSwapMode; |
|---|
| 1021 | } |
|---|
| 1022 | |
|---|
| 1023 | pPciDma->eSwapMode = eSwapMode; |
|---|
| 1024 | |
|---|
| 1025 | BDMA_P_Done_Pci_SetSwapMode: |
|---|
| 1026 | return eResult; |
|---|
| 1027 | } |
|---|
| 1028 | |
|---|
| 1029 | /*************************************************************************** |
|---|
| 1030 | * |
|---|
| 1031 | */ |
|---|
| 1032 | BERR_Code BDMA_P_Pci_SetMaxBurstSize_isr( |
|---|
| 1033 | BDMA_Pci_Handle hPciDma, |
|---|
| 1034 | BDMA_MaxBurstSize eMaxBurstSize ) |
|---|
| 1035 | { |
|---|
| 1036 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1037 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1038 | |
|---|
| 1039 | BDMA_P_PCI_GET_CONTEXT(hPciDma, pPciDma); |
|---|
| 1040 | if ( (NULL == pPciDma) || |
|---|
| 1041 | (eMaxBurstSize >= BDMA_MaxBurstSize_eInvalid) ) |
|---|
| 1042 | { |
|---|
| 1043 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1044 | goto BDMA_P_Done_Pci_SetMaxBurstSize; |
|---|
| 1045 | } |
|---|
| 1046 | |
|---|
| 1047 | pPciDma->eMaxBurstSize = eMaxBurstSize; |
|---|
| 1048 | |
|---|
| 1049 | BDMA_P_Done_Pci_SetMaxBurstSize: |
|---|
| 1050 | return eResult; |
|---|
| 1051 | } |
|---|
| 1052 | |
|---|
| 1053 | /*************************************************************************** |
|---|
| 1054 | * To be called to created a new Tran |
|---|
| 1055 | */ |
|---|
| 1056 | BERR_Code BDMA_P_Pci_Tran_Create_isr( |
|---|
| 1057 | BDMA_Pci_Handle hPciDma, |
|---|
| 1058 | uint32_t ulNumBlocks, |
|---|
| 1059 | bool bCachedDesc, |
|---|
| 1060 | BDMA_Pci_Tran_Handle * phTran ) |
|---|
| 1061 | { |
|---|
| 1062 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1063 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1064 | BDMA_P_QueueEntry * pTran; |
|---|
| 1065 | |
|---|
| 1066 | if ( NULL != phTran ) |
|---|
| 1067 | *phTran = NULL; |
|---|
| 1068 | |
|---|
| 1069 | BDMA_P_PCI_GET_CONTEXT( hPciDma, pPciDma ); |
|---|
| 1070 | if ( (NULL == pPciDma) || (NULL == phTran) ) |
|---|
| 1071 | { |
|---|
| 1072 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1073 | goto BDMA_P_Done_Pci_Tran_Create; |
|---|
| 1074 | } |
|---|
| 1075 | |
|---|
| 1076 | eResult = BDMA_P_Queue_CreateTran_isr( |
|---|
| 1077 | pPciDma->hQueue, ulNumBlocks, bCachedDesc, &pTran ); |
|---|
| 1078 | if ( BERR_SUCCESS == eResult ) |
|---|
| 1079 | *phTran = (BDMA_Pci_Tran_Handle ) pTran; |
|---|
| 1080 | |
|---|
| 1081 | BDMA_P_Done_Pci_Tran_Create: |
|---|
| 1082 | return BERR_TRACE(eResult); |
|---|
| 1083 | } |
|---|
| 1084 | |
|---|
| 1085 | /*************************************************************************** |
|---|
| 1086 | * To be called to set the block info for a Tran block. Input block info are |
|---|
| 1087 | * validated against the current engine state. |
|---|
| 1088 | */ |
|---|
| 1089 | BERR_Code BDMA_P_Pci_Tran_SetBlockInfo_isr( |
|---|
| 1090 | BDMA_Pci_Tran_Handle hTran, |
|---|
| 1091 | uint32_t ulBlockId, |
|---|
| 1092 | uint32_t ulMemBusAddr, |
|---|
| 1093 | uint32_t ulPciBusAddr, |
|---|
| 1094 | uint32_t ulBlockSize, |
|---|
| 1095 | BDMA_TranDir eTranDirection ) |
|---|
| 1096 | { |
|---|
| 1097 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1098 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1099 | BDMA_P_QueueEntry * pTran; |
|---|
| 1100 | BDMA_P_QueueEntry * pBlock; |
|---|
| 1101 | bool bLastBlock; |
|---|
| 1102 | |
|---|
| 1103 | BDMA_P_TRAN_GET_CONTEXT( hTran, pTran ); |
|---|
| 1104 | if ( NULL == pTran ) |
|---|
| 1105 | { |
|---|
| 1106 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1107 | goto BDMA_P_Done_Pci_Tran_SetBlockInfo; |
|---|
| 1108 | } |
|---|
| 1109 | |
|---|
| 1110 | if ( pTran->ulNumTranBlocks <= ulBlockId ) |
|---|
| 1111 | { |
|---|
| 1112 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1113 | goto BDMA_P_Done_Pci_Tran_SetBlockInfo; |
|---|
| 1114 | } |
|---|
| 1115 | |
|---|
| 1116 | eResult = BDMA_P_Pci_GetPciDmaPtrFromTran_isr( pTran, &pPciDma ); |
|---|
| 1117 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_SetBlockInfo ); |
|---|
| 1118 | |
|---|
| 1119 | /* validate addr, size and set desc */ |
|---|
| 1120 | bLastBlock = (pTran->ulNumTranBlocks == (ulBlockId+1)); |
|---|
| 1121 | pBlock = pTran + ulBlockId; |
|---|
| 1122 | eResult = BDMA_P_Pci_SetBlockDesc_isr( pPciDma, |
|---|
| 1123 | pBlock, |
|---|
| 1124 | pTran->bCachedDscrp, |
|---|
| 1125 | ulMemBusAddr, ulPciBusAddr, |
|---|
| 1126 | ulBlockSize, |
|---|
| 1127 | eTranDirection ); |
|---|
| 1128 | if ( BERR_SUCCESS == eResult ) |
|---|
| 1129 | pBlock->bBlockInfoSet = true; |
|---|
| 1130 | |
|---|
| 1131 | BDMA_P_Done_Pci_Tran_SetBlockInfo: |
|---|
| 1132 | return BERR_TRACE( eResult ); |
|---|
| 1133 | } |
|---|
| 1134 | |
|---|
| 1135 | /*************************************************************************** |
|---|
| 1136 | * To be called by both BDMA_P_Pci_Tran_Start_isrAndCallBack and |
|---|
| 1137 | * BDMA_P_Pci_Tran_Start_isr. BDMA_P_Pci_Tran_Start_isr should pass NULL for |
|---|
| 1138 | * pCallBackFunc_isr and pUserCallBackParam |
|---|
| 1139 | * |
|---|
| 1140 | * Note: when a Tran is sent to HW, interrupt is alwayas enabled. If the |
|---|
| 1141 | * Tran is async, the module's interrupt handler BDMA_P_Pci_DoneCallBack_isr |
|---|
| 1142 | * will call user's callback function. In the sync case, there is no user's |
|---|
| 1143 | * call back function to call, BDMA_P_Pci_DoneCallBack_isr_isr only sets the |
|---|
| 1144 | * internal record of the status, the ideal is that the user will check the |
|---|
| 1145 | * Tran's status in a waiting loop and process the Tran result synchronously. |
|---|
| 1146 | */ |
|---|
| 1147 | BERR_Code BDMA_P_Pci_Tran_Start_isr( |
|---|
| 1148 | BDMA_Pci_Tran_Handle hTran, |
|---|
| 1149 | uint32_t ulNumActBlocks, |
|---|
| 1150 | BDMA_Pci_CallbackFunc pCallBackFunc_isr, |
|---|
| 1151 | void * pUserCallBackParam ) |
|---|
| 1152 | { |
|---|
| 1153 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1154 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1155 | BDMA_P_QueueEntry * pTran; |
|---|
| 1156 | |
|---|
| 1157 | BDMA_P_TRAN_GET_CONTEXT( hTran, pTran ); |
|---|
| 1158 | if ( NULL == pTran ) |
|---|
| 1159 | { |
|---|
| 1160 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1161 | goto BDMA_P_Done_Pci_Tran_Start; |
|---|
| 1162 | } |
|---|
| 1163 | |
|---|
| 1164 | eResult = BDMA_P_Pci_GetPciDmaPtrFromTran_isr( pTran, &pPciDma ); |
|---|
| 1165 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Start ); |
|---|
| 1166 | |
|---|
| 1167 | eResult = BDMA_P_Pci_Tran_PrepareStart_isr( pTran, pPciDma->hQueue, |
|---|
| 1168 | BDMA_P_GetMemoryHandle(pPciDma->hDma), ulNumActBlocks); |
|---|
| 1169 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Start ); |
|---|
| 1170 | |
|---|
| 1171 | eResult = BDMA_P_Queue_StartTran_isr ( |
|---|
| 1172 | pPciDma->hQueue, pTran, ulNumActBlocks, false, |
|---|
| 1173 | (BDMA_P_CallbackFunc) pCallBackFunc_isr, pUserCallBackParam ); |
|---|
| 1174 | |
|---|
| 1175 | BDMA_P_Done_Pci_Tran_Start: |
|---|
| 1176 | return BERR_TRACE(eResult); |
|---|
| 1177 | } |
|---|
| 1178 | |
|---|
| 1179 | /*************************************************************************** |
|---|
| 1180 | */ |
|---|
| 1181 | |
|---|
| 1182 | BERR_Code BDMA_P_Pci_Tran_StartSubset_isr( |
|---|
| 1183 | BDMA_Mem_Tran_Handle hTran, |
|---|
| 1184 | uint32_t ulFirstBlock, |
|---|
| 1185 | uint32_t ulNumActBlocks, |
|---|
| 1186 | BDMA_Mem_CallbackFunc pCallBackFunc_isr, |
|---|
| 1187 | void * pUserCallBackParam ) |
|---|
| 1188 | { |
|---|
| 1189 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1190 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1191 | BDMA_P_QueueEntry * pTran; |
|---|
| 1192 | |
|---|
| 1193 | |
|---|
| 1194 | BDMA_P_TRAN_GET_CONTEXT( hTran, pTran ); |
|---|
| 1195 | if ( NULL == pTran ) |
|---|
| 1196 | { |
|---|
| 1197 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1198 | goto BDMA_P_Done_Pci_Tran_Start; |
|---|
| 1199 | } |
|---|
| 1200 | |
|---|
| 1201 | eResult = BDMA_P_Pci_GetPciDmaPtrFromTran_isr( pTran, &pPciDma ); |
|---|
| 1202 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Start ); |
|---|
| 1203 | |
|---|
| 1204 | eResult = BDMA_P_Pci_Tran_PrepareStartSubset_isr( pTran, pPciDma->hQueue, |
|---|
| 1205 | BDMA_P_GetMemoryHandle(pPciDma->hDma), ulFirstBlock, ulNumActBlocks); |
|---|
| 1206 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Start ); |
|---|
| 1207 | |
|---|
| 1208 | eResult = BDMA_P_Queue_StartTran_isr ( |
|---|
| 1209 | pPciDma->hQueue, pTran, ulNumActBlocks, false, |
|---|
| 1210 | (BDMA_P_CallbackFunc) pCallBackFunc_isr, pUserCallBackParam ); |
|---|
| 1211 | |
|---|
| 1212 | BDMA_P_Done_Pci_Tran_Start: |
|---|
| 1213 | return BERR_TRACE(eResult); |
|---|
| 1214 | } |
|---|
| 1215 | |
|---|
| 1216 | /*************************************************************************** |
|---|
| 1217 | * To be called by BDMA_Pci_Tran_GetStatus. It outputs the internal records |
|---|
| 1218 | * of the Tran directly. |
|---|
| 1219 | */ |
|---|
| 1220 | BERR_Code BDMA_P_Pci_Tran_GetStatus_isr( |
|---|
| 1221 | BDMA_Pci_Tran_Handle hTran, |
|---|
| 1222 | BDMA_TranStatus * peTranStatus ) |
|---|
| 1223 | { |
|---|
| 1224 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1225 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1226 | BDMA_P_QueueEntry * pTran; |
|---|
| 1227 | |
|---|
| 1228 | BDMA_P_TRAN_GET_CONTEXT( hTran, pTran ); |
|---|
| 1229 | if ( NULL == pTran ) |
|---|
| 1230 | { |
|---|
| 1231 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1232 | goto BDMA_P_Done_Pci_Tran_GetStatus; |
|---|
| 1233 | } |
|---|
| 1234 | |
|---|
| 1235 | eResult = BDMA_P_Pci_GetPciDmaPtrFromTran_isr( pTran, &pPciDma ); |
|---|
| 1236 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_GetStatus ); |
|---|
| 1237 | |
|---|
| 1238 | /* read status from HW and update Trans' records */ |
|---|
| 1239 | BDMA_P_Queue_CheckHwAndSendNewReq_isr( pPciDma->hQueue ); |
|---|
| 1240 | *peTranStatus = pTran->eStatus; |
|---|
| 1241 | return BERR_SUCCESS; |
|---|
| 1242 | |
|---|
| 1243 | BDMA_P_Done_Pci_Tran_GetStatus: |
|---|
| 1244 | return BERR_TRACE(eResult); |
|---|
| 1245 | } |
|---|
| 1246 | |
|---|
| 1247 | |
|---|
| 1248 | /*************************************************************************** |
|---|
| 1249 | * To be called by BDMA_Pci_Tran_Destroy. It free the queue entries occupied |
|---|
| 1250 | * this Tran |
|---|
| 1251 | */ |
|---|
| 1252 | BERR_Code BDMA_P_Pci_Tran_Destroy_isr( |
|---|
| 1253 | BDMA_Pci_Tran_Handle hTran ) |
|---|
| 1254 | { |
|---|
| 1255 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1256 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1257 | BDMA_P_QueueEntry * pTran; |
|---|
| 1258 | |
|---|
| 1259 | BDMA_P_TRAN_GET_CONTEXT( hTran, pTran ); |
|---|
| 1260 | if ( NULL == pTran ) |
|---|
| 1261 | { |
|---|
| 1262 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1263 | goto BDMA_P_Done_Pci_Tran_Destroy; |
|---|
| 1264 | } |
|---|
| 1265 | |
|---|
| 1266 | eResult = BDMA_P_Pci_GetPciDmaPtrFromTran_isr( pTran, &pPciDma ); |
|---|
| 1267 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Destroy ); |
|---|
| 1268 | |
|---|
| 1269 | /* tell queue module to free the queue entries of this */ |
|---|
| 1270 | eResult = BDMA_P_Queue_DestroyTran_isr ( pPciDma->hQueue, |
|---|
| 1271 | pTran ); |
|---|
| 1272 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Destroy ); |
|---|
| 1273 | |
|---|
| 1274 | return BERR_SUCCESS; |
|---|
| 1275 | |
|---|
| 1276 | BDMA_P_Done_Pci_Tran_Destroy: |
|---|
| 1277 | return BERR_TRACE(eResult); |
|---|
| 1278 | } |
|---|
| 1279 | |
|---|
| 1280 | /*************************************************************************** |
|---|
| 1281 | * To be called by BDMA_Pci_Tran_Reset. It resets the Tran into its |
|---|
| 1282 | * initially created state |
|---|
| 1283 | */ |
|---|
| 1284 | BERR_Code BDMA_P_Pci_Tran_Reset_isr( |
|---|
| 1285 | BDMA_Pci_Tran_Handle hTran ) |
|---|
| 1286 | { |
|---|
| 1287 | BERR_Code eResult = BERR_SUCCESS; |
|---|
| 1288 | BDMA_P_Pci_Context * pPciDma; |
|---|
| 1289 | BDMA_P_QueueEntry * pTran; |
|---|
| 1290 | |
|---|
| 1291 | BDMA_P_TRAN_GET_CONTEXT( hTran, pTran ); |
|---|
| 1292 | if ( NULL == pTran ) |
|---|
| 1293 | { |
|---|
| 1294 | eResult = BERR_TRACE(BERR_INVALID_PARAMETER); |
|---|
| 1295 | goto BDMA_P_Done_Pci_Tran_Reset; |
|---|
| 1296 | } |
|---|
| 1297 | |
|---|
| 1298 | eResult = BDMA_P_Pci_GetPciDmaPtrFromTran_isr( pTran, &pPciDma ); |
|---|
| 1299 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Reset ); |
|---|
| 1300 | |
|---|
| 1301 | /* tell queue module to reset this Tran into initially created state */ |
|---|
| 1302 | eResult = BDMA_P_Queue_ResetTran_isr ( pPciDma->hQueue, |
|---|
| 1303 | pTran ); |
|---|
| 1304 | BDMA_P_END_IF_ERR( eResult, BDMA_P_Done_Pci_Tran_Reset ); |
|---|
| 1305 | |
|---|
| 1306 | return BERR_SUCCESS; |
|---|
| 1307 | |
|---|
| 1308 | BDMA_P_Done_Pci_Tran_Reset: |
|---|
| 1309 | return BERR_TRACE(eResult); |
|---|
| 1310 | } |
|---|
| 1311 | |
|---|
| 1312 | |
|---|
| 1313 | /* End of File */ |
|---|