]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/vxge/vxgehal/vxgehal-channel.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / vxge / vxgehal / vxgehal-channel.h
1 /*-
2  * Copyright(c) 2002-2011 Exar Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification are permitted provided the following conditions are met:
7  *
8  *    1. Redistributions of source code must retain the above copyright notice,
9  *       this list of conditions and the following disclaimer.
10  *
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.
14  *
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.
18  *
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.
30  */
31 /*$FreeBSD$*/
32
33 #ifndef VXGE_HAL_CHANNEL_H
34 #define VXGE_HAL_CHANNEL_H
35
36 __EXTERN_BEGIN_DECLS
37
38 /*
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
41  */
42 typedef void *__hal_dtr_h;
43
44 /*
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.
56  *
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.
59  */
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;
71
72 /*
73  * __hal_dtr_item_t
74  * @dtr: Pointer to the descriptors that contains the dma data
75  *              to/from the device.
76  * @hal_priv: HAL Private data related to the dtr.
77  * @uld_priv: ULD Private data related to the dtr.
78  */
79 typedef struct __hal_dtr_item_t {
80         void   *dtr;
81         void   *hal_priv;
82         void   *uld_priv;
83         u32     state;
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
88 } __hal_dtr_item_t;
89
90 /*
91  * __hal_channel_t
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
101  *      private data.
102  *      Note that at any point in time @dtr_arr contains 3 types of
103  *      descriptors:
104  *      1) posted but not yet consumed by X3100 device;
105  *      2) consumed but not yet completed;
106  *      3) 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
109  *      descriptor.
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.
128  *
129  * HAL channel object.
130  *
131  * See also: vxge_hal_channel_type_e {}, vxge_hal_channel_flag_e
132  */
133 typedef struct __hal_channel_t {
134         vxge_list_t             item;
135         __hal_channel_type_e    type;
136         vxge_hal_device_h       devh;
137         pci_dev_h               pdev;
138         vxge_hal_vpath_h        vph;
139         u32                     length;
140         u32                     is_initd;
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;
145         u32                     poll_bytes;
146         u32                     per_dtr_space;
147         vxge_hal_vpath_stats_sw_common_info_t *stats;
148         void                    *userdata;
149 } __hal_channel_t __vxge_os_attr_cacheline_aligned;
150
151 #define __hal_channel_is_posted_dtr(channel, index) \
152             ((channel)->dtr_arr[index].state == VXGE_HAL_CHANNEL_DTR_POSTED)
153
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)
161
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))
167
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))
173
174 /* ========================== CHANNEL PRIVATE API ========================= */
175
176 __hal_channel_t *
177 vxge_hal_channel_allocate(
178     vxge_hal_device_h devh,
179     vxge_hal_vpath_h vph,
180     __hal_channel_type_e type,
181     u32 length,
182     u32 per_dtr_space,
183     void *userdata);
184
185 void
186 vxge_hal_channel_free(
187     __hal_channel_t *channel);
188
189 vxge_hal_status_e
190 vxge_hal_channel_initialize(
191     __hal_channel_t *channel);
192
193 vxge_hal_status_e
194 __hal_channel_reset(
195     __hal_channel_t *channel);
196
197 void
198 vxge_hal_channel_terminate(
199     __hal_channel_t *channel);
200
201 void
202 __hal_channel_init_pending_list(
203     vxge_hal_device_h devh);
204
205 void
206 __hal_channel_insert_pending_list(
207     __hal_channel_t * channel);
208
209 void
210 __hal_channel_process_pending_list(
211     vxge_hal_device_h devhv);
212
213 void
214 __hal_channel_destroy_pending_list(
215     vxge_hal_device_h devh);
216
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 */
224
225 /* ========================== CHANNEL Fast Path API ========================= */
226 /*
227  * __hal_channel_dtr_reserve- Reserve a dtr from the channel
228  * @channelh: Channel
229  * @dtrh: Buffer to return the DTR pointer
230  *
231  * Reserve a dtr from the reserve array.
232  *
233  */
234 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL vxge_hal_status_e
235 /* LINTED */
236 __hal_channel_dtr_reserve(__hal_channel_t *channel, __hal_dtr_h *dtrh)
237 {
238         vxge_hal_status_e status = VXGE_HAL_INF_OUT_OF_DESCRIPTORS;
239
240         *dtrh = NULL;
241
242         if (channel->dtr_arr[channel->reserve_index].state ==
243             VXGE_HAL_CHANNEL_DTR_FREE) {
244
245                 *dtrh = channel->dtr_arr[channel->reserve_index].dtr;
246
247                 channel->dtr_arr[channel->reserve_index].state =
248                     VXGE_HAL_CHANNEL_DTR_RESERVED;
249
250                 if (++channel->reserve_index == channel->length)
251                         channel->reserve_index = 0;
252
253                 status = VXGE_HAL_OK;
254
255         } else {
256
257 #if (VXGE_COMPONENT_HAL_CHANNEL & VXGE_DEBUG_MODULE_MASK)
258                 __hal_device_t *hldev = (__hal_device_t *) channel->devh;
259
260                 vxge_hal_info_log_channel("channel %d is full!", channel->type);
261 #endif
262
263                 channel->stats->full_cnt++;
264         }
265
266         return (status);
267 }
268
269 /*
270  * __hal_channel_dtr_restore - Restores a dtr to the channel
271  * @channelh: Channel
272  * @dtr: DTR pointer
273  *
274  * Returns a dtr back to reserve array.
275  *
276  */
277 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
278 /* LINTED */
279 __hal_channel_dtr_restore(__hal_channel_t *channel, __hal_dtr_h dtrh)
280 {
281         u32 dtr_index;
282
283         /*
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
287          */
288
289         if (channel->reserve_index == 0)
290                 dtr_index = channel->length;
291         else
292                 dtr_index = channel->reserve_index - 1;
293
294         if ((channel->dtr_arr[dtr_index].dtr = dtrh) != NULL) {
295
296                 channel->reserve_index = dtr_index;
297                 channel->dtr_arr[dtr_index].state = VXGE_HAL_CHANNEL_DTR_FREE;
298
299 #if (VXGE_COMPONENT_HAL_CHANNEL & VXGE_DEBUG_MODULE_MASK)
300
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);
306 #endif
307         }
308 }
309
310 /*
311  * __hal_channel_dtr_post - Post a dtr to the channel
312  * @channelh: Channel
313  * @dtr: DTR pointer
314  *
315  * Posts a dtr to work array.
316  *
317  */
318 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
319 /* LINTED */
320 __hal_channel_dtr_post(__hal_channel_t *channel, u32 dtr_index)
321 {
322         channel->dtr_arr[dtr_index].state =
323             VXGE_HAL_CHANNEL_DTR_POSTED;
324 }
325
326 /*
327  * __hal_channel_dtr_try_complete - Returns next completed dtr
328  * @channelh: Channel
329  * @dtr: Buffer to return the next completed DTR pointer
330  *
331  * Returns the next completed dtr with out removing it from work array
332  *
333  */
334 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
335 /* LINTED */
336 __hal_channel_dtr_try_complete(__hal_channel_t *channel, __hal_dtr_h *dtrh)
337 {
338         vxge_assert(channel->dtr_arr);
339         vxge_assert(channel->compl_index < channel->length);
340
341         if (channel->dtr_arr[channel->compl_index].state ==
342             VXGE_HAL_CHANNEL_DTR_POSTED)
343                 *dtrh = channel->dtr_arr[channel->compl_index].dtr;
344         else
345                 *dtrh = NULL;
346 }
347
348 /*
349  * __hal_channel_dtr_complete - Removes next completed dtr from the work array
350  * @channelh: Channel
351  *
352  * Removes the next completed dtr from work array
353  *
354  */
355 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
356 /* LINTED */
357 __hal_channel_dtr_complete(__hal_channel_t *channel)
358 {
359         channel->dtr_arr[channel->compl_index].state =
360         VXGE_HAL_CHANNEL_DTR_COMPLETED;
361
362         if (++channel->compl_index == channel->length)
363                 channel->compl_index = 0;
364
365         channel->stats->total_compl_cnt++;
366 }
367
368 /*
369  * __hal_channel_dtr_free - Frees a dtr
370  * @channelh: Channel
371  * @index:  Index of DTR
372  *
373  * Returns the dtr to free array
374  *
375  */
376 __HAL_STATIC_CHANNEL __HAL_INLINE_CHANNEL void
377 /* LINTED */
378 __hal_channel_dtr_free(__hal_channel_t *channel, u32 dtr_index)
379 {
380         channel->dtr_arr[dtr_index].state =
381             VXGE_HAL_CHANNEL_DTR_FREE;
382 }
383
384 __EXTERN_END_DECLS
385
386 #endif  /* VXGE_HAL_CHANNEL_H */