1221167Sgnn/*- 2221167Sgnn * Copyright(c) 2002-2011 Exar Corp. 3221167Sgnn * All rights reserved. 4221167Sgnn * 5221167Sgnn * Redistribution and use in source and binary forms, with or without 6221167Sgnn * modification are permitted provided the following conditions are met: 7221167Sgnn * 8221167Sgnn * 1. Redistributions of source code must retain the above copyright notice, 9221167Sgnn * this list of conditions and the following disclaimer. 10221167Sgnn * 11221167Sgnn * 2. Redistributions in binary form must reproduce the above copyright 12221167Sgnn * notice, this list of conditions and the following disclaimer in the 13221167Sgnn * documentation and/or other materials provided with the distribution. 14221167Sgnn * 15221167Sgnn * 3. Neither the name of the Exar Corporation nor the names of its 16221167Sgnn * contributors may be used to endorse or promote products derived from 17221167Sgnn * this software without specific prior written permission. 18221167Sgnn * 19221167Sgnn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20221167Sgnn * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21221167Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22221167Sgnn * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23221167Sgnn * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24221167Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25221167Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26221167Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27221167Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28221167Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29221167Sgnn * POSSIBILITY OF SUCH DAMAGE. 30221167Sgnn */ 31221167Sgnn/*$FreeBSD$*/ 32221167Sgnn 33221167Sgnn#ifndef VXGE_HAL_RING_H 34221167Sgnn#define VXGE_HAL_RING_H 35221167Sgnn 36221167Sgnn__EXTERN_BEGIN_DECLS 37221167Sgnn 38221167Sgnntypedef u8 vxge_hal_ring_block_t[VXGE_OS_HOST_PAGE_SIZE]; 39221167Sgnn 40221167Sgnn#define VXGE_HAL_RING_NEXT_BLOCK_POINTER_OFFSET (VXGE_OS_HOST_PAGE_SIZE-8) 41221167Sgnn#define VXGE_HAL_RING_MEMBLOCK_IDX_OFFSET (VXGE_OS_HOST_PAGE_SIZE-16) 42221167Sgnn 43221167Sgnn/* 44221167Sgnn * struct __hal_ring_rxd_priv_t - Receive descriptor HAL-private data. 45221167Sgnn * @dma_addr: DMA (mapped) address of _this_ descriptor. 46221167Sgnn * @dma_handle: DMA handle used to map the descriptor onto device. 47221167Sgnn * @dma_offset: Descriptor's offset in the memory block. HAL allocates 48221167Sgnn * descriptors in memory blocks of %VXGE_OS_HOST_PAGE_SIZE 49221167Sgnn * bytes. Each memblock is contiguous DMA-able memory. Each 50221167Sgnn * memblock contains 1 or more 4KB RxD blocks visible to the 51221167Sgnn * X3100 hardware. 52221167Sgnn * @dma_object: DMA address and handle of the memory block that contains 53221167Sgnn * the descriptor. This member is used only in the "checked" 54221167Sgnn * version of the HAL (to enforce certain assertions); 55221167Sgnn * otherwise it gets compiled out. 56221167Sgnn * @allocated: True if the descriptor is reserved, 0 otherwise. Internal usage. 57221167Sgnn * @db_bytes: Number of doorbell bytes to be posted for this Rxd. This includes 58221167Sgnn * next RxD block pointers 59221167Sgnn * 60221167Sgnn * Per-receive decsriptor HAL-private data. HAL uses the space to keep DMA 61221167Sgnn * information associated with the descriptor. Note that ULD can ask HAL 62221167Sgnn * to allocate additional per-descriptor space for its own (ULD-specific) 63221167Sgnn * purposes. 64221167Sgnn */ 65221167Sgnntypedef struct __hal_ring_rxd_priv_t { 66221167Sgnn dma_addr_t dma_addr; 67221167Sgnn pci_dma_h dma_handle; 68221167Sgnn ptrdiff_t dma_offset; 69221167Sgnn#if defined(VXGE_DEBUG_ASSERT) 70221167Sgnn vxge_hal_mempool_dma_t *dma_object; 71221167Sgnn#endif 72221167Sgnn#if defined(VXGE_OS_MEMORY_CHECK) 73221167Sgnn u32 allocated; 74221167Sgnn#endif 75221167Sgnn u32 db_bytes; 76221167Sgnn} __hal_ring_rxd_priv_t; 77221167Sgnn 78221167Sgnn 79221167Sgnn/* 80221167Sgnn * struct __hal_ring_t - Ring channel. 81221167Sgnn * @channel: Channel "base" of this ring, the common part of all HAL 82221167Sgnn * channels. 83221167Sgnn * @mempool: Memory pool, the pool from which descriptors get allocated. 84221167Sgnn * (See vxge_hal_mm.h). 85221167Sgnn * @config: Ring configuration, part of device configuration 86221167Sgnn * (see vxge_hal_device_config_t {}). 87221167Sgnn * @ring_length: Length of the ring 88221167Sgnn * @buffer_mode: 1, 3, or 5. The value specifies a receive buffer mode, 89221167Sgnn * as per X3100 User Guide. 90221167Sgnn * @indicate_max_pkts: Maximum number of packets processed within a single 91221167Sgnn * interrupt. Can be used to limit the time spent inside hw interrupt. 92221167Sgnn * @rxd_size: RxD sizes for 1-, 3- or 5- buffer modes. As per X3100 spec, 93221167Sgnn * 1-buffer mode descriptor is 32 byte long, etc. 94221167Sgnn * @rxd_priv_size: Per RxD size reserved (by HAL) for ULD to keep per-descriptor 95221167Sgnn * data (e.g., DMA handle for Solaris) 96221167Sgnn * @per_rxd_space: Per rxd space requested by ULD 97221167Sgnn * @rxds_per_block: Number of descriptors per hardware-defined RxD 98221167Sgnn * block. Depends on the (1-, 3-, 5-) buffer mode. 99221167Sgnn * @rxdblock_priv_size: Reserved at the end of each RxD block. HAL internal 100221167Sgnn * usage. Not to confuse with @rxd_priv_size. 101221167Sgnn * @rxd_mem_avail: Available RxD memory 102221167Sgnn * @db_byte_count: Number of doorbell bytes to be posted 103221167Sgnn * @cmpl_cnt: Completion counter. Is reset to zero upon entering the ISR. 104221167Sgnn * Used in conjunction with @indicate_max_pkts. 105221167Sgnn * @active_sw_lros: List of Software LRO sessions in progess 106221167Sgnn * @active_sw_lro_count: Number of Software LRO sessions in progess 107221167Sgnn * @free_sw_lros: List of Software LRO sessions free 108221167Sgnn * @free_sw_lro_count: Number of Software LRO sessions free 109221167Sgnn * @sw_lro_lock: LRO session lists' lock 110221167Sgnn * @callback: Channel completion callback. HAL invokes the callback when there 111221167Sgnn * are new completions on that channel. In many implementations 112221167Sgnn * the @callback executes in the hw interrupt context. 113221167Sgnn * @rxd_init: Channel's descriptor-initialize callback. 114221167Sgnn * See vxge_hal_ring_rxd_init_f {}. 115221167Sgnn * If not NULL, HAL invokes the callback when opening the ring. 116221167Sgnn * @rxd_term: Channel's descriptor-terminate callback. If not NULL, 117221167Sgnn * HAL invokes the callback when closing the corresponding channel. 118221167Sgnn * See also vxge_hal_channel_rxd_term_f {}. 119221167Sgnn * @stats: Statistics for ring 120221167Sgnn * Ring channel. 121221167Sgnn * 122221167Sgnn * Note: The structure is cache line aligned to better utilize 123221167Sgnn * CPU cache performance. 124221167Sgnn */ 125221167Sgnntypedef struct __hal_ring_t { 126221167Sgnn __hal_channel_t channel; 127221167Sgnn vxge_hal_mempool_t *mempool; 128221167Sgnn vxge_hal_ring_config_t *config; 129221167Sgnn u32 ring_length; 130221167Sgnn u32 buffer_mode; 131221167Sgnn u32 indicate_max_pkts; 132221167Sgnn u32 rxd_size; 133221167Sgnn u32 rxd_priv_size; 134221167Sgnn u32 per_rxd_space; 135221167Sgnn u32 rxds_per_block; 136221167Sgnn u32 rxdblock_priv_size; 137221167Sgnn u32 rxd_mem_avail; 138221167Sgnn u32 db_byte_count; 139221167Sgnn u32 cmpl_cnt; 140221167Sgnn vxge_hal_ring_callback_f callback; 141221167Sgnn vxge_hal_ring_rxd_init_f rxd_init; 142221167Sgnn vxge_hal_ring_rxd_term_f rxd_term; 143221167Sgnn vxge_hal_vpath_stats_sw_ring_info_t *stats; 144221167Sgnn} __vxge_os_attr_cacheline_aligned __hal_ring_t; 145221167Sgnn 146221167Sgnn#define VXGE_HAL_RING_ULD_PRIV(ring, rxdh) \ 147221167Sgnn ring->channel.dtr_arr[ \ 148221167Sgnn ((vxge_hal_ring_rxd_5_t *)(rxdh))->host_control].uld_priv 149221167Sgnn 150221167Sgnn#define VXGE_HAL_RING_HAL_PRIV(ring, rxdh) \ 151221167Sgnn ((__hal_ring_rxd_priv_t *)(ring->channel.dtr_arr[ \ 152221167Sgnn ((vxge_hal_ring_rxd_5_t *)(rxdh))->host_control].hal_priv)) 153221167Sgnn 154221167Sgnn#define VXGE_HAL_RING_POST_DOORBELL(vph, ringh) \ 155221167Sgnn{ \ 156221167Sgnn if (((__hal_ring_t *)(ringh))->config->post_mode == \ 157221167Sgnn VXGE_HAL_RING_POST_MODE_DOORBELL) { \ 158221167Sgnn vxge_hal_ring_rxd_post_post_db(vph); \ 159221167Sgnn } \ 160221167Sgnn} 161221167Sgnn 162221167Sgnn#define VXGE_HAL_RING_RXD_INDEX(rxdp) \ 163221167Sgnn (u32)((vxge_hal_ring_rxd_5_t *)rxdp)->host_control 164221167Sgnn 165221167Sgnn/* ========================== RING PRIVATE API ============================ */ 166221167Sgnn 167221167Sgnnu64 168221167Sgnn__hal_ring_first_block_address_get( 169221167Sgnn vxge_hal_ring_h ringh); 170221167Sgnn 171221167Sgnnvxge_hal_status_e 172221167Sgnn__hal_ring_create( 173221167Sgnn vxge_hal_vpath_h vpath_handle, 174221167Sgnn vxge_hal_ring_attr_t *attr); 175221167Sgnn 176221167Sgnnvoid 177221167Sgnn__hal_ring_abort( 178221167Sgnn vxge_hal_ring_h ringh, 179221167Sgnn vxge_hal_reopen_e reopen); 180221167Sgnn 181221167Sgnnvxge_hal_status_e 182221167Sgnn__hal_ring_reset( 183221167Sgnn vxge_hal_ring_h ringh); 184221167Sgnn 185221167Sgnnvoid 186221167Sgnn__hal_ring_delete( 187221167Sgnn vxge_hal_vpath_h vpath_handle); 188221167Sgnn 189221167Sgnnvxge_hal_status_e 190221167Sgnnvxge_hal_ring_initial_replenish( 191221167Sgnn __hal_ring_t *ring, 192221167Sgnn vxge_hal_reopen_e reopen); 193221167Sgnn 194221167Sgnnvxge_hal_status_e 195221167Sgnn__hal_ring_frame_length_set( 196221167Sgnn __hal_virtualpath_t *vpath, 197221167Sgnn u32 new_frmlen); 198221167Sgnn 199221167Sgnn__EXTERN_END_DECLS 200221167Sgnn 201221167Sgnn#endif /* VXGE_HAL_RING_H */ 202