xgehal-channel.c revision 171095
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: head/sys/dev/nxge/xgehal/xgehal-channel.c 171095 2007-06-29 22:47:18Z sam $ 27 */ 28 29/* 30 * FileName : xgehal-channel.c 31 * 32 * Description: chipset channel abstraction 33 * 34 * Created: 10 May 2004 35 */ 36 37#include <dev/nxge/include/xgehal-channel.h> 38#include <dev/nxge/include/xgehal-fifo.h> 39#include <dev/nxge/include/xgehal-ring.h> 40#include <dev/nxge/include/xgehal-device.h> 41#include <dev/nxge/include/xgehal-regs.h> 42#ifdef XGEHAL_RNIC 43#include <dev/nxge/include/xgehal-types.h> 44#include "xgehal-iov.h" 45#endif 46 47/* 48 * __hal_channel_dtr_next_reservelist 49 * 50 * Walking through the all available DTRs. 51 */ 52static xge_hal_status_e 53__hal_channel_dtr_next_reservelist(xge_hal_channel_h channelh, 54 xge_hal_dtr_h *dtrh) 55{ 56 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh; 57 58 if (channel->reserve_top >= channel->reserve_length) { 59 return XGE_HAL_INF_NO_MORE_FREED_DESCRIPTORS; 60 } 61 62 *dtrh = channel->reserve_arr[channel->reserve_top++]; 63 64 return XGE_HAL_OK; 65} 66 67/* 68 * __hal_channel_dtr_next_freelist 69 * 70 * Walking through the "freed" DTRs. 71 */ 72static xge_hal_status_e 73__hal_channel_dtr_next_freelist(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh) 74{ 75 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh; 76 77 if (channel->reserve_initial == channel->free_length) { 78 return XGE_HAL_INF_NO_MORE_FREED_DESCRIPTORS; 79 } 80 81 *dtrh = channel->free_arr[channel->free_length++]; 82 83 return XGE_HAL_OK; 84} 85 86/* 87 * __hal_channel_dtr_next_not_completed - Get the _next_ posted but 88 * not completed descriptor. 89 * 90 * Walking through the "not completed" DTRs. 91 */ 92static xge_hal_status_e 93__hal_channel_dtr_next_not_completed(xge_hal_channel_h channelh, 94 xge_hal_dtr_h *dtrh) 95{ 96#ifndef XGEHAL_RNIC 97 xge_hal_ring_rxd_1_t *rxdp; /* doesn't matter 1, 3 or 5... */ 98#endif 99 100 __hal_channel_dtr_try_complete(channelh, dtrh); 101 if (*dtrh == NULL) { 102 return XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS; 103 } 104 105#ifndef XGEHAL_RNIC 106 rxdp = (xge_hal_ring_rxd_1_t *)*dtrh; 107 xge_assert(rxdp->host_control!=0); 108#endif 109 110 __hal_channel_dtr_complete(channelh); 111 112 return XGE_HAL_OK; 113} 114 115xge_hal_channel_t* 116__hal_channel_allocate(xge_hal_device_h devh, int post_qid, 117#ifdef XGEHAL_RNIC 118 u32 vp_id, 119#endif 120 xge_hal_channel_type_e type) 121{ 122 xge_hal_device_t *hldev = (xge_hal_device_t*)devh; 123 xge_hal_channel_t *channel; 124 int size = 0; 125 126 switch(type) { 127 case XGE_HAL_CHANNEL_TYPE_FIFO: 128 xge_assert(post_qid + 1 >= XGE_HAL_MIN_FIFO_NUM && 129 post_qid + 1 <= XGE_HAL_MAX_FIFO_NUM); 130 size = sizeof(xge_hal_fifo_t); 131 break; 132 case XGE_HAL_CHANNEL_TYPE_RING: 133 xge_assert(post_qid + 1 >= XGE_HAL_MIN_RING_NUM && 134 post_qid + 1 <= XGE_HAL_MAX_RING_NUM); 135 size = sizeof(xge_hal_ring_t); 136 break; 137#ifdef XGEHAL_RNIC 138 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 139 size = sizeof(__hal_sq_t); 140 break; 141 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 142 size = sizeof(__hal_srq_t); 143 break; 144 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 145 size = sizeof(__hal_cqrq_t); 146 break; 147 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 148 size = sizeof(__hal_umq_t); 149 break; 150 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 151 size = sizeof(__hal_dmq_t); 152 break; 153#endif 154 default : 155 xge_assert(size); 156 break; 157 158 } 159 160 161 /* allocate FIFO channel */ 162 channel = (xge_hal_channel_t *) xge_os_malloc(hldev->pdev, size); 163 if (channel == NULL) { 164 return NULL; 165 } 166 xge_os_memzero(channel, size); 167 168 channel->pdev = hldev->pdev; 169 channel->regh0 = hldev->regh0; 170 channel->regh1 = hldev->regh1; 171 channel->type = type; 172 channel->devh = devh; 173#ifdef XGEHAL_RNIC 174 channel->vp_id = vp_id; 175#endif 176 channel->post_qid = post_qid; 177 channel->compl_qid = 0; 178 179 return channel; 180} 181 182void __hal_channel_free(xge_hal_channel_t *channel) 183{ 184 int size = 0; 185 186 xge_assert(channel->pdev); 187 188 switch(channel->type) { 189 case XGE_HAL_CHANNEL_TYPE_FIFO: 190 size = sizeof(xge_hal_fifo_t); 191 break; 192 case XGE_HAL_CHANNEL_TYPE_RING: 193 size = sizeof(xge_hal_ring_t); 194 break; 195#ifdef XGEHAL_RNIC 196 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 197 size = sizeof(__hal_sq_t); 198 break; 199 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 200 size = sizeof(__hal_srq_t); 201 break; 202 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 203 size = sizeof(__hal_cqrq_t); 204 break; 205 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 206 size = sizeof(__hal_umq_t); 207 break; 208 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 209 size = sizeof(__hal_dmq_t); 210 break; 211#else 212 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 213 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 214 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 215 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 216 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 217 xge_assert(size); 218 break; 219#endif 220 default: 221 break; 222 } 223 224 xge_os_free(channel->pdev, channel, size); 225} 226 227xge_hal_status_e 228__hal_channel_initialize (xge_hal_channel_h channelh, 229 xge_hal_channel_attr_t *attr, void **reserve_arr, 230 int reserve_initial, int reserve_max, int reserve_threshold) 231{ 232 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh; 233 xge_hal_device_t *hldev; 234 235 hldev = (xge_hal_device_t *)channel->devh; 236 237 channel->dtr_term = attr->dtr_term; 238 channel->dtr_init = attr->dtr_init; 239 channel->callback = attr->callback; 240 channel->userdata = attr->userdata; 241 channel->flags = attr->flags; 242 channel->per_dtr_space = attr->per_dtr_space; 243 244 channel->reserve_arr = reserve_arr; 245 channel->reserve_initial = reserve_initial; 246 channel->reserve_max = reserve_max; 247 channel->reserve_length = channel->reserve_initial; 248 channel->reserve_threshold = reserve_threshold; 249 channel->reserve_top = 0; 250 channel->saved_arr = (void **) xge_os_malloc(hldev->pdev, 251 sizeof(void*)*channel->reserve_max); 252 if (channel->saved_arr == NULL) { 253 return XGE_HAL_ERR_OUT_OF_MEMORY; 254 } 255 xge_os_memzero(channel->saved_arr, sizeof(void*)*channel->reserve_max); 256 channel->free_arr = channel->saved_arr; 257 channel->free_length = channel->reserve_initial; 258 channel->work_arr = (void **) xge_os_malloc(hldev->pdev, 259 sizeof(void*)*channel->reserve_max); 260 if (channel->work_arr == NULL) { 261 return XGE_HAL_ERR_OUT_OF_MEMORY; 262 } 263 xge_os_memzero(channel->work_arr, 264 sizeof(void*)*channel->reserve_max); 265 channel->post_index = 0; 266 channel->compl_index = 0; 267 channel->length = channel->reserve_initial; 268 269 channel->orig_arr = (void **) xge_os_malloc(hldev->pdev, 270 sizeof(void*)*channel->reserve_max); 271 if (channel->orig_arr == NULL) 272 return XGE_HAL_ERR_OUT_OF_MEMORY; 273 274 xge_os_memzero(channel->orig_arr, sizeof(void*)*channel->reserve_max); 275 276#if defined(XGE_HAL_RX_MULTI_FREE_IRQ) || defined(XGE_HAL_TX_MULTI_FREE_IRQ) 277 xge_os_spin_lock_init_irq(&channel->free_lock, hldev->irqh); 278#elif defined(XGE_HAL_RX_MULTI_FREE) || defined(XGE_HAL_TX_MULTI_FREE) 279 xge_os_spin_lock_init(&channel->free_lock, hldev->pdev); 280#endif 281 282 return XGE_HAL_OK; 283} 284 285void __hal_channel_terminate(xge_hal_channel_h channelh) 286{ 287 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh; 288 xge_hal_device_t *hldev; 289 290 hldev = (xge_hal_device_t *)channel->devh; 291 292 xge_assert(channel->pdev); 293 /* undo changes made at channel_initialize() */ 294 if (channel->work_arr) { 295 xge_os_free(channel->pdev, channel->work_arr, 296 sizeof(void*)*channel->reserve_max); 297 channel->work_arr = NULL; 298 } 299 300 if (channel->saved_arr) { 301 xge_os_free(channel->pdev, channel->saved_arr, 302 sizeof(void*)*channel->reserve_max); 303 channel->saved_arr = NULL; 304 } 305 306 if (channel->orig_arr) { 307 xge_os_free(channel->pdev, channel->orig_arr, 308 sizeof(void*)*channel->reserve_max); 309 channel->orig_arr = NULL; 310 } 311 312#if defined(XGE_HAL_RX_MULTI_FREE_IRQ) || defined(XGE_HAL_TX_MULTI_FREE_IRQ) 313 xge_os_spin_lock_destroy_irq(&channel->free_lock, hldev->irqh); 314#elif defined(XGE_HAL_RX_MULTI_FREE) || defined(XGE_HAL_TX_MULTI_FREE) 315 xge_os_spin_lock_destroy(&channel->free_lock, hldev->pdev); 316#endif 317} 318 319/** 320 * xge_hal_channel_open - Open communication channel. 321 * @devh: HAL device, pointer to xge_hal_device_t structure. 322 * @attr: Contains attributes required to open 323 * the channel. 324 * @channelh: The channel handle. On success (XGE_HAL_OK) HAL fills 325 * this "out" parameter with a valid channel handle. 326 * @reopen: See xge_hal_channel_reopen_e{}. 327 * 328 * Open communication channel with the device. 329 * 330 * HAL uses (persistent) channel configuration to allocate both channel 331 * and Xframe Tx and Rx descriptors. 332 * Notes: 333 * 1) The channel config data is fed into HAL prior to 334 * xge_hal_channel_open(). 335 * 336 * 2) The corresponding hardware queues must be already configured and 337 * enabled. 338 * 339 * 3) Either down or up queue may be omitted, in which case the channel 340 * is treated as _unidirectional_. 341 * 342 * 4) Post and completion queue may be the same, in which case the channel 343 * is said to have "in-band completions". 344 * 345 * Note that free_channels list is not protected. i.e. caller must provide 346 * safe context. 347 * 348 * Returns: XGE_HAL_OK - success. 349 * XGE_HAL_ERR_CHANNEL_NOT_FOUND - Unable to locate the channel. 350 * XGE_HAL_ERR_OUT_OF_MEMORY - Memory allocation failed. 351 * 352 * See also: xge_hal_channel_attr_t{}. 353 * Usage: See ex_open{}. 354 */ 355xge_hal_status_e 356xge_hal_channel_open(xge_hal_device_h devh, 357 xge_hal_channel_attr_t *attr, 358 xge_hal_channel_h *channelh, 359 xge_hal_channel_reopen_e reopen) 360{ 361 xge_list_t *item; 362 int i; 363 xge_hal_status_e status = XGE_HAL_OK; 364 xge_hal_channel_t *channel = NULL; 365 xge_hal_device_t *device = (xge_hal_device_t *)devh; 366 367 xge_assert(device); 368 xge_assert(attr); 369 370 *channelh = NULL; 371 372#ifdef XGEHAL_RNIC 373 if((attr->type == XGE_HAL_CHANNEL_TYPE_FIFO) || 374 (attr->type == XGE_HAL_CHANNEL_TYPE_RING)) { 375#endif 376 /* find channel */ 377 xge_list_for_each(item, &device->free_channels) { 378 xge_hal_channel_t *tmp; 379 380 tmp = xge_container_of(item, xge_hal_channel_t, item); 381 if (tmp->type == attr->type && 382 tmp->post_qid == attr->post_qid && 383 tmp->compl_qid == attr->compl_qid) { 384 channel = tmp; 385 break; 386 } 387 } 388 389 if (channel == NULL) { 390 return XGE_HAL_ERR_CHANNEL_NOT_FOUND; 391 } 392 393#ifdef XGEHAL_RNIC 394 } 395 else { 396 channel = __hal_channel_allocate(devh, attr->post_qid, 397#ifdef XGEHAL_RNIC 398 attr->vp_id, 399#endif 400 attr->type); 401 if (channel == NULL) { 402 xge_debug_device(XGE_ERR, 403 "__hal_channel_allocate failed"); 404 return XGE_HAL_ERR_OUT_OF_MEMORY; 405 } 406 } 407#endif 408 409#ifndef XGEHAL_RNIC 410 xge_assert((channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) || 411 (channel->type == XGE_HAL_CHANNEL_TYPE_RING)); 412#endif 413 414#ifdef XGEHAL_RNIC 415 if((reopen == XGE_HAL_CHANNEL_OC_NORMAL) || 416 ((channel->type != XGE_HAL_CHANNEL_TYPE_FIFO) && 417 (channel->type != XGE_HAL_CHANNEL_TYPE_RING))) { 418#else 419 if (reopen == XGE_HAL_CHANNEL_OC_NORMAL) { 420#endif 421 /* allocate memory, initialize pointers, etc */ 422 switch(channel->type) { 423 case XGE_HAL_CHANNEL_TYPE_FIFO: 424 status = __hal_fifo_open(channel, attr); 425 break; 426 case XGE_HAL_CHANNEL_TYPE_RING: 427 status = __hal_ring_open(channel, attr); 428 break; 429#ifdef XGEHAL_RNIC 430 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 431 status = __hal_sq_open(channel, attr); 432 break; 433 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 434 status = __hal_srq_open(channel, attr); 435 break; 436 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 437 status = __hal_cqrq_open(channel, attr); 438 break; 439 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 440 status = __hal_umq_open(channel, attr); 441 break; 442 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 443 status = __hal_dmq_open(channel, attr); 444 break; 445#else 446 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 447 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 448 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 449 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 450 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 451 status = XGE_HAL_FAIL; 452 break; 453#endif 454 default: 455 break; 456 } 457 458 if (status == XGE_HAL_OK) { 459 for (i = 0; i < channel->reserve_initial; i++) { 460 channel->orig_arr[i] = 461 channel->reserve_arr[i]; 462 } 463 } 464 else 465 return status; 466 } else { 467 xge_assert(reopen == XGE_HAL_CHANNEL_RESET_ONLY); 468 469 for (i = 0; i < channel->reserve_initial; i++) { 470 channel->reserve_arr[i] = channel->orig_arr[i]; 471 channel->free_arr[i] = NULL; 472 } 473 channel->free_length = channel->reserve_initial; 474 channel->reserve_length = channel->reserve_initial; 475 channel->reserve_top = 0; 476 channel->post_index = 0; 477 channel->compl_index = 0; 478 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) { 479 status = __hal_ring_initial_replenish(channel, 480 reopen); 481 if (status != XGE_HAL_OK) 482 return status; 483 } 484 } 485 486 /* move channel to the open state list */ 487 488 switch(channel->type) { 489 case XGE_HAL_CHANNEL_TYPE_FIFO: 490 xge_list_remove(&channel->item); 491 xge_list_insert(&channel->item, &device->fifo_channels); 492 break; 493 case XGE_HAL_CHANNEL_TYPE_RING: 494 xge_list_remove(&channel->item); 495 xge_list_insert(&channel->item, &device->ring_channels); 496 break; 497#ifdef XGEHAL_RNIC 498 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 499 xge_list_insert(&channel->item, 500 &device->virtual_paths[attr->vp_id].sq_channels); 501 device->virtual_paths[attr->vp_id].stats.no_sqs++; 502 break; 503 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 504 xge_list_insert(&channel->item, 505 &device->virtual_paths[attr->vp_id].srq_channels); 506 device->virtual_paths[attr->vp_id].stats.no_srqs++; 507 break; 508 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 509 xge_list_insert(&channel->item, 510 &device->virtual_paths[attr->vp_id].cqrq_channels); 511 device->virtual_paths[attr->vp_id].stats.no_cqrqs++; 512 break; 513 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 514 xge_list_init(&channel->item); 515 device->virtual_paths[attr->vp_id].umq_channelh = channel; 516 break; 517 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 518 xge_list_init(&channel->item); 519 device->virtual_paths[attr->vp_id].dmq_channelh = channel; 520 break; 521#else 522 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 523 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 524 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 525 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 526 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 527 xge_assert(channel->type == XGE_HAL_CHANNEL_TYPE_FIFO || 528 channel->type == XGE_HAL_CHANNEL_TYPE_RING); 529 break; 530#endif 531 default: 532 break; 533 } 534 channel->is_open = 1; 535 /* 536 * The magic check the argument validity, has to be 537 * removed before 03/01/2005. 538 */ 539 channel->magic = XGE_HAL_MAGIC; 540 541 *channelh = channel; 542 543 return XGE_HAL_OK; 544} 545 546/** 547 * xge_hal_channel_abort - Abort the channel. 548 * @channelh: Channel handle. 549 * @reopen: See xge_hal_channel_reopen_e{}. 550 * 551 * Terminate (via xge_hal_channel_dtr_term_f{}) all channel descriptors. 552 * Currently used internally only by HAL, as part of its 553 * xge_hal_channel_close() and xge_hal_channel_open() in case 554 * of fatal error. 555 * 556 * See also: xge_hal_channel_dtr_term_f{}. 557 */ 558void xge_hal_channel_abort(xge_hal_channel_h channelh, 559 xge_hal_channel_reopen_e reopen) 560{ 561 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh; 562 xge_hal_dtr_h dtr; 563#ifdef XGE_OS_MEMORY_CHECK 564 int check_cnt = 0; 565#endif 566 int free_length_sav; 567 int reserve_top_sav; 568 569 if (channel->dtr_term == NULL) { 570 return; 571 } 572 573 free_length_sav = channel->free_length; 574 while (__hal_channel_dtr_next_freelist(channelh, &dtr) == XGE_HAL_OK) { 575#ifdef XGE_OS_MEMORY_CHECK 576#ifdef XGE_DEBUG_ASSERT 577 if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) { 578 xge_assert(!__hal_fifo_txdl_priv(dtr)->allocated); 579 } else { 580 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) { 581 xge_assert(!__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtr)->allocated); 582 } 583 } 584#endif 585 check_cnt++; 586#endif 587 channel->dtr_term(channel, dtr, XGE_HAL_DTR_STATE_FREED, 588 channel->userdata, reopen); 589 } 590 channel->free_length = free_length_sav; 591 592 while (__hal_channel_dtr_next_not_completed(channelh, &dtr) == 593 XGE_HAL_OK) { 594#ifdef XGE_OS_MEMORY_CHECK 595#ifdef XGE_DEBUG_ASSERT 596 if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) { 597 xge_assert(__hal_fifo_txdl_priv(dtr)->allocated); 598 } else { 599 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) { 600 xge_assert(__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtr) 601 ->allocated); 602 } 603 } 604#endif 605 check_cnt++; 606#endif 607 channel->dtr_term(channel, dtr, XGE_HAL_DTR_STATE_POSTED, 608 channel->userdata, reopen); 609 610 } 611 612 reserve_top_sav = channel->reserve_top; 613 while (__hal_channel_dtr_next_reservelist(channelh, &dtr) == 614 XGE_HAL_OK) { 615#ifdef XGE_OS_MEMORY_CHECK 616#ifdef XGE_DEBUG_ASSERT 617 if (channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) { 618 xge_assert(!__hal_fifo_txdl_priv(dtr)->allocated); 619 } else { 620 if (channel->type == XGE_HAL_CHANNEL_TYPE_RING) { 621 xge_assert(!__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtr)->allocated); 622 } 623 } 624#endif 625 check_cnt++; 626#endif 627 channel->dtr_term(channel, dtr, XGE_HAL_DTR_STATE_AVAIL, 628 channel->userdata, reopen); 629 } 630 channel->reserve_top = reserve_top_sav; 631 632 xge_assert(channel->reserve_length == 633 (channel->free_length + channel->reserve_top)); 634 635#ifdef XGE_OS_MEMORY_CHECK 636 xge_assert(check_cnt == channel->reserve_initial); 637#endif 638 639} 640 641/** 642 * xge_hal_channel_close - Close communication channel. 643 * @channelh: The channel handle. 644 * @reopen: See xge_hal_channel_reopen_e{}. 645 * 646 * Will close previously opened channel and deallocate associated resources. 647 * Channel must be opened otherwise assert will be generated. 648 * Note that free_channels list is not protected. i.e. caller must provide 649 * safe context. 650 */ 651void xge_hal_channel_close(xge_hal_channel_h channelh, 652 xge_hal_channel_reopen_e reopen) 653{ 654 xge_hal_channel_t *channel = (xge_hal_channel_t *)channelh; 655 xge_hal_device_t *hldev; 656 xge_list_t *item; 657#ifdef XGEHAL_RNIC 658 u32 vp_id; 659#endif 660 xge_assert(channel); 661 xge_assert(channel->type < XGE_HAL_CHANNEL_TYPE_MAX); 662 663 hldev = (xge_hal_device_t *)channel->devh; 664 channel->is_open = 0; 665 channel->magic = XGE_HAL_DEAD; 666 667#ifdef XGEHAL_RNIC 668 vp_id = channel->vp_id; 669 670 if((channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) || 671 (channel->type == XGE_HAL_CHANNEL_TYPE_RING)) { 672#endif 673 /* sanity check: make sure channel is not in free list */ 674 xge_list_for_each(item, &hldev->free_channels) { 675 xge_hal_channel_t *tmp; 676 677 tmp = xge_container_of(item, xge_hal_channel_t, item); 678 xge_assert(!tmp->is_open); 679 if (channel == tmp) { 680 return; 681 } 682 } 683#ifdef XGEHAL_RNIC 684 } 685#endif 686 687 xge_hal_channel_abort(channel, reopen); 688 689#ifndef XGEHAL_RNIC 690 xge_assert((channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) || 691 (channel->type == XGE_HAL_CHANNEL_TYPE_RING)); 692#endif 693 694 if (reopen == XGE_HAL_CHANNEL_OC_NORMAL) { 695 /* de-allocate */ 696 switch(channel->type) { 697 case XGE_HAL_CHANNEL_TYPE_FIFO: 698 __hal_fifo_close(channelh); 699 break; 700 case XGE_HAL_CHANNEL_TYPE_RING: 701 __hal_ring_close(channelh); 702 break; 703#ifdef XGEHAL_RNIC 704 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 705 __hal_sq_close(channelh); 706 hldev->virtual_paths[vp_id].stats.no_sqs--; 707 break; 708 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 709 __hal_srq_close(channelh); 710 hldev->virtual_paths[vp_id].stats.no_srqs--; 711 break; 712 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 713 __hal_cqrq_close(channelh); 714 hldev->virtual_paths[vp_id].stats.no_cqrqs--; 715 break; 716 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 717 __hal_umq_close(channelh); 718 break; 719 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 720 __hal_dmq_close(channelh); 721 break; 722#else 723 case XGE_HAL_CHANNEL_TYPE_SEND_QUEUE: 724 case XGE_HAL_CHANNEL_TYPE_RECEIVE_QUEUE: 725 case XGE_HAL_CHANNEL_TYPE_COMPLETION_QUEUE: 726 case XGE_HAL_CHANNEL_TYPE_UP_MESSAGE_QUEUE: 727 case XGE_HAL_CHANNEL_TYPE_DOWN_MESSAGE_QUEUE: 728 xge_assert(channel->type == XGE_HAL_CHANNEL_TYPE_FIFO || 729 channel->type == XGE_HAL_CHANNEL_TYPE_RING); 730 break; 731#endif 732 default: 733 break; 734 } 735 } 736 else 737 xge_assert(reopen == XGE_HAL_CHANNEL_RESET_ONLY); 738 739 /* move channel back to free state list */ 740 xge_list_remove(&channel->item); 741#ifdef XGEHAL_RNIC 742 if((channel->type == XGE_HAL_CHANNEL_TYPE_FIFO) || 743 (channel->type == XGE_HAL_CHANNEL_TYPE_RING)) { 744#endif 745 xge_list_insert(&channel->item, &hldev->free_channels); 746 747 if (xge_list_is_empty(&hldev->fifo_channels) && 748 xge_list_is_empty(&hldev->ring_channels)) { 749 /* clear msix_idx in case of following HW reset */ 750 hldev->reset_needed_after_close = 1; 751 } 752#ifdef XGEHAL_RNIC 753 } 754 else { 755 __hal_channel_free(channel); 756 } 757#endif 758 759} 760