]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/vxge/vxgehal/vxgehal-channel.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / vxge / vxgehal / vxgehal-channel.c
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 #include <dev/vxge/vxgehal/vxgehal.h>
34
35
36 /*
37  * vxge_hal_channel_allocate - Allocate memory for channel
38  * @devh: Handle to the device object
39  * @vph: Handle to Virtual Path
40  * @type: Type of channel
41  * @length: Lengths of arrays
42  * @per_dtr_space: ULD requested per dtr space to be allocated in priv
43  * @userdata: User data to be passed back in the callback
44  *
45  * This function allocates required memory for the channel and various arrays
46  * in the channel
47  */
48 __hal_channel_t *
49 vxge_hal_channel_allocate(
50     vxge_hal_device_h devh,
51     vxge_hal_vpath_h vph,
52     __hal_channel_type_e type,
53     u32 length,
54     u32 per_dtr_space,
55     void *userdata)
56 {
57         vxge_hal_device_t *hldev = (vxge_hal_device_t *) devh;
58         __hal_channel_t *channel;
59         u32 i, size = 0;
60
61         vxge_assert((devh != NULL) && (vph != NULL));
62
63         vxge_hal_trace_log_channel("==> %s:%s:%d",
64             __FILE__, __func__, __LINE__);
65
66         vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT", vph = "
67             "0x"VXGE_OS_STXFMT", type = %d, length = %d, "
68             "per_dtr_space = %d, userdata = 0x"VXGE_OS_STXFMT,
69             (ptr_t) devh, (ptr_t) vph, type, length, per_dtr_space,
70             (ptr_t) userdata);
71
72         switch (type) {
73         case VXGE_HAL_CHANNEL_TYPE_FIFO:
74                 size = sizeof(__hal_fifo_t);
75                 break;
76         case VXGE_HAL_CHANNEL_TYPE_RING:
77                 size = sizeof(__hal_ring_t);
78                 break;
79
80
81         default:
82                 vxge_assert(size);
83                 break;
84
85         }
86
87         channel = (__hal_channel_t *) vxge_os_malloc(hldev->pdev, size);
88         if (channel == NULL) {
89                 vxge_hal_trace_log_channel("<== %s:%s:%d  Result: %d",
90                     __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY);
91                 return (NULL);
92         }
93
94         vxge_os_memzero(channel, size);
95         vxge_list_init(&channel->item);
96
97         channel->pdev = hldev->pdev;
98         channel->type = type;
99         channel->devh = devh;
100         channel->vph = vph;
101
102         channel->userdata = userdata;
103         channel->per_dtr_space = per_dtr_space;
104
105         channel->length = length;
106
107         channel->dtr_arr = (__hal_dtr_item_t *) vxge_os_malloc(hldev->pdev,
108             sizeof(__hal_dtr_item_t)*length);
109         if (channel->dtr_arr == NULL) {
110                 vxge_hal_channel_free(channel);
111                 vxge_hal_trace_log_channel("<== %s:%s:%d  Result: %d",
112                     __FILE__, __func__, __LINE__, VXGE_HAL_ERR_OUT_OF_MEMORY);
113                 return (NULL);
114         }
115
116         vxge_os_memzero(channel->dtr_arr, sizeof(__hal_dtr_item_t)*length);
117
118         channel->compl_index = 0;
119         channel->reserve_index = 0;
120
121         for (i = 0; i < length; i++)
122                 channel->dtr_arr[i].state = VXGE_HAL_CHANNEL_DTR_FREE;
123
124         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
125             __FILE__, __func__, __LINE__);
126         return (channel);
127 }
128
129 /*
130  * __hal_channel_free - Free memory allocated for channel
131  * @channel: channel to be freed
132  *
133  * This function deallocates memory from the channel and various arrays
134  * in the channel
135  */
136 void
137 vxge_hal_channel_free(
138     __hal_channel_t *channel)
139 {
140         int size = 0;
141         vxge_hal_device_t *hldev;
142
143         vxge_assert(channel != NULL);
144
145         hldev = (vxge_hal_device_t *) channel->devh;
146
147         vxge_hal_trace_log_channel("==> %s:%s:%d",
148             __FILE__, __func__, __LINE__);
149
150         vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
151             (ptr_t) channel);
152
153         vxge_assert(channel->pdev);
154
155         if (channel->dtr_arr) {
156                 vxge_os_free(channel->pdev, channel->dtr_arr,
157                     sizeof(__hal_dtr_item_t)*channel->length);
158                 channel->dtr_arr = NULL;
159         }
160
161         switch (channel->type) {
162         case VXGE_HAL_CHANNEL_TYPE_FIFO:
163                 size = sizeof(__hal_fifo_t);
164                 break;
165         case VXGE_HAL_CHANNEL_TYPE_RING:
166                 size = sizeof(__hal_ring_t);
167                 break;
168         default:
169                 break;
170         }
171
172         vxge_os_free(channel->pdev, channel, size);
173
174         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
175             __FILE__, __func__, __LINE__);
176 }
177
178 /*
179  * __hal_channel_initialize - Initialize a channel
180  * @channel: channel to be initialized
181  *
182  * This function initializes a channel by properly
183  *              setting the various references
184  */
185 vxge_hal_status_e
186 vxge_hal_channel_initialize(
187     __hal_channel_t *channel)
188 {
189         vxge_hal_device_t *hldev;
190         __hal_virtualpath_t *vpath;
191
192         vxge_assert(channel != NULL);
193
194         hldev = (vxge_hal_device_t *) channel->devh;
195         vpath = (__hal_virtualpath_t *)
196             ((__hal_vpath_handle_t *) channel->vph)->vpath;
197
198         vxge_assert(vpath != NULL);
199
200         vxge_hal_trace_log_channel("==> %s:%s:%d",
201             __FILE__, __func__, __LINE__);
202
203         vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
204             (ptr_t) channel);
205
206         switch (channel->type) {
207         case VXGE_HAL_CHANNEL_TYPE_FIFO:
208                 vpath->fifoh = (vxge_hal_fifo_h) channel;
209                 channel->stats =
210                     &((__hal_fifo_t *) channel)->stats->common_stats;
211                 break;
212         case VXGE_HAL_CHANNEL_TYPE_RING:
213                 vpath->ringh = (vxge_hal_ring_h) channel;
214                 channel->stats =
215                     &((__hal_ring_t *) channel)->stats->common_stats;
216                 break;
217
218
219         default:
220                 break;
221         }
222
223         channel->is_initd = 1;
224         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
225             __FILE__, __func__, __LINE__);
226
227         return (VXGE_HAL_OK);
228 }
229
230 /*
231  * __hal_channel_reset - Resets a channel
232  * @channel: channel to be reset
233  *
234  * This function resets a channel by properly setting the various references
235  */
236 vxge_hal_status_e
237 __hal_channel_reset(
238     __hal_channel_t *channel)
239 {
240         u32 i;
241         __hal_device_t *hldev;
242
243         vxge_assert(channel != NULL);
244
245         hldev = (__hal_device_t *) channel->devh;
246
247         vxge_hal_trace_log_channel("==> %s:%s:%d",
248             __FILE__, __func__, __LINE__);
249
250         vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
251             (ptr_t) channel);
252
253         vxge_assert(channel->pdev);
254
255         channel->compl_index = 0;
256         channel->reserve_index = 0;
257
258         for (i = 0; i < channel->length; i++) {
259                 channel->dtr_arr[i].state =
260                     VXGE_HAL_CHANNEL_DTR_FREE;
261         }
262
263         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
264             __FILE__, __func__, __LINE__);
265
266         return (VXGE_HAL_OK);
267 }
268
269 /*
270  * vxge_hal_channel_terminate - Deinitializes a channel
271  * @channel: channel to be deinitialized
272  *
273  * This function deinitializes a channel by properly
274  *              setting the various references
275  */
276 void
277 vxge_hal_channel_terminate(
278     __hal_channel_t *channel)
279 {
280         __hal_device_t *hldev;
281         __hal_virtualpath_t *vpath;
282
283         vxge_assert(channel != NULL);
284
285         if (!channel || !channel->is_initd)
286                 return;
287
288         hldev = (__hal_device_t *) channel->devh;
289         vpath = (__hal_virtualpath_t *)
290             ((__hal_vpath_handle_t *) channel->vph)->vpath;
291
292         vxge_assert(vpath != NULL);
293
294         vxge_hal_trace_log_channel("==> %s:%s:%d",
295             __FILE__, __func__, __LINE__);
296
297         vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
298             (ptr_t) channel);
299
300         switch (channel->type) {
301         case VXGE_HAL_CHANNEL_TYPE_FIFO:
302                 vpath->fifoh = 0;
303                 break;
304         case VXGE_HAL_CHANNEL_TYPE_RING:
305                 vpath->ringh = 0;
306                 break;
307         case VXGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
308                 vxge_list_remove(&channel->item);
309                 vpath->sw_stats->obj_counts.no_sqs--;
310                 break;
311         case VXGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
312                 vxge_list_remove(&channel->item);
313                 vpath->sw_stats->obj_counts.no_srqs--;
314                 break;
315         case VXGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
316                 vxge_list_remove(&channel->item);
317                 vpath->sw_stats->obj_counts.no_cqrqs--;
318                 break;
319         default:
320                 break;
321         }
322
323         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
324             __FILE__, __func__, __LINE__);
325 }
326
327 void
328 __hal_channel_init_pending_list(
329     vxge_hal_device_h devh)
330 {
331         __hal_device_t *hldev = (__hal_device_t *) devh;
332
333         vxge_assert(devh != NULL);
334
335         vxge_hal_trace_log_channel("==> %s:%s:%d",
336             __FILE__, __func__, __LINE__);
337
338         vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
339             (ptr_t) devh);
340         vxge_list_init(&hldev->pending_channel_list);
341
342 #if defined(VXGE_HAL_VP_CHANNELS)
343         vxge_os_spin_lock_init(&hldev->pending_channel_lock, hldev->pdev);
344 #elif defined(VXGE_HAL_VP_CHANNELS_IRQ)
345         vxge_os_spin_lock_init_irq(&hldev->pending_channel_lock, hldev->irqh);
346 #endif
347         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
348             __FILE__, __func__, __LINE__);
349 }
350
351 void
352 __hal_channel_insert_pending_list(
353     __hal_channel_t * channel)
354 {
355         __hal_device_t *hldev = (__hal_device_t *) channel->devh;
356
357         vxge_assert(channel != NULL);
358
359         vxge_hal_trace_log_channel("==> %s:%s:%d",
360             __FILE__, __func__, __LINE__);
361
362         vxge_hal_trace_log_channel("channel = 0x"VXGE_OS_STXFMT,
363             (ptr_t) channel);
364
365 #if defined(VXGE_HAL_PENDING_CHANNELS)
366         vxge_os_spin_lock(&hldev->pending_channel_lock);
367 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
368         vxge_os_spin_lock_irq(&hldev->pending_channel_lock, flags);
369 #endif
370
371         vxge_list_insert_before(&channel->item, &hldev->pending_channel_list);
372
373 #if defined(VXGE_HAL_PENDING_CHANNELS)
374         vxge_os_spin_unlock(&hldev->pending_channel_lock);
375 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
376         vxge_os_spin_unlock_irq(&hldev->pending_channel_lock, flags);
377 #endif
378
379         __hal_channel_process_pending_list(channel->devh);
380
381         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
382             __FILE__, __func__, __LINE__);
383 }
384
385 void
386 __hal_channel_process_pending_list(
387     vxge_hal_device_h devh)
388 {
389         vxge_hal_status_e status;
390         __hal_channel_t *channel;
391         __hal_device_t *hldev = (__hal_device_t *) devh;
392
393         vxge_assert(devh != NULL);
394
395         vxge_hal_trace_log_channel("==> %s:%s:%d",
396             __FILE__, __func__, __LINE__);
397
398         vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
399             (ptr_t) devh);
400
401         for (;;) {
402 #if defined(VXGE_HAL_PENDING_CHANNELS)
403                 vxge_os_spin_lock(&hldev->pending_channel_lock);
404 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
405                 vxge_os_spin_lock_irq(&hldev->pending_channel_lock, flags);
406 #endif
407
408                 channel = (__hal_channel_t *)
409                     vxge_list_first_get(&hldev->pending_channel_list);
410
411                 if (channel != NULL)
412                         vxge_list_remove(&channel->item);
413
414 #if defined(VXGE_HAL_PENDING_CHANNELS)
415                 vxge_os_spin_unlock(&hldev->pending_channel_lock);
416 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
417                 vxge_os_spin_unlock_irq(&hldev->pending_channel_lock, flags);
418 #endif
419
420                 if (channel == NULL) {
421                         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
422                             __FILE__, __func__, __LINE__);
423                         return;
424                 }
425
426                 switch (channel->type) {
427                 default:
428                         status = VXGE_HAL_OK;
429                         break;
430                 }
431
432                 if (status == VXGE_HAL_ERR_OUT_OF_MEMORY) {
433 #if defined(VXGE_HAL_PENDING_CHANNELS)
434                         vxge_os_spin_lock(&hldev->pending_channel_lock);
435 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
436                         vxge_os_spin_lock_irq(&hldev->pending_channel_lock,
437                             flags);
438 #endif
439
440                         vxge_list_insert(&channel->item,
441                             &hldev->pending_channel_list);
442
443 #if defined(VXGE_HAL_PENDING_CHANNELS)
444                         vxge_os_spin_unlock(&hldev->pending_channel_lock);
445 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
446                         vxge_os_spin_unlock_irq(&hldev->pending_channel_lock,
447                             flags);
448 #endif
449                         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
450                             __FILE__, __func__, __LINE__);
451
452                         return;
453                 }
454
455         }
456 }
457
458 void
459 __hal_channel_destroy_pending_list(
460     vxge_hal_device_h devh)
461 {
462         vxge_list_t *p, *n;
463         __hal_device_t *hldev = (__hal_device_t *) devh;
464
465         vxge_assert(devh != NULL);
466
467         vxge_hal_trace_log_channel("==> %s:%s:%d",
468             __FILE__, __func__, __LINE__);
469
470         vxge_hal_trace_log_channel("devh = 0x"VXGE_OS_STXFMT,
471             (ptr_t) devh);
472
473         vxge_list_for_each_safe(p, n, &hldev->pending_channel_list) {
474
475                 vxge_list_remove(p);
476
477                 switch (((__hal_channel_t *) p)->type) {
478                 default:
479                         break;
480                 }
481
482         }
483
484 #if defined(VXGE_HAL_PENDING_CHANNELS)
485         vxge_os_spin_lock_destroy(&hldev->pending_channel_lock,
486             hldev->header.pdev);
487 #elif defined(VXGE_HAL_PENDING_CHANNELS_IRQ)
488         vxge_os_spin_lock_destroy_irq(&hldev->pending_channel_lock,
489             hldev->header.pdev);
490 #endif
491         vxge_hal_trace_log_channel("<== %s:%s:%d  Result: 0",
492             __FILE__, __func__, __LINE__);
493 }