aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/vxge/vxgehal/vxgehal-channel.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/vxge/vxgehal/vxgehal-channel.h')
-rw-r--r--sys/dev/vxge/vxgehal/vxgehal-channel.h386
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 */