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: stable/10/sys/dev/nxge/xgehal/xgehal-channel.c 173139 2007-10-29 14:19:32Z rwatson $
27 */
28
29 #include <dev/nxge/include/xgehal-channel.h>
30 #include <dev/nxge/include/xgehal-fifo.h>
31 #include <dev/nxge/include/xgehal-ring.h>
32 #include <dev/nxge/include/xgehal-device.h>
33 #include <dev/nxge/include/xgehal-regs.h>
34
35 /*
36 * __hal_channel_dtr_next_reservelist
37 *
38 * Walking through the all available DTRs.
39 */
40 static xge_hal_status_e
__hal_channel_dtr_next_reservelist(xge_hal_channel_h channelh,xge_hal_dtr_h * dtrh)41 __hal_channel_dtr_next_reservelist(xge_hal_channel_h channelh,
42 xge_hal_dtr_h *dtrh)
43 {
44 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
45
46 if (channel->reserve_top >= channel->reserve_length) {
47 return XGE_HAL_INF_NO_MORE_FREED_DESCRIPTORS;
48 }
49
50 *dtrh = channel->reserve_arr[channel->reserve_top++];
51
52 return XGE_HAL_OK;
53 }
54
55 /*
56 * __hal_channel_dtr_next_freelist
57 *
58 * Walking through the "freed" DTRs.
59 */
60 static xge_hal_status_e
__hal_channel_dtr_next_freelist(xge_hal_channel_h channelh,xge_hal_dtr_h * dtrh)61 __hal_channel_dtr_next_freelist(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh)
62 {
63 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
64
65 if (channel->reserve_initial == channel->free_length) {
66 return XGE_HAL_INF_NO_MORE_FREED_DESCRIPTORS;
67 }
68
69 *dtrh = channel->free_arr[channel->free_length++];
70
71 return XGE_HAL_OK;
72 }
73
74 /*
75 * __hal_channel_dtr_next_not_completed - Get the _next_ posted but
76 * not completed descriptor.
77 *
78 * Walking through the "not completed" DTRs.
79 */
80 static xge_hal_status_e
__hal_channel_dtr_next_not_completed(xge_hal_channel_h channelh,xge_hal_dtr_h * dtrh)81 __hal_channel_dtr_next_not_completed(xge_hal_channel_h channelh,
82 xge_hal_dtr_h *dtrh)
83 {
84 xge_hal_ring_rxd_1_t *rxdp; /* doesn't matter 1, 3 or 5... */
85 __hal_channel_dtr_try_complete(channelh, dtrh);
86 if (*dtrh == NULL) {
87 return XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS;
88 }
89
90 rxdp = (xge_hal_ring_rxd_1_t *)*dtrh;
91 xge_assert(rxdp->host_control!=0);
92
93 __hal_channel_dtr_complete(channelh);
94
95 return XGE_HAL_OK;
96 }
97
98 xge_hal_channel_t*
__hal_channel_allocate(xge_hal_device_h devh,int post_qid,xge_hal_channel_type_e type)99 __hal_channel_allocate(xge_hal_device_h devh, int post_qid,
100 xge_hal_channel_type_e type)
101 {
102 xge_hal_device_t *hldev = (xge_hal_device_t*)devh;
103 xge_hal_channel_t *channel;
104 int size = 0;
105
106 switch(type) {
107 case XGE_HAL_CHANNEL_TYPE_FIFO:
108 xge_assert(post_qid + 1 >= XGE_HAL_MIN_FIFO_NUM &&
109 post_qid + 1 <= XGE_HAL_MAX_FIFO_NUM);
110 size = sizeof(xge_hal_fifo_t);
111 break;
112 case XGE_HAL_CHANNEL_TYPE_RING:
113 xge_assert(post_qid + 1 >= XGE_HAL_MIN_RING_NUM &&
114 post_qid + 1 <= XGE_HAL_MAX_RING_NUM);
115 size = sizeof(xge_hal_ring_t);
116 break;
117 default :
118 xge_assert(size);
119 break;
120
121 }
122
123
124 /* allocate FIFO channel */
125 channel = (xge_hal_channel_t *) xge_os_malloc(hldev->pdev, size);
126 if (channel == NULL) {
127 return NULL;
128 }
129 xge_os_memzero(channel, size);
130
131 channel->pdev = hldev->pdev;
132 channel->regh0 = hldev->regh0;
133 channel->regh1 = hldev->regh1;
134 channel->type = type;
135 channel->devh = devh;
136 channel->post_qid = post_qid;
137 channel->compl_qid = 0;
138
139 return channel;
140 }
141
__hal_channel_free(xge_hal_channel_t * channel)142 void __hal_channel_free(xge_hal_channel_t *channel)
143 {
144 int size = 0;
145
146 xge_assert(channel->pdev);
147
148 switch(channel->type) {
149 case XGE_HAL_CHANNEL_TYPE_FIFO:
150 size = sizeof(xge_hal_fifo_t);
151 break;
152 case XGE_HAL_CHANNEL_TYPE_RING:
153 size = sizeof(xge_hal_ring_t);
154 break;
155 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
156 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
157 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
158 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE:
159 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE:
160 xge_assert(size);
161 break;
162 default:
163 break;
164 }
165
166 xge_os_free(channel->pdev, channel, size);
167 }
168
169 xge_hal_status_e
__hal_channel_initialize(xge_hal_channel_h channelh,xge_hal_channel_attr_t * attr,void ** reserve_arr,int reserve_initial,int reserve_max,int reserve_threshold)170 __hal_channel_initialize (xge_hal_channel_h channelh,
171 xge_hal_channel_attr_t *attr, void **reserve_arr,
172 int reserve_initial, int reserve_max, int reserve_threshold)
173 {
174 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
175 xge_hal_device_t *hldev;
176
177 hldev = (xge_hal_device_t *)channel->devh;
178
179 channel->dtr_term = attr->dtr_term;
180 channel->dtr_init = attr->dtr_init;
181 channel->callback = attr->callback;
182 channel->userdata = attr->userdata;
183 channel->flags = attr->flags;
184 channel->per_dtr_space = attr->per_dtr_space;
185
186 channel->reserve_arr = reserve_arr;
187 channel->reserve_initial = reserve_initial;
188 channel->reserve_max = reserve_max;
189 channel->reserve_length = channel->reserve_initial;
190 channel->reserve_threshold = reserve_threshold;
191 channel->reserve_top = 0;
192 channel->saved_arr = (void **) xge_os_malloc(hldev->pdev,
193 sizeof(void*)*channel->reserve_max);
194 if (channel->saved_arr == NULL) {
195 return XGE_HAL_ERR_OUT_OF_MEMORY;
196 }
197 xge_os_memzero(channel->saved_arr, sizeof(void*)*channel->reserve_max);
198 channel->free_arr = channel->saved_arr;
199 channel->free_length = channel->reserve_initial;
200 channel->work_arr = (void **) xge_os_malloc(hldev->pdev,
201 sizeof(void*)*channel->reserve_max);
202 if (channel->work_arr == NULL) {
203 return XGE_HAL_ERR_OUT_OF_MEMORY;
204 }
205 xge_os_memzero(channel->work_arr,
206 sizeof(void*)*channel->reserve_max);
207 channel->post_index = 0;
208 channel->compl_index = 0;
209 channel->length = channel->reserve_initial;
210
211 channel->orig_arr = (void **) xge_os_malloc(hldev->pdev,
212 sizeof(void*)*channel->reserve_max);
213 if (channel->orig_arr == NULL)
214 return XGE_HAL_ERR_OUT_OF_MEMORY;
215
216 xge_os_memzero(channel->orig_arr, sizeof(void*)*channel->reserve_max);
217
218 #if defined(XGE_HAL_RX_MULTI_FREE_IRQ) || defined(XGE_HAL_TX_MULTI_FREE_IRQ)
219 xge_os_spin_lock_init_irq(&channel->free_lock, hldev->irqh);
220 #elif defined(XGE_HAL_RX_MULTI_FREE) || defined(XGE_HAL_TX_MULTI_FREE)
221 xge_os_spin_lock_init(&channel->free_lock, hldev->pdev);
222 #endif
223
224 return XGE_HAL_OK;
225 }
226
__hal_channel_terminate(xge_hal_channel_h channelh)227 void __hal_channel_terminate(xge_hal_channel_h channelh)
228 {
229 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
230 xge_hal_device_t *hldev;
231
232 hldev = (xge_hal_device_t *)channel->devh;
233
234 xge_assert(channel->pdev);
235 /* undo changes made at channel_initialize() */
236 if (channel->work_arr) {
237 xge_os_free(channel->pdev, channel->work_arr,
238 sizeof(void*)*channel->reserve_max);
239 channel->work_arr = NULL;
240 }
241
242 if (channel->saved_arr) {
243 xge_os_free(channel->pdev, channel->saved_arr,
244 sizeof(void*)*channel->reserve_max);
245 channel->saved_arr = NULL;
246 }
247
248 if (channel->orig_arr) {
249 xge_os_free(channel->pdev, channel->orig_arr,
250 sizeof(void*)*channel->reserve_max);
251 channel->orig_arr = NULL;
252 }
253
254 #if defined(XGE_HAL_RX_MULTI_FREE_IRQ) || defined(XGE_HAL_TX_MULTI_FREE_IRQ)
255 xge_os_spin_lock_destroy_irq(&channel->free_lock, hldev->irqh);
256 #elif defined(XGE_HAL_RX_MULTI_FREE) || defined(XGE_HAL_TX_MULTI_FREE)
257 xge_os_spin_lock_destroy(&channel->free_lock, hldev->pdev);
258 #endif
259 }
260
261 /**
262 * xge_hal_channel_open - Open communication channel.
263 * @devh: HAL device, pointer to xge_hal_device_t structure.
264 * @attr: Contains attributes required to open
265 * the channel.
266 * @channelh: The channel handle. On success (XGE_HAL_OK) HAL fills
267 * this "out" parameter with a valid channel handle.
268 * @reopen: See xge_hal_channel_reopen_e{}.
269 *
270 * Open communication channel with the device.
271 *
272 * HAL uses (persistent) channel configuration to allocate both channel
273 * and Xframe Tx and Rx descriptors.
274 * Notes:
275 * 1) The channel config data is fed into HAL prior to
276 * xge_hal_channel_open().
277 *
278 * 2) The corresponding hardware queues must be already configured and
279 * enabled.
280 *
281 * 3) Either down or up queue may be omitted, in which case the channel
282 * is treated as _unidirectional_.
283 *
284 * 4) Post and completion queue may be the same, in which case the channel
285 * is said to have "in-band completions".
286 *
287 * Note that free_channels list is not protected. i.e. caller must provide
288 * safe context.
289 *
290 * Returns: XGE_HAL_OK - success.
291 * XGE_HAL_ERR_CHANNEL_NOT_FOUND - Unable to locate the channel.
292 * XGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed.
293 *
294 * See also: xge_hal_channel_attr_t{}.
295 * Usage: See ex_open{}.
296 */
297 xge_hal_status_e
xge_hal_channel_open(xge_hal_device_h devh,xge_hal_channel_attr_t * attr,xge_hal_channel_h * channelh,xge_hal_channel_reopen_e reopen)298 xge_hal_channel_open(xge_hal_device_h devh,
299 xge_hal_channel_attr_t *attr,
300 xge_hal_channel_h *channelh,
301 xge_hal_channel_reopen_e reopen)
302 {
303 xge_list_t *item;
304 int i;
305 xge_hal_status_e status = XGE_HAL_OK;
306 xge_hal_channel_t *channel = NULL;
307 xge_hal_device_t *device = (xge_hal_device_t *)devh;
308
309 xge_assert(device);
310 xge_assert(attr);
311
312 *channelh = NULL;
313
314 /* find channel */
315 xge_list_for_each(item, &device->free_channels) {
316 xge_hal_channel_t *tmp;
317
318 tmp = xge_container_of(item, xge_hal_channel_t, item);
319 if (tmp->type == attr->type &&
320 tmp->post_qid == attr->post_qid &&
321 tmp->compl_qid == attr->compl_qid) {
322 channel = tmp;
323 break;
324 }
325 }
326
327 if (channel == NULL) {
328 return XGE_HAL_ERR_CHANNEL_NOT_FOUND;
329 }
330
331 xge_assert((channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) ||
332 (channel->type == XGE_HAL_CHANNEL_TYPE_RING));
333
334 if (reopen == XGE_HAL_CHANNEL_OC_NORMAL) {
335 /* allocate memory, initialize pointers, etc */
336 switch(channel->type) {
337 case XGE_HAL_CHANNEL_TYPE_FIFO:
338 status = __hal_fifo_open(channel, attr);
339 break;
340 case XGE_HAL_CHANNEL_TYPE_RING:
341 status = __hal_ring_open(channel, attr);
342 break;
343 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
344 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
345 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
346 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE:
347 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE:
348 status = XGE_HAL_FAIL;
349 break;
350 default:
351 break;
352 }
353
354 if (status == XGE_HAL_OK) {
355 for (i = 0; i < channel->reserve_initial; i++) {
356 channel->orig_arr[i] =
357 channel->reserve_arr[i];
358 }
359 }
360 else
361 return status;
362 } else {
363 xge_assert(reopen == XGE_HAL_CHANNEL_RESET_ONLY);
364
365 for (i = 0; i < channel->reserve_initial; i++) {
366 channel->reserve_arr[i] = channel->orig_arr[i];
367 channel->free_arr[i] = NULL;
368 }
369 channel->free_length = channel->reserve_initial;
370 channel->reserve_length = channel->reserve_initial;
371 channel->reserve_top = 0;
372 channel->post_index = 0;
373 channel->compl_index = 0;
374 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
375 status = __hal_ring_initial_replenish(channel,
376 reopen);
377 if (status != XGE_HAL_OK)
378 return status;
379 }
380 }
381
382 /* move channel to the open state list */
383
384 switch(channel->type) {
385 case XGE_HAL_CHANNEL_TYPE_FIFO:
386 xge_list_remove(&channel->item);
387 xge_list_insert(&channel->item, &device->fifo_channels);
388 break;
389 case XGE_HAL_CHANNEL_TYPE_RING:
390 xge_list_remove(&channel->item);
391 xge_list_insert(&channel->item, &device->ring_channels);
392 break;
393 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
394 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
395 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
396 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE:
397 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE:
398 xge_assert(channel->type == XGE_HAL_CHANNEL_TYPE_FIFO ||
399 channel->type == XGE_HAL_CHANNEL_TYPE_RING);
400 break;
401 default:
402 break;
403 }
404 channel->is_open = 1;
405 channel->terminating = 0;
406 /*
407 * The magic check the argument validity, has to be
408 * removed before 03/01/2005.
409 */
410 channel->magic = XGE_HAL_MAGIC;
411
412 *channelh = channel;
413
414 return XGE_HAL_OK;
415 }
416
417 /**
418 * xge_hal_channel_abort - Abort the channel.
419 * @channelh: Channel handle.
420 * @reopen: See xge_hal_channel_reopen_e{}.
421 *
422 * Terminate (via xge_hal_channel_dtr_term_f{}) all channel descriptors.
423 * Currently used internally only by HAL, as part of its
424 * xge_hal_channel_close() and xge_hal_channel_open() in case
425 * of fatal error.
426 *
427 * See also: xge_hal_channel_dtr_term_f{}.
428 */
xge_hal_channel_abort(xge_hal_channel_h channelh,xge_hal_channel_reopen_e reopen)429 void xge_hal_channel_abort(xge_hal_channel_h channelh,
430 xge_hal_channel_reopen_e reopen)
431 {
432 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
433 xge_hal_dtr_h dtr;
434 #ifdef XGE_OS_MEMORY_CHECK
435 int check_cnt = 0;
436 #endif
437 int free_length_sav;
438 int reserve_top_sav;
439
440 if (channel->dtr_term == NULL) {
441 return;
442 }
443
444 free_length_sav = channel->free_length;
445 while (__hal_channel_dtr_next_freelist(channelh, &dtr) == XGE_HAL_OK) {
446 #ifdef XGE_OS_MEMORY_CHECK
447 #ifdef XGE_DEBUG_ASSERT
448 if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
449 xge_assert(!__hal_fifo_txdl_priv(dtr)->allocated);
450 } else {
451 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
452 xge_assert(!__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtr)->allocated);
453 }
454 }
455 #endif
456 check_cnt++;
457 #endif
458 channel->dtr_term(channel, dtr, XGE_HAL_DTR_STATE_FREED,
459 channel->userdata, reopen);
460 }
461 channel->free_length = free_length_sav;
462
463 while (__hal_channel_dtr_next_not_completed(channelh, &dtr) ==
464 XGE_HAL_OK) {
465 #ifdef XGE_OS_MEMORY_CHECK
466 #ifdef XGE_DEBUG_ASSERT
467 if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
468 xge_assert(__hal_fifo_txdl_priv(dtr)->allocated);
469 } else {
470 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
471 xge_assert(__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtr)
472 ->allocated);
473 }
474 }
475 #endif
476 check_cnt++;
477 #endif
478 channel->dtr_term(channel, dtr, XGE_HAL_DTR_STATE_POSTED,
479 channel->userdata, reopen);
480
481 }
482
483 reserve_top_sav = channel->reserve_top;
484 while (__hal_channel_dtr_next_reservelist(channelh, &dtr) ==
485 XGE_HAL_OK) {
486 #ifdef XGE_OS_MEMORY_CHECK
487 #ifdef XGE_DEBUG_ASSERT
488 if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) {
489 xge_assert(!__hal_fifo_txdl_priv(dtr)->allocated);
490 } else {
491 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) {
492 xge_assert(!__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtr)->allocated);
493 }
494 }
495 #endif
496 check_cnt++;
497 #endif
498 channel->dtr_term(channel, dtr, XGE_HAL_DTR_STATE_AVAIL,
499 channel->userdata, reopen);
500 }
501 channel->reserve_top = reserve_top_sav;
502
503 xge_assert(channel->reserve_length ==
504 (channel->free_length + channel->reserve_top));
505
506 #ifdef XGE_OS_MEMORY_CHECK
507 xge_assert(check_cnt == channel->reserve_initial);
508 #endif
509
510 }
511
512 /**
513 * xge_hal_channel_close - Close communication channel.
514 * @channelh: The channel handle.
515 * @reopen: See xge_hal_channel_reopen_e{}.
516 *
517 * Will close previously opened channel and deallocate associated resources.
518 * Channel must be opened otherwise assert will be generated.
519 * Note that free_channels list is not protected. i.e. caller must provide
520 * safe context.
521 */
xge_hal_channel_close(xge_hal_channel_h channelh,xge_hal_channel_reopen_e reopen)522 void xge_hal_channel_close(xge_hal_channel_h channelh,
523 xge_hal_channel_reopen_e reopen)
524 {
525 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh;
526 xge_hal_device_t *hldev;
527 xge_list_t *item;
528 xge_assert(channel);
529 xge_assert(channel->type < XGE_HAL_CHANNEL_TYPE_MAX);
530
531 hldev = (xge_hal_device_t *)channel->devh;
532 channel->is_open = 0;
533 channel->magic = XGE_HAL_DEAD;
534
535 /* sanity check: make sure channel is not in free list */
536 xge_list_for_each(item, &hldev->free_channels) {
537 xge_hal_channel_t *tmp;
538
539 tmp = xge_container_of(item, xge_hal_channel_t, item);
540 xge_assert(!tmp->is_open);
541 if (channel == tmp) {
542 return;
543 }
544 }
545
546 xge_hal_channel_abort(channel, reopen);
547
548 xge_assert((channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) ||
549 (channel->type == XGE_HAL_CHANNEL_TYPE_RING));
550
551 if (reopen == XGE_HAL_CHANNEL_OC_NORMAL) {
552 /* de-allocate */
553 switch(channel->type) {
554 case XGE_HAL_CHANNEL_TYPE_FIFO:
555 __hal_fifo_close(channelh);
556 break;
557 case XGE_HAL_CHANNEL_TYPE_RING:
558 __hal_ring_close(channelh);
559 break;
560 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE:
561 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE:
562 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE:
563 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE:
564 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE:
565 xge_assert(channel->type == XGE_HAL_CHANNEL_TYPE_FIFO ||
566 channel->type == XGE_HAL_CHANNEL_TYPE_RING);
567 break;
568 default:
569 break;
570 }
571 }
572 else
573 xge_assert(reopen == XGE_HAL_CHANNEL_RESET_ONLY);
574
575 /* move channel back to free state list */
576 xge_list_remove(&channel->item);
577 xge_list_insert(&channel->item, &hldev->free_channels);
578
579 if (xge_list_is_empty(&hldev->fifo_channels) &&
580 xge_list_is_empty(&hldev->ring_channels)) {
581 /* clear msix_idx in case of following HW reset */
582 hldev->reset_needed_after_close = 1;
583 }
584 }
585