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