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