diff options
Diffstat (limited to 'sys/dev/vxge/vxgehal/vxgehal-channel.h')
-rw-r--r-- | sys/dev/vxge/vxgehal/vxgehal-channel.h | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/sys/dev/vxge/vxgehal/vxgehal-channel.h b/sys/dev/vxge/vxgehal/vxgehal-channel.h new file mode 100644 index 000000000000..bce3ad2d1f61 --- /dev/null +++ b/sys/dev/vxge/vxgehal/vxgehal-channel.h @@ -0,0 +1,386 @@ +/*- + * Copyright(c) 2002-2011 Exar Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification are permitted provided the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Exar Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/*$FreeBSD$*/ + +#ifndef VXGE_HAL_CHANNEL_H +#define VXGE_HAL_CHANNEL_H + +__EXTERN_BEGIN_DECLS + +/* + * __hal_dtr_h - Handle to the desriptor object used for nonoffload + * send or receive. Generic handle which can be with txd or rxd + */ +typedef void *__hal_dtr_h; + +/* + * enum __hal_channel_type_e - Enumerated channel types. + * @VXGE_HAL_CHANNEL_TYPE_UNKNOWN: Unknown channel. + * @VXGE_HAL_CHANNEL_TYPE_FIFO: fifo. + * @VXGE_HAL_CHANNEL_TYPE_RING: ring. + * @VXGE_HAL_CHANNEL_TYPE_SQ: Send Queue + * @VXGE_HAL_CHANNEL_TYPE_SRQ: Receive Queue + * @VXGE_HAL_CHANNEL_TYPE_CQRQ: Receive queue completion queue + * @VXGE_HAL_CHANNEL_TYPE_UMQ: Up message queue + * @VXGE_HAL_CHANNEL_TYPE_DMQ: Down message queue + * @VXGE_HAL_CHANNEL_TYPE_MAX: Maximum number of HAL-supported + * (and recognized) channel types. Currently: 7. + * + * Enumerated channel types. Currently there are only two link-layer + * channels - X3100 fifo and X3100 ring. In the future the list will grow. + */ +typedef enum __hal_channel_type_e { + VXGE_HAL_CHANNEL_TYPE_UNKNOWN = 0, + VXGE_HAL_CHANNEL_TYPE_FIFO = 1, + VXGE_HAL_CHANNEL_TYPE_RING = 2, + VXGE_HAL_CHANNEL_TYPE_SEND_QUEUE = 3, + VXGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE = 4, + VXGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE = 5, + VXGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE = 6, + VXGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE = 7, + VXGE_HAL_CHANNEL_TYPE_MAX = 8 +} __hal_channel_type_e; + +/* + * __hal_dtr_item_t + * @dtr: Pointer to the descriptors that contains the dma data + * to/from the device. + * @hal_priv: HAL Private data related to the dtr. + * @uld_priv: ULD Private data related to the dtr. + */ +typedef struct __hal_dtr_item_t { + void *dtr; + void *hal_priv; + void *uld_priv; + u32 state; +#define VXGE_HAL_CHANNEL_DTR_FREE 0 +#define VXGE_HAL_CHANNEL_DTR_RESERVED 1 +#define VXGE_HAL_CHANNEL_DTR_POSTED 2 +#define VXGE_HAL_CHANNEL_DTR_COMPLETED 3 +} __hal_dtr_item_t; + +/* + * __hal_channel_t + * @item: List item; used to maintain a list of open channels. + * @type: Channel type. See vxge_hal_channel_type_e {}. + * @devh: Device handle. HAL device object that contains _this_ channel. + * @pdev: PCI Device object + * @vph: Virtual path handle. Virtual Path Object that contains _this_ channel. + * @length: Channel length. Currently allocated number of descriptors. + * The channel length "grows" when more descriptors get allocated. + * See _hal_mempool_grow. + * @dtr_arr: Dtr array. Contains descriptors posted to the channel and their + * private data. + * Note that at any point in time @dtr_arr contains 3 types of + * descriptors: + * 1) posted but not yet consumed by X3100 device; + * 2) consumed but not yet completed; + * 3) completed. + * @post_index: Post index. At any point in time points on the + * position in the channel, which'll contain next to-be-posted + * descriptor. + * @compl_index: Completion index. At any point in time points on the + * position in the channel, which will contain next + * to-be-completed descriptor. + * @reserve_index: Reserve index. At any point in time points on the + * position in the channel, which will contain next + * to-be-reserved descriptor. + * @free_dtr_count: Number of dtrs free. + * @posted_dtr_count: Number of dtrs posted + * @post_lock: Lock to serialize multiple concurrent "posters" of descriptors + * on the given channel. + * @poll_bytes: Poll bytes. + * @per_dtr_space: Per-descriptor space (in bytes) that channel user can utilize + * to store per-operation control information. + * @stats: Pointer to common statistics + * @userdata: Per-channel opaque (void *) user-defined context, which may be + * upper-layer driver object, ULP connection, etc. + * Once channel is open, @userdata is passed back to user via + * vxge_hal_channel_callback_f. + * + * HAL channel object. + * + * See also: vxge_hal_channel_type_e {}, vxge_hal_channel_flag_e + */ +typedef struct __hal_channel_t { + vxge_list_t item; + __hal_channel_type_e type; + vxge_hal_device_h devh; + pci_dev_h pdev; + vxge_hal_vpath_h vph; + u32 length; + u32 is_initd; + __hal_dtr_item_t *dtr_arr; + u32 compl_index __vxge_os_attr_cacheline_aligned; + u32 reserve_index __vxge_os_attr_cacheline_aligned; + spinlock_t post_lock; + u32 poll_bytes; + u32 per_dtr_space; + vxge_hal_vpath_stats_sw_common_info_t *stats; + void *userdata; +} __hal_channel_t __vxge_os_attr_cacheline_aligned; + +#define __hal_channel_is_posted_dtr(channel, index) \ + ((channel)->dtr_arr[index].state == VXGE_HAL_CHANNEL_DTR_POSTED) + +#define __hal_channel_for_each_posted_dtr(channel, dtrh, index) \ + for (index = (channel)->compl_index,\ + dtrh = (channel)->dtr_arr[index].dtr; \ + (index < (channel)->reserve_index) && \ + ((channel)->dtr_arr[index].state == VXGE_HAL_CHANNEL_DTR_POSTED); \ + index = (++index == (channel)->length)? 0 : index, \ + dtrh = (channel)->dtr_arr[index].dtr) + +#define __hal_channel_for_each_dtr(channel, dtrh, index) \ + for (index = 0, dtrh = (channel)->dtr_arr[index].dtr; \ + index < (channel)->length; \ + dtrh = ((++index == (channel)->length)? 0 : \ + (channel)->dtr_arr[index].dtr)) + +#define __hal_channel_free_dtr_count(channel) \ + (((channel)->reserve_index < (channel)->compl_index) ? \ + ((channel)->compl_index - (channel)->reserve_index) : \ + (((channel)->length - (channel)->reserve_index) + \ + (channel)->reserve_index)) + +/* ========================== CHANNEL PRIVATE API ========================= */ + +__hal_channel_t * +vxge_hal_channel_allocate( + vxge_hal_device_h devh, + vxge_hal_vpath_h vph, + __hal_channel_type_e type, + u32 length, + u32 per_dtr_space, + void *userdata); + +void +vxge_hal_channel_free( + __hal_channel_t *channel); + +vxge_hal_status_e +vxge_hal_channel_initialize( + __hal_channel_t *channel); + +vxge_hal_status_e +__hal_channel_reset( + __hal_channel_t *channel); + +void +vxge_hal_channel_terminate( + __hal_channel_t *channel); + +void +__hal_channel_init_pending_list( + vxge_hal_device_h devh); + +void +__hal_channel_insert_pending_list( + __hal_channel_t * channel); + +void +__hal_channel_process_pending_list( + vxge_hal_device_h devhv); + +void +__hal_channel_destroy_pending_list( + vxge_hal_device_h devh); + +#if defined(VXGE_DEBUG_FP) && (VXGE_DEBUG_FP & VXGE_DEBUG_FP_CHANNEL) +#define __HAL_STATIC_CHANNEL +#define __HAL_INLINE_CHANNEL +#else /* VXGE_FASTPATH_EXTERN */ +#define __HAL_STATIC_CHANNEL static +#define __HAL_INLINE_CHANNEL inline +#endif /* VXGE_FASTPATH_INLINE */ + +/* ========================== CHANNEL Fast Path API ========================= */ +/* + * __hal_channel_dtr_reserve- Reserve a dtr from the channel + * @channelh: Channel + * @dtrh: Buffer to return the DTR pointer + * + * Reserve a dtr from the reserve array. + * + */ +__HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL vxge_hal_status_e +/* LINTED */ +__hal_channel_dtr_reserve(__hal_channel_t *channel, __hal_dtr_h *dtrh) +{ + vxge_hal_status_e status = VXGE_HAL_INF_OUT_OF_DESCRIPTORS; + + *dtrh = NULL; + + if (channel->dtr_arr[channel->reserve_index].state == + VXGE_HAL_CHANNEL_DTR_FREE) { + + *dtrh = channel->dtr_arr[channel->reserve_index].dtr; + + channel->dtr_arr[channel->reserve_index].state = + VXGE_HAL_CHANNEL_DTR_RESERVED; + + if (++channel->reserve_index == channel->length) + channel->reserve_index = 0; + + status = VXGE_HAL_OK; + + } else { + +#if (VXGE_COMPONENT_HAL_CHANNEL & VXGE_DEBUG_MODULE_MASK) + __hal_device_t *hldev = (__hal_device_t *) channel->devh; + + vxge_hal_info_log_channel("channel %d is full!", channel->type); +#endif + + channel->stats->full_cnt++; + } + + return (status); +} + +/* + * __hal_channel_dtr_restore - Restores a dtr to the channel + * @channelh: Channel + * @dtr: DTR pointer + * + * Returns a dtr back to reserve array. + * + */ +__HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void +/* LINTED */ +__hal_channel_dtr_restore(__hal_channel_t *channel, __hal_dtr_h dtrh) +{ + u32 dtr_index; + + /* + * restore a previously allocated dtrh at current offset and update + * the available reserve length accordingly. If dtrh is null just + * update the reserve length, only + */ + + if (channel->reserve_index == 0) + dtr_index = channel->length; + else + dtr_index = channel->reserve_index - 1; + + if ((channel->dtr_arr[dtr_index].dtr == dtrh)) { + + channel->reserve_index = dtr_index; + channel->dtr_arr[dtr_index].state = VXGE_HAL_CHANNEL_DTR_FREE; + +#if (VXGE_COMPONENT_HAL_CHANNEL & VXGE_DEBUG_MODULE_MASK) + + __hal_device_t *hldev = (__hal_device_t *) channel->devh; + vxge_hal_info_log_channel("dtrh 0x"VXGE_OS_STXFMT" \ + restored for " "channel %d at reserve index %d, ", + (ptr_t) dtrh, channel->type, + channel->reserve_index); +#endif + } +} + +/* + * __hal_channel_dtr_post - Post a dtr to the channel + * @channelh: Channel + * @dtr: DTR pointer + * + * Posts a dtr to work array. + * + */ +__HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void +/* LINTED */ +__hal_channel_dtr_post(__hal_channel_t *channel, u32 dtr_index) +{ + channel->dtr_arr[dtr_index].state = + VXGE_HAL_CHANNEL_DTR_POSTED; +} + +/* + * __hal_channel_dtr_try_complete - Returns next completed dtr + * @channelh: Channel + * @dtr: Buffer to return the next completed DTR pointer + * + * Returns the next completed dtr with out removing it from work array + * + */ +__HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void +/* LINTED */ +__hal_channel_dtr_try_complete(__hal_channel_t *channel, __hal_dtr_h *dtrh) +{ + vxge_assert(channel->dtr_arr); + vxge_assert(channel->compl_index < channel->length); + + if (channel->dtr_arr[channel->compl_index].state == + VXGE_HAL_CHANNEL_DTR_POSTED) + *dtrh = channel->dtr_arr[channel->compl_index].dtr; + else + *dtrh = NULL; +} + +/* + * __hal_channel_dtr_complete - Removes next completed dtr from the work array + * @channelh: Channel + * + * Removes the next completed dtr from work array + * + */ +__HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void +/* LINTED */ +__hal_channel_dtr_complete(__hal_channel_t *channel) +{ + channel->dtr_arr[channel->compl_index].state = + VXGE_HAL_CHANNEL_DTR_COMPLETED; + + if (++channel->compl_index == channel->length) + channel->compl_index = 0; + + channel->stats->total_compl_cnt++; +} + +/* + * __hal_channel_dtr_free - Frees a dtr + * @channelh: Channel + * @index: Index of DTR + * + * Returns the dtr to free array + * + */ +__HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void +/* LINTED */ +__hal_channel_dtr_free(__hal_channel_t *channel, u32 dtr_index) +{ + channel->dtr_arr[dtr_index].state = + VXGE_HAL_CHANNEL_DTR_FREE; +} + +__EXTERN_END_DECLS + +#endif /* VXGE_HAL_CHANNEL_H */ |