static xge_hal_status_e __hal_fifo_mempool_item_free(xge_hal_mempool_h mempoolh, void *memblock, int memblock_index, xge_hal_mempool_dma_t *dma_object, void *item, int index, int is_last, void *userdata) { int memblock_item_idx; xge_hal_fifo_txdl_priv_t *txdl_priv; #ifdef XGE_HAL_ALIGN_XMIT xge_hal_fifo_t *fifo = (xge_hal_fifo_t *)userdata; #endif xge_assert(item); txdl_priv = __hal_mempool_item_priv(mempoolh, memblock_index, item, &memblock_item_idx); xge_assert(txdl_priv); #ifdef XGE_HAL_ALIGN_XMIT if (fifo->config->alignment_size) { if (txdl_priv->align_dma_addr != 0) { xge_os_dma_unmap(fifo->channel.pdev, txdl_priv->align_dma_handle, txdl_priv->align_dma_addr, fifo->config->alignment_size * fifo->config->max_aligned_frags, XGE_OS_DMA_DIR_TODEVICE); txdl_priv->align_dma_addr = 0; } if (txdl_priv->align_vaddr != NULL) { xge_os_dma_free(fifo->channel.pdev, txdl_priv->align_vaddr, fifo->config->alignment_size * fifo->config->max_aligned_frags, &txdl_priv->align_dma_acch, &txdl_priv->align_dma_handle); txdl_priv->align_vaddr = NULL; } } #endif return XGE_HAL_OK; }
static xge_hal_status_e __hal_ring_mempool_item_alloc(xge_hal_mempool_h mempoolh, void *memblock, int memblock_index, xge_hal_mempool_dma_t *dma_object, void *item, int index, int is_last, void *userdata) { int i; xge_hal_ring_t *ring = (xge_hal_ring_t *)userdata; xge_assert(item); xge_assert(ring); /* format rxds array */ for (i=ring->rxds_per_block-1; i>=0; i--) { void *rxdblock_priv; xge_hal_ring_rxd_priv_t *rxd_priv; xge_hal_ring_rxd_1_t *rxdp; int reserve_index = index * ring->rxds_per_block + i; int memblock_item_idx; ring->reserved_rxds_arr[reserve_index] = (char *)item + (ring->rxds_per_block - 1 - i) * ring->rxd_size; /* Note: memblock_item_idx is index of the item within * the memblock. For instance, in case of three RxD-blocks * per memblock this value can be 0,1 or 2. */ rxdblock_priv = __hal_mempool_item_priv(mempoolh, memblock_index, item, &memblock_item_idx); rxdp = (xge_hal_ring_rxd_1_t *) ring->reserved_rxds_arr[reserve_index]; rxd_priv = (xge_hal_ring_rxd_priv_t *) (void *) ((char*)rxdblock_priv + ring->rxd_priv_size * i); /* pre-format per-RxD Ring's private */ rxd_priv->dma_offset = (char*)rxdp - (char*)memblock; rxd_priv->dma_addr = dma_object->addr + rxd_priv->dma_offset; rxd_priv->dma_handle = dma_object->handle; #ifdef XGE_DEBUG_ASSERT rxd_priv->dma_object = dma_object; #endif /* pre-format Host_Control */ #if defined(XGE_HAL_USE_5B_MODE) if (ring->buffer_mode == XGE_HAL_RING_QUEUE_BUFFER_MODE_5) { xge_hal_ring_rxd_5_t *rxdp_5 = (xge_hal_ring_rxd_5_t *)rxdp; #if defined(XGE_OS_PLATFORM_64BIT) xge_assert(memblock_index <= 0xFFFF); xge_assert(i <= 0xFFFF); /* store memblock's index */ rxdp_5->host_control = (u32)memblock_index << 16; /* store index of memblock's private */ rxdp_5->host_control |= (u32)(memblock_item_idx * ring->rxds_per_block + i); #else /* 32-bit case */ rxdp_5->host_control = (u32)rxd_priv; #endif } else { /* 1b and 3b modes */ rxdp->host_control = (u64)(ulong_t)rxd_priv; } #else /* 1b and 3b modes */ rxdp->host_control = (u64)(ulong_t)rxd_priv; #endif } __hal_ring_block_memblock_idx_set(item, memblock_index); if (is_last) { /* link last one with first one */ __hal_ring_rxdblock_link(mempoolh, ring, 0, index); } if (index > 0 ) { /* link this RxD block with previous one */ __hal_ring_rxdblock_link(mempoolh, ring, index, index-1); } return XGE_HAL_OK; }
/* * __hal_ring_mempool_item_alloc - Allocate List blocks for RxD block callback * @mempoolh: Handle to memory pool * @memblock: Address of this memory block * @memblock_index: Index of this memory block * @dma_object: dma object for this block * @item: Pointer to this item * @index: Index of this item in memory block * @is_last: If this is last item in the block * @userdata: Specific data of user * * This function is callback passed to __hal_mempool_create to create memory * pool for RxD block */ static vxge_hal_status_e __hal_ring_mempool_item_alloc( vxge_hal_mempool_h mempoolh, void *memblock, u32 memblock_index, vxge_hal_mempool_dma_t *dma_object, void *item, u32 item_index, u32 is_last, void *userdata) { u32 i; __hal_ring_t *ring = (__hal_ring_t *) userdata; __hal_device_t *hldev; vxge_assert((item != NULL) && (ring != NULL)); hldev = (__hal_device_t *) ring->channel.devh; vxge_hal_trace_log_pool("==> %s:%s:%d", __FILE__, __func__, __LINE__); vxge_hal_trace_log_pool( "mempoolh = 0x"VXGE_OS_STXFMT", memblock = 0x"VXGE_OS_STXFMT", " "memblock_index = %d, dma_object = 0x"VXGE_OS_STXFMT", " "item = 0x"VXGE_OS_STXFMT", item_index = %d, is_last = %d, " "userdata = 0x"VXGE_OS_STXFMT, (ptr_t) mempoolh, (ptr_t) memblock, memblock_index, (ptr_t) dma_object, (ptr_t) item, item_index, is_last, (ptr_t) userdata); /* format rxds array */ for (i = 0; i < ring->rxds_per_block; i++) { void *uld_priv; void *rxdblock_priv; __hal_ring_rxd_priv_t *rxd_priv; vxge_hal_ring_rxd_1_t *rxdp; u32 memblock_item_idx; u32 dtr_index = item_index * ring->rxds_per_block + i; ring->channel.dtr_arr[dtr_index].dtr = ((u8 *) item) + i * ring->rxd_size; /* * Note: memblock_item_idx is index of the item within * the memblock. For instance, in case of three RxD-blocks * per memblock this value can be 0, 1 or 2. */ rxdblock_priv = __hal_mempool_item_priv( (vxge_hal_mempool_t *) mempoolh, memblock_index, item, &memblock_item_idx); rxdp = (vxge_hal_ring_rxd_1_t *) ring->channel.dtr_arr[dtr_index].dtr; uld_priv = ((u8 *) rxdblock_priv + ring->rxd_priv_size * i); rxd_priv = (__hal_ring_rxd_priv_t *) ((void *)(((char *) uld_priv) + ring->per_rxd_space)); ((vxge_hal_ring_rxd_5_t *) rxdp)->host_control = dtr_index; ring->channel.dtr_arr[dtr_index].uld_priv = (void *)uld_priv; ring->channel.dtr_arr[dtr_index].hal_priv = (void *)rxd_priv; /* pre-format per-RxD Ring's private */ /* LINTED */ rxd_priv->dma_offset = (u8 *) rxdp - (u8 *) memblock; rxd_priv->dma_addr = dma_object->addr + rxd_priv->dma_offset; rxd_priv->dma_handle = dma_object->handle; #if defined(VXGE_DEBUG_ASSERT) rxd_priv->dma_object = dma_object; #endif rxd_priv->db_bytes = ring->rxd_size; if (i == (ring->rxds_per_block - 1)) { rxd_priv->db_bytes += (((vxge_hal_mempool_t *) mempoolh)->memblock_size - (ring->rxds_per_block * ring->rxd_size)); } } __hal_ring_block_memblock_idx_set((u8 *) item, memblock_index); if (is_last) { /* link last one with first one */ __hal_ring_rxdblock_link(mempoolh, ring, item_index, 0); } if (item_index > 0) { /* link this RxD block with previous one */ __hal_ring_rxdblock_link(mempoolh, ring, item_index - 1, item_index); } vxge_hal_trace_log_pool("<== %s:%s:%d Result: 0", __FILE__, __func__, __LINE__); return (VXGE_HAL_OK); }
static xge_hal_status_e __hal_fifo_mempool_item_alloc(xge_hal_mempool_h mempoolh, void *memblock, int memblock_index, xge_hal_mempool_dma_t *dma_object, void *item, int index, int is_last, void *userdata) { int memblock_item_idx; xge_hal_fifo_txdl_priv_t *txdl_priv; xge_hal_fifo_txd_t *txdp = (xge_hal_fifo_txd_t *)item; xge_hal_fifo_t *fifo = (xge_hal_fifo_t *)userdata; xge_assert(item); txdl_priv = __hal_mempool_item_priv(mempoolh, memblock_index, item, &memblock_item_idx); xge_assert(txdl_priv); /* pre-format HAL's TxDL's private */ txdl_priv->dma_offset = (char*)item - (char*)memblock; txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset; txdl_priv->dma_handle = dma_object->handle; txdl_priv->memblock = memblock; txdl_priv->first_txdp = (xge_hal_fifo_txd_t *)item; txdl_priv->next_txdl_priv = NULL; txdl_priv->dang_txdl = NULL; txdl_priv->dang_frags = 0; txdl_priv->alloc_frags = 0; #ifdef XGE_DEBUG_ASSERT txdl_priv->dma_object = dma_object; #endif txdp->host_control = (u64)(ulong_t)txdl_priv; #ifdef XGE_HAL_ALIGN_XMIT txdl_priv->align_vaddr = NULL; txdl_priv->align_dma_addr = (dma_addr_t)0; #ifndef XGE_HAL_ALIGN_XMIT_ALLOC_RT { xge_hal_status_e status; if (fifo->config->alignment_size) { status =__hal_fifo_dtr_align_alloc_map(fifo, txdp); if (status != XGE_HAL_OK) { xge_debug_mm(XGE_ERR, "align buffer[%d] %d bytes, status %d", index, fifo->config->alignment_size * fifo->config->max_aligned_frags, status); return status; } } } #endif #endif if (fifo->channel.dtr_init) { fifo->channel.dtr_init(fifo, (xge_hal_dtr_h)txdp, index, fifo->channel.userdata, XGE_HAL_CHANNEL_OC_NORMAL); } return XGE_HAL_OK; }