2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2002-2007 Neterion, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #ifndef XGE_HAL_CHANNEL_H
32 #define XGE_HAL_CHANNEL_H
34 #include <dev/nxge/include/xge-os-pal.h>
35 #include <dev/nxge/include/xge-list.h>
36 #include <dev/nxge/include/xgehal-types.h>
37 #include <dev/nxge/include/xgehal-stats.h>
42 * enum xge_hal_channel_type_e - Enumerated channel types.
43 * @XGE_HAL_CHANNEL_TYPE_FIFO: fifo.
44 * @XGE_HAL_CHANNEL_TYPE_RING: ring.
45 * @XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: Send Queue
46 * @XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: Receive Queue
47 * @XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: Receive queue completion queue
48 * @XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: Up message queue
49 * @XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: Down message queue
50 * @XGE_HAL_CHANNEL_TYPE_MAX: Maximum number of HAL-supported
51 * (and recognized) channel types. Currently: two.
53 * Enumerated channel types. Currently there are only two link-layer
54 * channels - Xframe fifo and Xframe ring. In the future the list will grow.
56 typedef enum xge_hal_channel_type_e {
57 XGE_HAL_CHANNEL_TYPE_FIFO,
58 XGE_HAL_CHANNEL_TYPE_RING,
59 XGE_HAL_CHANNEL_TYPE_SEND_QUEUE,
60 XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE,
61 XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE,
62 XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE,
63 XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE,
64 XGE_HAL_CHANNEL_TYPE_MAX
65 } xge_hal_channel_type_e;
68 * enum xge_hal_channel_flag_e - Channel flags.
69 * @XGE_HAL_CHANNEL_FLAG_NONE: zero (nil) flag.
70 * @XGE_HAL_CHANNEL_FLAG_USE_TX_LOCK: use lock when posting transmit
72 * @XGE_HAL_CHANNEL_FLAG_FREE_RXD: to-be-defined.
74 * Channel opening flags. Reserved for future usage.
76 typedef enum xge_hal_channel_flag_e {
77 XGE_HAL_CHANNEL_FLAG_NONE = 0x0,
78 XGE_HAL_CHANNEL_FLAG_USE_TX_LOCK = 0x1,
79 XGE_HAL_CHANNEL_FLAG_FREE_RXD = 0x2
80 } xge_hal_channel_flag_e;
83 * enum xge_hal_dtr_state_e - Descriptor (DTR) state.
84 * @XGE_HAL_DTR_STATE_NONE: Invalid state.
85 * @XGE_HAL_DTR_STATE_AVAIL: Descriptor is available for reservation
86 * (via xge_hal_fifo_dtr_reserve(), xge_hal_ring_dtr_reserve(), etc.).
87 * @XGE_HAL_DTR_STATE_POSTED: Descriptor is posted for processing by the
89 * @XGE_HAL_DTR_STATE_FREED: Descriptor is free and can be reused for
90 * filling-in and posting later.
92 * Xframe/HAL descriptor states. For more on descriptor states and transitions
93 * please refer to ch_intern{}.
95 * See also: xge_hal_channel_dtr_term_f{}.
97 typedef enum xge_hal_dtr_state_e {
98 XGE_HAL_DTR_STATE_NONE = 0,
99 XGE_HAL_DTR_STATE_AVAIL = 1,
100 XGE_HAL_DTR_STATE_POSTED = 2,
101 XGE_HAL_DTR_STATE_FREED = 3
102 } xge_hal_dtr_state_e;
105 * enum xge_hal_channel_reopen_e - Channel open, close, or reopen option.
106 * @XGE_HAL_CHANNEL_RESET_ONLY: Do not (de)allocate channel; used with
107 * xge_hal_channel_open(), xge_hal_channel_close().
108 * @XGE_HAL_CHANNEL_OC_NORMAL: Do (de)allocate channel; used with
109 * xge_hal_channel_open(), xge_hal_channel_close().
111 * Enumerates options used with channel open and close operations.
112 * The @XGE_HAL_CHANNEL_RESET_ONLY can be used when resetting the device;
113 * in this case there is actually no need to free and then again malloc
114 * the memory (including DMA-able memory) used for channel operation.
116 typedef enum xge_hal_channel_reopen_e {
117 XGE_HAL_CHANNEL_RESET_ONLY = 1,
118 XGE_HAL_CHANNEL_OC_NORMAL = 2
119 } xge_hal_channel_reopen_e;
122 * function xge_hal_channel_callback_f - Channel callback.
123 * @channelh: Channel "containing" 1 or more completed descriptors.
124 * @dtrh: First completed descriptor.
125 * @t_code: Transfer code, as per Xframe User Guide.
127 * @host_control: Opaque 64bit data stored by ULD inside the Xframe
128 * descriptor prior to posting the latter on the channel
129 * via xge_hal_fifo_dtr_post() or xge_hal_ring_dtr_post().
130 * The @host_control is returned as is to the ULD with each
131 * completed descriptor.
132 * @userdata: Opaque per-channel data specified at channel open
133 * time, via xge_hal_channel_open().
135 * Channel completion callback (type declaration). A single per-channel
136 * callback is specified at channel open time, via
137 * xge_hal_channel_open().
138 * Typically gets called as part of the processing of the Interrupt
141 * Channel callback gets called by HAL if, and only if, there is at least
142 * one new completion on a given ring or fifo channel. Upon processing the
143 * first @dtrh ULD is _supposed_ to continue consuming completions
144 * using one of the following HAL APIs:
145 * - xge_hal_fifo_dtr_next_completed()
147 * - xge_hal_ring_dtr_next_completed().
149 * Note that failure to process new completions in a timely fashion
150 * leads to XGE_HAL_INF_OUT_OF_DESCRIPTORS condition.
152 * Non-zero @t_code means failure to process (transmit or receive, depending
153 * on the channel type) the descriptor.
155 * In the "transmit" case the failure could happen, for instance, when the
156 * link is down, in which case Xframe completes the descriptor because it
157 * is not able to send the data out.
159 * For details please refer to Xframe User Guide.
161 * See also: xge_hal_fifo_dtr_next_completed(),
162 * xge_hal_ring_dtr_next_completed(), xge_hal_channel_dtr_term_f{}.
164 typedef xge_hal_status_e (*xge_hal_channel_callback_f)
165 (xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
166 u8 t_code, void *userdata);
169 * function xge_hal_channel_dtr_init_f - Initialize descriptor callback.
170 * @channelh: Channel "containing" the @dtrh descriptor.
172 * @index: Index of the descriptor in the channel's set of descriptors.
173 * @userdata: Per-channel user data (a.k.a. context) specified at
174 * channel open time, via xge_hal_channel_open().
175 * @reopen: See xge_hal_channel_reopen_e{}.
177 * Initialize descriptor callback. Unless NULL is specified in the
178 * xge_hal_channel_attr_t{} structure passed to xge_hal_channel_open()),
179 * HAL invokes the callback as part of the xge_hal_channel_open()
181 * For the ring type of channel the ULD is expected to fill in this descriptor
182 * with buffer(s) and control information.
183 * For the fifo type of channel the ULD could use the callback to
184 * pre-set DMA mappings and/or alignment buffers.
186 * See also: xge_hal_channel_attr_t{}, xge_hal_channel_dtr_term_f{}.
188 typedef xge_hal_status_e (*xge_hal_channel_dtr_init_f)
189 (xge_hal_channel_h channelh,
193 xge_hal_channel_reopen_e reopen);
196 * function xge_hal_channel_dtr_term_f - Terminate descriptor callback.
197 * @channelh: Channel "containing" the @dtrh descriptor.
198 * @dtrh: First completed descriptor.
199 * @state: One of the xge_hal_dtr_state_e{} enumerated states.
200 * @userdata: Per-channel user data (a.k.a. context) specified at
201 * channel open time, via xge_hal_channel_open().
202 * @reopen: See xge_hal_channel_reopen_e{}.
204 * Terminate descriptor callback. Unless NULL is specified in the
205 * xge_hal_channel_attr_t{} structure passed to xge_hal_channel_open()),
206 * HAL invokes the callback as part of closing the corresponding
207 * channel, prior to de-allocating the channel and associated data
208 * structures (including descriptors).
209 * ULD should utilize the callback to (for instance) unmap
210 * and free DMA data buffers associated with the posted (state =
211 * XGE_HAL_DTR_STATE_POSTED) descriptors,
212 * as well as other relevant cleanup functions.
214 * See also: xge_hal_channel_attr_t{}, xge_hal_channel_dtr_init_f{}.
216 typedef void (*xge_hal_channel_dtr_term_f) (xge_hal_channel_h channelh,
218 xge_hal_dtr_state_e state,
220 xge_hal_channel_reopen_e reopen);
224 * struct xge_hal_channel_attr_t - Channel open "template".
225 * @type: xge_hal_channel_type_e channel type.
226 * @vp_id: Virtual path id
227 * @post_qid: Queue ID to post descriptors. For the link layer this
228 * number should be in the 0..7 range.
229 * @compl_qid: Completion queue ID. Must be set to zero for the link layer.
230 * @callback: Channel completion callback. HAL invokes the callback when there
231 * are new completions on that channel. In many implementations
232 * the @callback executes in the hw interrupt context.
233 * @dtr_init: Channel's descriptor-initialize callback.
234 * See xge_hal_channel_dtr_init_f{}.
235 * If not NULL, HAL invokes the callback when opening
236 * the channel via xge_hal_channel_open().
237 * @dtr_term: Channel's descriptor-terminate callback. If not NULL,
238 * HAL invokes the callback when closing the corresponding channel.
239 * See also xge_hal_channel_dtr_term_f{}.
240 * @userdata: User-defined "context" of _that_ channel. Passed back to the
241 * user as one of the @callback, @dtr_init, and @dtr_term arguments.
242 * @per_dtr_space: If specified (i.e., greater than zero): extra space
243 * reserved by HAL per each transmit or receive (depending on the
244 * channel type) descriptor. Can be used to store,
245 * and retrieve on completion, information specific
246 * to the upper-layer.
247 * @flags: xge_hal_channel_flag_e enumerated flags.
249 * Channel open "template". User fills the structure with channel
250 * attributes and passes it to xge_hal_channel_open().
251 * Usage: See ex_open{}.
253 typedef struct xge_hal_channel_attr_t {
254 xge_hal_channel_type_e type;
257 xge_hal_channel_callback_f callback;
258 xge_hal_channel_dtr_init_f dtr_init;
259 xge_hal_channel_dtr_term_f dtr_term;
262 xge_hal_channel_flag_e flags;
263 } xge_hal_channel_attr_t;
267 * ---------- complete/free section ---------------
268 * @item: List item; used to maintain a list of open channels.
269 * @callback: Channel completion callback. See
270 * xge_hal_channel_callback_f.
271 * @compl_index: Completion index. At any point in time points on the
272 * position in the channel, which will contain next
273 * to-be-completed descriptor.
274 * @length: Channel length. Currently allocated number of descriptors.
275 * The channel length "grows" when more descriptors get allocated.
276 * See _hal_mempool_grow.
277 * @free_arr: Free array. Contains completed descriptors that were freed
278 * (i.e., handed over back to HAL) by ULD.
279 * See xge_hal_fifo_dtr_free(), xge_hal_ring_dtr_free().
280 * @free_lock: Lock to protect @free_arr.
281 * ----------- reserve/post section ---------------
282 * @post_index: Post index. At any point in time points on the
283 * position in the channel, which'll contain next to-be-posted
285 * @post_lock: Lock to serialize multiple concurrent "posters" of descriptors
286 * on the given channel.
287 * @reserve_arr: Reserve array. Contains descriptors that can be reserved
288 * by ULD for the subsequent send or receive operation.
289 * See xge_hal_fifo_dtr_reserve(),
290 * xge_hal_ring_dtr_reserve().
291 * @reserve_length: Length of the @reserve_arr. The length dynamically
292 * changes: it decrements each time descriptor is reserved.
293 * @reserve_lock: Lock to serialize multiple concurrent threads accessing
295 * @reserve_threshold: Reserve threshold. Minimal number of free descriptors
296 * that ought to be preserved in the channel at all times.
297 * Note that @reserve_threshold >= 0 &&
298 * @reserve_threshold < @reserve_max.
299 * ------------ common section --------------------
300 * @devh: Device handle. HAL device object that contains _this_ channel.
301 * @dmah: Channel's DMA address. Used to synchronize (to/from device)
303 * @regh0: Base address of the device memory space handle. Copied from HAL device
304 * at channel open time.
305 * @regh1: Base address of the device memory space handle. Copied from HAL device
306 * at channel open time.
307 * @userdata: Per-channel opaque (void*) user-defined context, which may be
308 * upper-layer driver object, ULP connection, etc.
309 * Once channel is open, @userdata is passed back to user via
310 * xge_hal_channel_callback_f.
311 * @work_arr: Work array. Contains descriptors posted to the channel.
312 * Note that at any point in time @work_arr contains 3 types of
314 * 1) posted but not yet consumed by Xframe device;
315 * 2) consumed but not yet completed;
316 * 3) completed but not yet freed
317 * (via xge_hal_fifo_dtr_free() or xge_hal_ring_dtr_free())
318 * @saved_arr: Array used internally to optimize channel full-duplex
320 * @stats: Channel statistcis. Includes HAL internal counters, including
321 * for instance, number of times out-of-descriptors
322 * (see XGE_HAL_INF_OUT_OF_DESCRIPTORS) condition happened.
323 * ------------- "slow" section ------------------
324 * @type: Channel type. See xge_hal_channel_type_e{}.
325 * @vp_id: Virtual path id
326 * @post_qid: Identifies Xframe queue used for posting descriptors.
327 * @compl_qid: Identifies Xframe completion queue.
328 * @flags: Channel flags. See xge_hal_channel_flag_e{}.
329 * @reserve_initial: Initial number of descriptors allocated at channel open
330 * time (see xge_hal_channel_open()). The number of
331 * channel descriptors can grow at runtime
332 * up to @reserve_max value.
333 * @reserve_max: Maximum number of channel descriptors. See @reserve_initial.
334 * @is_open: True, if channel is open; false - otherwise.
335 * @per_dtr_space: Per-descriptor space (in bytes) that channel user can utilize
336 * to store per-operation control information.
337 * HAL channel object. HAL devices (see xge_hal_device_t{}) contains
338 * zero or more channels. HAL channel contains zero or more descriptors. The
339 * latter are used by ULD(s) to manage the device and/or send and receive data
340 * to remote peer(s) via the channel.
342 * See also: xge_hal_channel_type_e{}, xge_hal_channel_flag_e,
343 * xge_hal_channel_callback_f{}
346 /* complete/free section */
348 xge_hal_channel_callback_f callback;
352 #if defined(XGE_HAL_RX_MULTI_FREE_IRQ) || defined(XGE_HAL_TX_MULTI_FREE_IRQ) || \
353 defined(XGE_HAL_RX_MULTI_FREE) || defined(XGE_HAL_TX_MULTI_FREE)
354 spinlock_t free_lock;
357 unsigned int usage_cnt;
358 unsigned int poll_bytes;
360 /* reserve/post data path section */
363 int __xge_os_attr_cacheline_aligned
367 __xge_os_attr_cacheline_aligned;
369 spinlock_t reserve_lock;
370 spinlock_t post_lock;
374 int reserve_threshold;
379 xge_hal_device_h devh;
387 xge_hal_stats_channel_info_t stats;
390 xge_hal_channel_type_e type;
393 xge_hal_channel_flag_e flags;
398 xge_hal_channel_dtr_term_f dtr_term;
399 xge_hal_channel_dtr_init_f dtr_init;
409 volatile int in_interrupt;
412 } __xge_os_attr_cacheline_aligned xge_hal_channel_t ;
414 } xge_hal_channel_t __xge_os_attr_cacheline_aligned;
417 /* ========================== CHANNEL PRIVATE API ========================= */
420 __hal_channel_initialize(xge_hal_channel_h channelh,
421 xge_hal_channel_attr_t *attr, void **reserve_arr,
422 int reserve_initial, int reserve_max, int reserve_threshold);
424 void __hal_channel_terminate(xge_hal_channel_h channelh);
427 __hal_channel_allocate(xge_hal_device_h devh, int post_qid,
428 xge_hal_channel_type_e type);
430 void __hal_channel_free(xge_hal_channel_t *channel);
432 #if defined(XGE_DEBUG_FP) && (XGE_DEBUG_FP & XGE_DEBUG_FP_CHANNEL)
433 #define __HAL_STATIC_CHANNEL
434 #define __HAL_INLINE_CHANNEL
436 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL xge_hal_status_e
437 __hal_channel_dtr_alloc(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh);
439 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
440 __hal_channel_dtr_post(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh);
442 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
443 __hal_channel_dtr_try_complete(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh);
445 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
446 __hal_channel_dtr_complete(xge_hal_channel_h channelh);
448 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
449 __hal_channel_dtr_free(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh);
451 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
452 __hal_channel_dtr_dealloc(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh);
454 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
455 __hal_channel_dtr_restore(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
458 /* ========================== CHANNEL PUBLIC API ========================= */
460 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL int
461 xge_hal_channel_dtr_count(xge_hal_channel_h channelh);
463 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void*
464 xge_hal_channel_userdata(xge_hal_channel_h channelh);
466 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL int
467 xge_hal_channel_id(xge_hal_channel_h channelh);
469 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL int
470 xge_hal_check_alignment(dma_addr_t dma_pointer, int size, int alignment,
473 #else /* XGE_FASTPATH_EXTERN */
474 #define __HAL_STATIC_CHANNEL static
475 #define __HAL_INLINE_CHANNEL inline
476 #include <dev/nxge/xgehal/xgehal-channel-fp.c>
477 #endif /* XGE_FASTPATH_INLINE */
480 xge_hal_channel_open(xge_hal_device_h hldev, xge_hal_channel_attr_t *attr,
481 xge_hal_channel_h *channel,
482 xge_hal_channel_reopen_e reopen);
484 void xge_hal_channel_close(xge_hal_channel_h channelh,
485 xge_hal_channel_reopen_e reopen);
487 void xge_hal_channel_abort(xge_hal_channel_h channelh,
488 xge_hal_channel_reopen_e reopen);
492 #endif /* XGE_HAL_CHANNEL_H */