2 * Copyright(c) 2002-2011 Exar Corp.
5 * Redistribution and use in source and binary forms, with or without
6 * modification are permitted provided the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Exar Corporation nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 #ifndef VXGE_HAL_CHANNEL_H
34 #define VXGE_HAL_CHANNEL_H
39 * __hal_dtr_h - Handle to the desriptor object used for nonoffload
40 * send or receive. Generic handle which can be with txd or rxd
42 typedef void *__hal_dtr_h;
45 * enum __hal_channel_type_e - Enumerated channel types.
46 * @VXGE_HAL_CHANNEL_TYPE_UNKNOWN: Unknown channel.
47 * @VXGE_HAL_CHANNEL_TYPE_FIFO: fifo.
48 * @VXGE_HAL_CHANNEL_TYPE_RING: ring.
49 * @VXGE_HAL_CHANNEL_TYPE_SQ: Send Queue
50 * @VXGE_HAL_CHANNEL_TYPE_SRQ: Receive Queue
51 * @VXGE_HAL_CHANNEL_TYPE_CQRQ: Receive queue completion queue
52 * @VXGE_HAL_CHANNEL_TYPE_UMQ: Up message queue
53 * @VXGE_HAL_CHANNEL_TYPE_DMQ: Down message queue
54 * @VXGE_HAL_CHANNEL_TYPE_MAX: Maximum number of HAL-supported
55 * (and recognized) channel types. Currently: 7.
57 * Enumerated channel types. Currently there are only two link-layer
58 * channels - X3100 fifo and X3100 ring. In the future the list will grow.
60 typedef enum __hal_channel_type_e {
61 VXGE_HAL_CHANNEL_TYPE_UNKNOWN = 0,
62 VXGE_HAL_CHANNEL_TYPE_FIFO = 1,
63 VXGE_HAL_CHANNEL_TYPE_RING = 2,
64 VXGE_HAL_CHANNEL_TYPE_SEND_QUEUE = 3,
65 VXGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE = 4,
66 VXGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE = 5,
67 VXGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE = 6,
68 VXGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE = 7,
69 VXGE_HAL_CHANNEL_TYPE_MAX = 8
70 } __hal_channel_type_e;
74 * @dtr: Pointer to the descriptors that contains the dma data
76 * @hal_priv: HAL Private data related to the dtr.
77 * @uld_priv: ULD Private data related to the dtr.
79 typedef struct __hal_dtr_item_t {
84 #define VXGE_HAL_CHANNEL_DTR_FREE 0
85 #define VXGE_HAL_CHANNEL_DTR_RESERVED 1
86 #define VXGE_HAL_CHANNEL_DTR_POSTED 2
87 #define VXGE_HAL_CHANNEL_DTR_COMPLETED 3
92 * @item: List item; used to maintain a list of open channels.
93 * @type: Channel type. See vxge_hal_channel_type_e {}.
94 * @devh: Device handle. HAL device object that contains _this_ channel.
95 * @pdev: PCI Device object
96 * @vph: Virtual path handle. Virtual Path Object that contains _this_ channel.
97 * @length: Channel length. Currently allocated number of descriptors.
98 * The channel length "grows" when more descriptors get allocated.
99 * See _hal_mempool_grow.
100 * @dtr_arr: Dtr array. Contains descriptors posted to the channel and their
102 * Note that at any point in time @dtr_arr contains 3 types of
104 * 1) posted but not yet consumed by X3100 device;
105 * 2) consumed but not yet completed;
107 * @post_index: Post index. At any point in time points on the
108 * position in the channel, which'll contain next to-be-posted
110 * @compl_index: Completion index. At any point in time points on the
111 * position in the channel, which will contain next
112 * to-be-completed descriptor.
113 * @reserve_index: Reserve index. At any point in time points on the
114 * position in the channel, which will contain next
115 * to-be-reserved descriptor.
116 * @free_dtr_count: Number of dtrs free.
117 * @posted_dtr_count: Number of dtrs posted
118 * @post_lock: Lock to serialize multiple concurrent "posters" of descriptors
119 * on the given channel.
120 * @poll_bytes: Poll bytes.
121 * @per_dtr_space: Per-descriptor space (in bytes) that channel user can utilize
122 * to store per-operation control information.
123 * @stats: Pointer to common statistics
124 * @userdata: Per-channel opaque (void *) user-defined context, which may be
125 * upper-layer driver object, ULP connection, etc.
126 * Once channel is open, @userdata is passed back to user via
127 * vxge_hal_channel_callback_f.
129 * HAL channel object.
131 * See also: vxge_hal_channel_type_e {}, vxge_hal_channel_flag_e
133 typedef struct __hal_channel_t {
135 __hal_channel_type_e type;
136 vxge_hal_device_h devh;
138 vxge_hal_vpath_h vph;
141 __hal_dtr_item_t *dtr_arr;
142 u32 compl_index __vxge_os_attr_cacheline_aligned;
143 u32 reserve_index __vxge_os_attr_cacheline_aligned;
144 spinlock_t post_lock;
147 vxge_hal_vpath_stats_sw_common_info_t *stats;
149 } __hal_channel_t __vxge_os_attr_cacheline_aligned;
151 #define __hal_channel_is_posted_dtr(channel, index) \
152 ((channel)->dtr_arr[index].state == VXGE_HAL_CHANNEL_DTR_POSTED)
154 #define __hal_channel_for_each_posted_dtr(channel, dtrh, index) \
155 for (index = (channel)->compl_index,\
156 dtrh = (channel)->dtr_arr[index].dtr; \
157 (index < (channel)->reserve_index) && \
158 ((channel)->dtr_arr[index].state == VXGE_HAL_CHANNEL_DTR_POSTED); \
159 index = (++index == (channel)->length)? 0 : index, \
160 dtrh = (channel)->dtr_arr[index].dtr)
162 #define __hal_channel_for_each_dtr(channel, dtrh, index) \
163 for (index = 0, dtrh = (channel)->dtr_arr[index].dtr; \
164 index < (channel)->length; \
165 dtrh = ((++index == (channel)->length)? 0 : \
166 (channel)->dtr_arr[index].dtr))
168 #define __hal_channel_free_dtr_count(channel) \
169 (((channel)->reserve_index < (channel)->compl_index) ? \
170 ((channel)->compl_index - (channel)->reserve_index) : \
171 (((channel)->length - (channel)->reserve_index) + \
172 (channel)->reserve_index))
174 /* ========================== CHANNEL PRIVATE API ========================= */
177 vxge_hal_channel_allocate(
178 vxge_hal_device_h devh,
179 vxge_hal_vpath_h vph,
180 __hal_channel_type_e type,
186 vxge_hal_channel_free(
187 __hal_channel_t *channel);
190 vxge_hal_channel_initialize(
191 __hal_channel_t *channel);
195 __hal_channel_t *channel);
198 vxge_hal_channel_terminate(
199 __hal_channel_t *channel);
202 __hal_channel_init_pending_list(
203 vxge_hal_device_h devh);
206 __hal_channel_insert_pending_list(
207 __hal_channel_t * channel);
210 __hal_channel_process_pending_list(
211 vxge_hal_device_h devhv);
214 __hal_channel_destroy_pending_list(
215 vxge_hal_device_h devh);
217 #if defined(VXGE_DEBUG_FP) && (VXGE_DEBUG_FP & VXGE_DEBUG_FP_CHANNEL)
218 #define __HAL_STATIC_CHANNEL
219 #define __HAL_INLINE_CHANNEL
220 #else /* VXGE_FASTPATH_EXTERN */
221 #define __HAL_STATIC_CHANNEL static
222 #define __HAL_INLINE_CHANNEL inline
223 #endif /* VXGE_FASTPATH_INLINE */
225 /* ========================== CHANNEL Fast Path API ========================= */
227 * __hal_channel_dtr_reserve- Reserve a dtr from the channel
229 * @dtrh: Buffer to return the DTR pointer
231 * Reserve a dtr from the reserve array.
234 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL vxge_hal_status_e
236 __hal_channel_dtr_reserve(__hal_channel_t *channel, __hal_dtr_h *dtrh)
238 vxge_hal_status_e status = VXGE_HAL_INF_OUT_OF_DESCRIPTORS;
242 if (channel->dtr_arr[channel->reserve_index].state ==
243 VXGE_HAL_CHANNEL_DTR_FREE) {
245 *dtrh = channel->dtr_arr[channel->reserve_index].dtr;
247 channel->dtr_arr[channel->reserve_index].state =
248 VXGE_HAL_CHANNEL_DTR_RESERVED;
250 if (++channel->reserve_index == channel->length)
251 channel->reserve_index = 0;
253 status = VXGE_HAL_OK;
257 #if (VXGE_COMPONENT_HAL_CHANNEL & VXGE_DEBUG_MODULE_MASK)
258 __hal_device_t *hldev = (__hal_device_t *) channel->devh;
260 vxge_hal_info_log_channel("channel %d is full!", channel->type);
263 channel->stats->full_cnt++;
270 * __hal_channel_dtr_restore - Restores a dtr to the channel
274 * Returns a dtr back to reserve array.
277 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
279 __hal_channel_dtr_restore(__hal_channel_t *channel, __hal_dtr_h dtrh)
284 * restore a previously allocated dtrh at current offset and update
285 * the available reserve length accordingly. If dtrh is null just
286 * update the reserve length, only
289 if (channel->reserve_index == 0)
290 dtr_index = channel->length;
292 dtr_index = channel->reserve_index - 1;
294 if ((channel->dtr_arr[dtr_index].dtr = dtrh) != NULL) {
296 channel->reserve_index = dtr_index;
297 channel->dtr_arr[dtr_index].state = VXGE_HAL_CHANNEL_DTR_FREE;
299 #if (VXGE_COMPONENT_HAL_CHANNEL & VXGE_DEBUG_MODULE_MASK)
301 __hal_device_t *hldev = (__hal_device_t *) channel->devh;
302 vxge_hal_info_log_channel("dtrh 0x"VXGE_OS_STXFMT" \
303 restored for " "channel %d at reserve index %d, ",
304 (ptr_t) dtrh, channel->type,
305 channel->reserve_index);
311 * __hal_channel_dtr_post - Post a dtr to the channel
315 * Posts a dtr to work array.
318 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
320 __hal_channel_dtr_post(__hal_channel_t *channel, u32 dtr_index)
322 channel->dtr_arr[dtr_index].state =
323 VXGE_HAL_CHANNEL_DTR_POSTED;
327 * __hal_channel_dtr_try_complete - Returns next completed dtr
329 * @dtr: Buffer to return the next completed DTR pointer
331 * Returns the next completed dtr with out removing it from work array
334 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
336 __hal_channel_dtr_try_complete(__hal_channel_t *channel, __hal_dtr_h *dtrh)
338 vxge_assert(channel->dtr_arr);
339 vxge_assert(channel->compl_index < channel->length);
341 if (channel->dtr_arr[channel->compl_index].state ==
342 VXGE_HAL_CHANNEL_DTR_POSTED)
343 *dtrh = channel->dtr_arr[channel->compl_index].dtr;
349 * __hal_channel_dtr_complete - Removes next completed dtr from the work array
352 * Removes the next completed dtr from work array
355 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
357 __hal_channel_dtr_complete(__hal_channel_t *channel)
359 channel->dtr_arr[channel->compl_index].state =
360 VXGE_HAL_CHANNEL_DTR_COMPLETED;
362 if (++channel->compl_index == channel->length)
363 channel->compl_index = 0;
365 channel->stats->total_compl_cnt++;
369 * __hal_channel_dtr_free - Frees a dtr
371 * @index: Index of DTR
373 * Returns the dtr to free array
376 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
378 __hal_channel_dtr_free(__hal_channel_t *channel, u32 dtr_index)
380 channel->dtr_arr[dtr_index].state =
381 VXGE_HAL_CHANNEL_DTR_FREE;
386 #endif /* VXGE_HAL_CHANNEL_H */