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 22 /* Copyright © 2003-2011 Emulex. All rights reserved. */ 23 24 /* 25 * Source file containing Queue handling functions 26 * 27 */ 28 29 #include <oce_impl.h> 30 extern struct oce_dev *oce_dev_list[]; 31 32 int oce_destroy_q(struct oce_dev *oce, struct oce_mbx *mbx, size_t req_size, 33 enum qtype qtype); 34 /* MAil box Queue functions */ 35 struct oce_mq * 36 oce_mq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len); 37 38 /* event queue handling */ 39 struct oce_eq * 40 oce_eq_create(struct oce_dev *dev, uint32_t q_len, uint32_t item_size, 41 uint32_t eq_delay); 42 43 /* completion queue handling */ 44 struct oce_cq * 45 oce_cq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len, 46 uint32_t item_size, boolean_t sol_event, boolean_t is_eventable, 47 boolean_t nodelay, uint32_t ncoalesce); 48 49 50 /* Tx WQ functions */ 51 static struct oce_wq *oce_wq_init(struct oce_dev *dev, uint32_t q_len, 52 int wq_type); 53 static void oce_wq_fini(struct oce_dev *dev, struct oce_wq *wq); 54 static int oce_wq_create(struct oce_wq *wq, struct oce_eq *eq); 55 static void oce_wq_del(struct oce_dev *dev, struct oce_wq *wq); 56 /* Rx Queue functions */ 57 static struct oce_rq *oce_rq_init(struct oce_dev *dev, uint32_t q_len, 58 uint32_t frag_size, uint32_t mtu, 59 boolean_t rss); 60 static void oce_rq_fini(struct oce_dev *dev, struct oce_rq *rq); 61 static int oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq); 62 static void oce_rq_del(struct oce_dev *dev, struct oce_rq *rq); 63 64 /* 65 * function to create an event queue 66 * 67 * dev - software handle to the device 68 * eqcfg - pointer to a config structure containg the eq parameters 69 * 70 * return pointer to EQ; NULL on failure 71 */ 72 struct oce_eq * 73 oce_eq_create(struct oce_dev *dev, uint32_t q_len, uint32_t item_size, 74 uint32_t eq_delay) 75 { 76 struct oce_eq *eq; 77 struct oce_mbx mbx; 78 struct mbx_create_common_eq *fwcmd; 79 int ret = 0; 80 81 /* allocate an eq */ 82 eq = kmem_zalloc(sizeof (struct oce_eq), KM_NOSLEEP); 83 84 if (eq == NULL) { 85 return (NULL); 86 } 87 88 bzero(&mbx, sizeof (struct oce_mbx)); 89 /* allocate mbx */ 90 fwcmd = (struct mbx_create_common_eq *)&mbx.payload; 91 92 eq->ring = create_ring_buffer(dev, q_len, 93 item_size, DDI_DMA_CONSISTENT); 94 95 if (eq->ring == NULL) { 96 oce_log(dev, CE_WARN, MOD_CONFIG, 97 "EQ ring alloc failed:0x%p", (void *)eq->ring); 98 kmem_free(eq, sizeof (struct oce_eq)); 99 return (NULL); 100 } 101 102 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 103 MBX_SUBSYSTEM_COMMON, 104 OPCODE_CREATE_COMMON_EQ, MBX_TIMEOUT_SEC, 105 sizeof (struct mbx_create_common_eq)); 106 107 fwcmd->params.req.num_pages = eq->ring->dbuf->num_pages; 108 oce_page_list(eq->ring->dbuf, &fwcmd->params.req.pages[0], 109 eq->ring->dbuf->num_pages); 110 111 /* dw 0 */ 112 fwcmd->params.req.eq_ctx.size = (item_size == 4) ? 0 : 1; 113 fwcmd->params.req.eq_ctx.valid = 1; 114 /* dw 1 */ 115 fwcmd->params.req.eq_ctx.armed = 0; 116 fwcmd->params.req.eq_ctx.pd = 0; 117 fwcmd->params.req.eq_ctx.count = OCE_LOG2(q_len/256); 118 119 /* dw 2 */ 120 fwcmd->params.req.eq_ctx.function = dev->fn; 121 fwcmd->params.req.eq_ctx.nodelay = 0; 122 fwcmd->params.req.eq_ctx.phase = 0; 123 /* todo: calculate multiplier from max min and cur */ 124 fwcmd->params.req.eq_ctx.delay_mult = eq_delay; 125 126 /* fill rest of mbx */ 127 mbx.u0.s.embedded = 1; 128 mbx.payload_length = sizeof (struct mbx_create_common_eq); 129 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 130 131 /* now post the command */ 132 ret = oce_mbox_post(dev, &mbx, NULL); 133 134 if (ret != 0) { 135 oce_log(dev, CE_WARN, MOD_CONFIG, "EQ create failed: %d", ret); 136 destroy_ring_buffer(dev, eq->ring); 137 kmem_free(eq, sizeof (struct oce_eq)); 138 return (NULL); 139 } 140 141 /* interpret the response */ 142 eq->eq_id = LE_16(fwcmd->params.rsp.eq_id); 143 eq->eq_cfg.q_len = q_len; 144 eq->eq_cfg.item_size = item_size; 145 eq->eq_cfg.cur_eqd = (uint8_t)eq_delay; 146 eq->parent = (void *)dev; 147 atomic_inc_32(&dev->neqs); 148 oce_log(dev, CE_NOTE, MOD_CONFIG, 149 "EQ created, eq=0x%p eq_id=0x%x", (void *)eq, eq->eq_id); 150 /* Save the eq pointer */ 151 return (eq); 152 } /* oce_eq_create */ 153 154 /* 155 * function to delete an event queue 156 * 157 * dev - software handle to the device 158 * eq - handle to the eq to be deleted 159 * 160 * return 0=>success, failure otherwise 161 */ 162 void 163 oce_eq_del(struct oce_dev *dev, struct oce_eq *eq) 164 { 165 struct oce_mbx mbx; 166 struct mbx_destroy_common_eq *fwcmd; 167 168 /* drain the residual events */ 169 oce_drain_eq(eq); 170 171 /* destroy the ring */ 172 destroy_ring_buffer(dev, eq->ring); 173 eq->ring = NULL; 174 175 /* send a command to delete the EQ */ 176 fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload; 177 fwcmd->params.req.id = eq->eq_id; 178 (void) oce_destroy_q(dev, &mbx, 179 sizeof (struct mbx_destroy_common_eq), 180 QTYPE_EQ); 181 kmem_free(eq, sizeof (struct oce_eq)); 182 atomic_dec_32(&dev->neqs); 183 } 184 185 /* 186 * function to create a completion queue 187 * 188 * dev - software handle to the device 189 * eq - optional eq to be associated with to the cq 190 * cqcfg - configuration for this queue 191 * 192 * return pointer to the cq created. NULL on failure 193 */ 194 struct oce_cq * 195 oce_cq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len, 196 uint32_t item_size, boolean_t sol_event, boolean_t is_eventable, 197 boolean_t nodelay, uint32_t ncoalesce) 198 { 199 struct oce_cq *cq = NULL; 200 struct oce_mbx mbx; 201 struct mbx_create_common_cq *fwcmd; 202 int ret = 0; 203 204 /* create cq */ 205 cq = kmem_zalloc(sizeof (struct oce_cq), KM_NOSLEEP); 206 if (cq == NULL) { 207 oce_log(dev, CE_NOTE, MOD_CONFIG, "%s", 208 "CQ allocation failed"); 209 return (NULL); 210 } 211 212 /* create the ring buffer for this queue */ 213 cq->ring = create_ring_buffer(dev, q_len, 214 item_size, DDI_DMA_CONSISTENT); 215 if (cq->ring == NULL) { 216 oce_log(dev, CE_WARN, MOD_CONFIG, 217 "CQ ring alloc failed:0x%p", 218 (void *)cq->ring); 219 kmem_free(cq, sizeof (struct oce_cq)); 220 return (NULL); 221 } 222 /* initialize mailbox */ 223 bzero(&mbx, sizeof (struct oce_mbx)); 224 fwcmd = (struct mbx_create_common_cq *)&mbx.payload; 225 226 /* fill the command header */ 227 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 228 MBX_SUBSYSTEM_COMMON, 229 OPCODE_CREATE_COMMON_CQ, MBX_TIMEOUT_SEC, 230 sizeof (struct mbx_create_common_cq)); 231 232 /* fill command context */ 233 /* dw0 */ 234 fwcmd->params.req.cq_ctx.eventable = is_eventable; 235 fwcmd->params.req.cq_ctx.sol_event = sol_event; 236 fwcmd->params.req.cq_ctx.valid = 1; 237 fwcmd->params.req.cq_ctx.count = OCE_LOG2(q_len/256); 238 fwcmd->params.req.cq_ctx.nodelay = nodelay; 239 fwcmd->params.req.cq_ctx.coalesce_wm = ncoalesce; 240 241 /* dw1 */ 242 fwcmd->params.req.cq_ctx.armed = B_FALSE; 243 fwcmd->params.req.cq_ctx.eq_id = eq->eq_id; 244 fwcmd->params.req.cq_ctx.pd = 0; 245 /* dw2 */ 246 fwcmd->params.req.cq_ctx.function = dev->fn; 247 248 /* fill the rest of the command */ 249 fwcmd->params.req.num_pages = cq->ring->dbuf->num_pages; 250 oce_page_list(cq->ring->dbuf, &fwcmd->params.req.pages[0], 251 cq->ring->dbuf->num_pages); 252 253 /* fill rest of mbx */ 254 mbx.u0.s.embedded = 1; 255 mbx.payload_length = sizeof (struct mbx_create_common_cq); 256 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 257 258 /* now send the mail box */ 259 ret = oce_mbox_post(dev, &mbx, NULL); 260 261 if (ret != 0) { 262 oce_log(dev, CE_WARN, MOD_CONFIG, 263 "CQ create failed: 0x%x", ret); 264 destroy_ring_buffer(dev, cq->ring); 265 kmem_free(cq, sizeof (struct oce_cq)); 266 return (NULL); 267 } 268 269 cq->parent = dev; 270 cq->eq = eq; /* eq array index */ 271 cq->cq_cfg.q_len = q_len; 272 cq->cq_cfg.item_size = item_size; 273 cq->cq_cfg.sol_eventable = (uint8_t)sol_event; 274 cq->cq_cfg.nodelay = (uint8_t)nodelay; 275 /* interpret the response */ 276 cq->cq_id = LE_16(fwcmd->params.rsp.cq_id); 277 dev->cq[cq->cq_id % OCE_MAX_CQ] = cq; 278 atomic_inc_32(&eq->ref_count); 279 return (cq); 280 } /* oce_cq_create */ 281 282 /* 283 * function to delete a completion queue 284 * 285 * dev - software handle to the device 286 * cq - handle to the CQ to delete 287 * 288 * return none 289 */ 290 static void 291 oce_cq_del(struct oce_dev *dev, struct oce_cq *cq) 292 { 293 struct oce_mbx mbx; 294 struct mbx_destroy_common_cq *fwcmd; 295 296 /* destroy the ring */ 297 destroy_ring_buffer(dev, cq->ring); 298 cq->ring = NULL; 299 300 bzero(&mbx, sizeof (struct oce_mbx)); 301 /* send a command to delete the CQ */ 302 fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload; 303 fwcmd->params.req.id = cq->cq_id; 304 (void) oce_destroy_q(dev, &mbx, 305 sizeof (struct mbx_destroy_common_cq), 306 QTYPE_CQ); 307 308 /* Reset the handler */ 309 cq->cq_handler = NULL; 310 dev->cq[cq->cq_id % OCE_MAX_CQ] = NULL; 311 atomic_dec_32(&cq->eq->ref_count); 312 mutex_destroy(&cq->lock); 313 314 /* release the eq */ 315 kmem_free(cq, sizeof (struct oce_cq)); 316 } /* oce_cq_del */ 317 318 /* 319 * function to create an MQ 320 * 321 * dev - software handle to the device 322 * eq - the EQ to associate with the MQ for event notification 323 * q_len - the number of entries to create in the MQ 324 * 325 * return pointer to the created MQ, failure otherwise 326 */ 327 struct oce_mq * 328 oce_mq_create(struct oce_dev *dev, struct oce_eq *eq, uint32_t q_len) 329 { 330 struct oce_mbx mbx; 331 struct mbx_create_common_mq *fwcmd; 332 struct oce_mq *mq = NULL; 333 int ret = 0; 334 struct oce_cq *cq; 335 336 /* Create the Completion Q */ 337 cq = oce_cq_create(dev, eq, CQ_LEN_256, 338 sizeof (struct oce_mq_cqe), 339 B_FALSE, B_TRUE, B_TRUE, 0); 340 if (cq == NULL) { 341 return (NULL); 342 } 343 344 345 /* allocate the mq */ 346 mq = kmem_zalloc(sizeof (struct oce_mq), KM_NOSLEEP); 347 348 if (mq == NULL) { 349 goto mq_alloc_fail; 350 } 351 352 bzero(&mbx, sizeof (struct oce_mbx)); 353 /* allocate mbx */ 354 fwcmd = (struct mbx_create_common_mq *)&mbx.payload; 355 356 /* create the ring buffer for this queue */ 357 mq->ring = create_ring_buffer(dev, q_len, 358 sizeof (struct oce_mbx), DDI_DMA_CONSISTENT | DDI_DMA_RDWR); 359 if (mq->ring == NULL) { 360 oce_log(dev, CE_WARN, MOD_CONFIG, 361 "MQ ring alloc failed:0x%p", 362 (void *)mq->ring); 363 goto mq_ring_alloc; 364 } 365 366 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 367 MBX_SUBSYSTEM_COMMON, 368 OPCODE_CREATE_COMMON_MQ, MBX_TIMEOUT_SEC, 369 sizeof (struct mbx_create_common_mq)); 370 371 fwcmd->params.req.num_pages = mq->ring->dbuf->num_pages; 372 oce_page_list(mq->ring->dbuf, fwcmd->params.req.pages, 373 mq->ring->dbuf->num_pages); 374 fwcmd->params.req.context.u0.s.cq_id = cq->cq_id; 375 fwcmd->params.req.context.u0.s.ring_size = 376 OCE_LOG2(q_len) + 1; 377 fwcmd->params.req.context.u0.s.valid = 1; 378 fwcmd->params.req.context.u0.s.fid = dev->fn; 379 380 /* fill rest of mbx */ 381 mbx.u0.s.embedded = 1; 382 mbx.payload_length = sizeof (struct mbx_create_common_mq); 383 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 384 385 /* now send the mail box */ 386 ret = oce_mbox_post(dev, &mbx, NULL); 387 if (ret != DDI_SUCCESS) { 388 oce_log(dev, CE_WARN, MOD_CONFIG, 389 "MQ create failed: 0x%x", ret); 390 goto mq_fail; 391 } 392 393 /* interpret the response */ 394 mq->mq_id = LE_16(fwcmd->params.rsp.mq_id); 395 mq->cq = cq; 396 mq->cfg.q_len = (uint8_t)q_len; 397 mq->cfg.eqd = 0; 398 399 /* fill rest of the mq */ 400 mq->parent = dev; 401 402 /* set the MQCQ handlers */ 403 cq->cq_handler = oce_drain_mq_cq; 404 cq->cb_arg = (void *)mq; 405 mutex_init(&mq->lock, NULL, MUTEX_DRIVER, 406 DDI_INTR_PRI(dev->intr_pri)); 407 return (mq); 408 409 mq_fail: 410 destroy_ring_buffer(dev, mq->ring); 411 mq_ring_alloc: 412 kmem_free(mq, sizeof (struct oce_mq)); 413 mq_alloc_fail: 414 oce_cq_del(dev, cq); 415 return (NULL); 416 } /* oce_mq_create */ 417 418 /* 419 * function to delete an MQ 420 * 421 * dev - software handle to the device 422 * mq - pointer to the MQ to delete 423 * 424 * return none 425 */ 426 static void 427 oce_mq_del(struct oce_dev *dev, struct oce_mq *mq) 428 { 429 struct oce_mbx mbx; 430 struct mbx_destroy_common_mq *fwcmd; 431 432 /* destroy the ring */ 433 destroy_ring_buffer(dev, mq->ring); 434 mq->ring = NULL; 435 bzero(&mbx, sizeof (struct oce_mbx)); 436 fwcmd = (struct mbx_destroy_common_mq *)&mbx.payload; 437 fwcmd->params.req.id = mq->mq_id; 438 (void) oce_destroy_q(dev, &mbx, 439 sizeof (struct mbx_destroy_common_mq), 440 QTYPE_MQ); 441 oce_cq_del(dev, mq->cq); 442 mq->cq = NULL; 443 mutex_destroy(&mq->lock); 444 kmem_free(mq, sizeof (struct oce_mq)); 445 } /* oce_mq_del */ 446 447 /* 448 * function to create a WQ for NIC Tx 449 * 450 * dev - software handle to the device 451 * wqcfg - configuration structure providing WQ config parameters 452 * 453 * return pointer to the WQ created. NULL on failure 454 */ 455 static struct oce_wq * 456 oce_wq_init(struct oce_dev *dev, uint32_t q_len, int wq_type) 457 { 458 struct oce_wq *wq; 459 char str[MAX_POOL_NAME]; 460 int ret; 461 static int wq_id = 0; 462 463 ASSERT(dev != NULL); 464 /* q_len must be min 256 and max 2k */ 465 if (q_len < 256 || q_len > 2048) { 466 oce_log(dev, CE_WARN, MOD_CONFIG, 467 "Invalid q length. Must be " 468 "[256, 2000]: 0x%x", q_len); 469 return (NULL); 470 } 471 472 /* allocate wq */ 473 wq = kmem_zalloc(sizeof (struct oce_wq), KM_NOSLEEP); 474 if (wq == NULL) { 475 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 476 "WQ allocation failed"); 477 return (NULL); 478 } 479 480 /* Set the wq config */ 481 wq->cfg.q_len = q_len; 482 wq->cfg.wq_type = (uint8_t)wq_type; 483 wq->cfg.eqd = OCE_DEFAULT_WQ_EQD; 484 wq->cfg.nbufs = 2 * wq->cfg.q_len; 485 wq->cfg.nhdl = 2 * wq->cfg.q_len; 486 wq->cfg.buf_size = dev->tx_bcopy_limit; 487 488 /* assign parent */ 489 wq->parent = (void *)dev; 490 491 /* Create the WQ Buffer pool */ 492 ret = oce_wqb_cache_create(wq, wq->cfg.buf_size); 493 if (ret != DDI_SUCCESS) { 494 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 495 "WQ Buffer Pool create failed "); 496 goto wqb_fail; 497 } 498 499 /* Create a pool of memory handles */ 500 ret = oce_wqm_cache_create(wq); 501 if (ret != DDI_SUCCESS) { 502 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 503 "WQ MAP Handles Pool create failed "); 504 goto wqm_fail; 505 } 506 507 (void) snprintf(str, MAX_POOL_NAME, "%s%d%s%d", "oce_wqed_", 508 dev->dev_id, "_", wq_id++); 509 wq->wqed_cache = kmem_cache_create(str, sizeof (oce_wqe_desc_t), 510 0, NULL, NULL, NULL, NULL, NULL, 0); 511 if (wq->wqed_cache == NULL) { 512 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 513 "WQ Packet Desc Pool create failed "); 514 goto wqed_fail; 515 } 516 517 /* create the ring buffer */ 518 wq->ring = create_ring_buffer(dev, q_len, 519 NIC_WQE_SIZE, DDI_DMA_CONSISTENT | DDI_DMA_RDWR); 520 if (wq->ring == NULL) { 521 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 522 "Failed to create WQ ring "); 523 goto wq_ringfail; 524 } 525 526 /* Initialize WQ lock */ 527 mutex_init(&wq->tx_lock, NULL, MUTEX_DRIVER, 528 DDI_INTR_PRI(dev->intr_pri)); 529 /* Initialize WQ lock */ 530 mutex_init(&wq->txc_lock, NULL, MUTEX_DRIVER, 531 DDI_INTR_PRI(dev->intr_pri)); 532 atomic_inc_32(&dev->nwqs); 533 534 OCE_LIST_CREATE(&wq->wqe_desc_list, DDI_INTR_PRI(dev->intr_pri)); 535 return (wq); 536 537 wqcq_fail: 538 destroy_ring_buffer(dev, wq->ring); 539 wq_ringfail: 540 kmem_cache_destroy(wq->wqed_cache); 541 wqed_fail: 542 oce_wqm_cache_destroy(wq); 543 wqm_fail: 544 oce_wqb_cache_destroy(wq); 545 wqb_fail: 546 kmem_free(wq, sizeof (struct oce_wq)); 547 return (NULL); 548 } /* oce_wq_create */ 549 550 /* 551 * function to delete a WQ 552 * 553 * dev - software handle to the device 554 * wq - WQ to delete 555 * 556 * return 0 => success, failure otherwise 557 */ 558 static void 559 oce_wq_fini(struct oce_dev *dev, struct oce_wq *wq) 560 { 561 /* destroy cq */ 562 oce_wqb_cache_destroy(wq); 563 oce_wqm_cache_destroy(wq); 564 kmem_cache_destroy(wq->wqed_cache); 565 566 /* Free the packet descriptor list */ 567 OCE_LIST_DESTROY(&wq->wqe_desc_list); 568 destroy_ring_buffer(dev, wq->ring); 569 wq->ring = NULL; 570 /* Destroy the Mutex */ 571 mutex_destroy(&wq->tx_lock); 572 mutex_destroy(&wq->txc_lock); 573 kmem_free(wq, sizeof (struct oce_wq)); 574 atomic_dec_32(&dev->nwqs); 575 } /* oce_wq_del */ 576 577 578 static int 579 oce_wq_create(struct oce_wq *wq, struct oce_eq *eq) 580 { 581 582 struct oce_mbx mbx; 583 struct mbx_create_nic_wq *fwcmd; 584 struct oce_dev *dev = wq->parent; 585 struct oce_cq *cq; 586 int ret; 587 588 /* create the CQ */ 589 cq = oce_cq_create(dev, eq, CQ_LEN_1024, 590 sizeof (struct oce_nic_tx_cqe), 591 B_FALSE, B_TRUE, B_FALSE, 3); 592 if (cq == NULL) { 593 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 594 "WCCQ create failed "); 595 return (DDI_FAILURE); 596 } 597 /* now fill the command */ 598 bzero(&mbx, sizeof (struct oce_mbx)); 599 fwcmd = (struct mbx_create_nic_wq *)&mbx.payload; 600 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 601 MBX_SUBSYSTEM_NIC, 602 OPCODE_CREATE_NIC_WQ, MBX_TIMEOUT_SEC, 603 sizeof (struct mbx_create_nic_wq)); 604 605 fwcmd->params.req.nic_wq_type = (uint8_t)wq->cfg.wq_type; 606 fwcmd->params.req.num_pages = wq->ring->dbuf->num_pages; 607 oce_log(dev, CE_NOTE, MOD_CONFIG, "NUM_PAGES = 0x%d size = %lu", 608 (uint32_t)wq->ring->dbuf->num_pages, 609 wq->ring->dbuf->size); 610 611 /* workaround: fill 0x01 for ulp_mask in rsvd0 */ 612 fwcmd->params.req.rsvd0 = 0x01; 613 fwcmd->params.req.wq_size = OCE_LOG2(wq->cfg.q_len) + 1; 614 fwcmd->params.req.valid = 1; 615 fwcmd->params.req.pd_id = 0; 616 fwcmd->params.req.pci_function_id = dev->fn; 617 fwcmd->params.req.cq_id = cq->cq_id; 618 619 oce_page_list(wq->ring->dbuf, fwcmd->params.req.pages, 620 wq->ring->dbuf->num_pages); 621 622 /* fill rest of mbx */ 623 mbx.u0.s.embedded = 1; 624 mbx.payload_length = sizeof (struct mbx_create_nic_wq); 625 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 626 627 /* now post the command */ 628 ret = oce_mbox_post(dev, &mbx, NULL); 629 if (ret != DDI_SUCCESS) { 630 oce_log(dev, CE_WARN, MOD_CONFIG, 631 "WQ create failed: %d", ret); 632 oce_cq_del(dev, cq); 633 return (ret); 634 } 635 636 /* interpret the response */ 637 wq->wq_id = LE_16(fwcmd->params.rsp.wq_id); 638 wq->qstate = QCREATED; 639 wq->cq = cq; 640 /* set the WQCQ handlers */ 641 wq->cq->cq_handler = oce_drain_wq_cq; 642 wq->cq->cb_arg = (void *)wq; 643 /* All are free to start with */ 644 wq->wq_free = wq->cfg.q_len; 645 /* reset indicies */ 646 wq->ring->cidx = 0; 647 wq->ring->pidx = 0; 648 oce_log(dev, CE_NOTE, MOD_CONFIG, "WQ CREATED WQID = %d", 649 wq->wq_id); 650 651 return (0); 652 } 653 654 /* 655 * function to delete a WQ 656 * 657 * dev - software handle to the device 658 * wq - WQ to delete 659 * 660 * return none 661 */ 662 static void 663 oce_wq_del(struct oce_dev *dev, struct oce_wq *wq) 664 { 665 struct oce_mbx mbx; 666 struct mbx_delete_nic_wq *fwcmd; 667 668 669 ASSERT(dev != NULL); 670 ASSERT(wq != NULL); 671 if (wq->qstate == QCREATED) { 672 bzero(&mbx, sizeof (struct oce_mbx)); 673 /* now fill the command */ 674 fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload; 675 fwcmd->params.req.wq_id = wq->wq_id; 676 (void) oce_destroy_q(dev, &mbx, 677 sizeof (struct mbx_delete_nic_wq), 678 QTYPE_WQ); 679 wq->qstate = QDELETED; 680 oce_cq_del(dev, wq->cq); 681 wq->cq = NULL; 682 } 683 } /* oce_wq_del */ 684 685 /* 686 * function to allocate RQ resources 687 * 688 * dev - software handle to the device 689 * rqcfg - configuration structure providing RQ config parameters 690 * 691 * return pointer to the RQ created. NULL on failure 692 */ 693 static struct oce_rq * 694 oce_rq_init(struct oce_dev *dev, uint32_t q_len, 695 uint32_t frag_size, uint32_t mtu, 696 boolean_t rss) 697 { 698 699 struct oce_rq *rq; 700 int ret; 701 702 /* validate q creation parameters */ 703 if (!OCE_LOG2(frag_size)) 704 return (NULL); 705 if ((q_len == 0) || (q_len > 1024)) 706 return (NULL); 707 708 /* allocate the rq */ 709 rq = kmem_zalloc(sizeof (struct oce_rq), KM_NOSLEEP); 710 if (rq == NULL) { 711 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 712 "RQ allocation failed"); 713 return (NULL); 714 } 715 716 rq->cfg.q_len = q_len; 717 rq->cfg.frag_size = frag_size; 718 rq->cfg.mtu = mtu; 719 rq->cfg.eqd = 0; 720 rq->cfg.nbufs = dev->rq_max_bufs; 721 rq->cfg.is_rss_queue = rss; 722 723 /* assign parent */ 724 rq->parent = (void *)dev; 725 726 rq->rq_bdesc_array = 727 kmem_zalloc((sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs), KM_NOSLEEP); 728 if (rq->rq_bdesc_array == NULL) { 729 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 730 "RQ bdesc alloc failed"); 731 goto rqbd_alloc_fail; 732 } 733 /* create the rq buffer descriptor ring */ 734 rq->shadow_ring = 735 kmem_zalloc((rq->cfg.q_len * sizeof (oce_rq_bdesc_t *)), 736 KM_NOSLEEP); 737 if (rq->shadow_ring == NULL) { 738 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 739 "RQ shadow ring alloc failed "); 740 goto rq_shdw_fail; 741 } 742 743 /* allocate the free list array */ 744 rq->rqb_freelist = 745 kmem_zalloc(rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *), KM_NOSLEEP); 746 if (rq->rqb_freelist == NULL) { 747 goto rqb_free_list_fail; 748 } 749 /* create the buffer pool */ 750 ret = oce_rqb_cache_create(rq, dev->rq_frag_size + 751 OCE_RQE_BUF_HEADROOM); 752 if (ret != DDI_SUCCESS) { 753 goto rqb_fail; 754 } 755 756 /* create the ring buffer */ 757 rq->ring = create_ring_buffer(dev, q_len, 758 sizeof (struct oce_nic_rqe), DDI_DMA_CONSISTENT | DDI_DMA_RDWR); 759 if (rq->ring == NULL) { 760 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 761 "RQ ring create failed "); 762 goto rq_ringfail; 763 } 764 765 /* Initialize the RQ lock */ 766 mutex_init(&rq->rx_lock, NULL, MUTEX_DRIVER, 767 DDI_INTR_PRI(dev->intr_pri)); 768 /* Initialize the recharge lock */ 769 mutex_init(&rq->rc_lock, NULL, MUTEX_DRIVER, 770 DDI_INTR_PRI(dev->intr_pri)); 771 atomic_inc_32(&dev->nrqs); 772 return (rq); 773 774 rq_ringfail: 775 oce_rqb_cache_destroy(rq); 776 rqb_fail: 777 kmem_free(rq->rqb_freelist, 778 (rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *))); 779 rqb_free_list_fail: 780 781 kmem_free(rq->shadow_ring, 782 (rq->cfg.q_len * sizeof (oce_rq_bdesc_t *))); 783 rq_shdw_fail: 784 kmem_free(rq->rq_bdesc_array, 785 (sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs)); 786 rqbd_alloc_fail: 787 kmem_free(rq, sizeof (struct oce_rq)); 788 return (NULL); 789 } /* oce_rq_create */ 790 791 /* 792 * function to delete an RQ 793 * 794 * dev - software handle to the device 795 * rq - RQ to delete 796 * 797 * return none 798 */ 799 static void 800 oce_rq_fini(struct oce_dev *dev, struct oce_rq *rq) 801 { 802 /* Destroy buffer cache */ 803 oce_rqb_cache_destroy(rq); 804 destroy_ring_buffer(dev, rq->ring); 805 rq->ring = NULL; 806 kmem_free(rq->shadow_ring, 807 sizeof (oce_rq_bdesc_t *) * rq->cfg.q_len); 808 rq->shadow_ring = NULL; 809 kmem_free(rq->rq_bdesc_array, 810 (sizeof (oce_rq_bdesc_t) * rq->cfg.nbufs)); 811 rq->rq_bdesc_array = NULL; 812 kmem_free(rq->rqb_freelist, 813 (rq->cfg.nbufs * sizeof (oce_rq_bdesc_t *))); 814 rq->rqb_freelist = NULL; 815 mutex_destroy(&rq->rx_lock); 816 mutex_destroy(&rq->rc_lock); 817 kmem_free(rq, sizeof (struct oce_rq)); 818 atomic_dec_32(&dev->nrqs); 819 } /* oce_rq_del */ 820 821 822 static int 823 oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq) 824 { 825 struct oce_mbx mbx; 826 struct mbx_create_nic_rq *fwcmd; 827 struct oce_dev *dev = rq->parent; 828 struct oce_cq *cq; 829 int ret; 830 831 cq = oce_cq_create(dev, eq, CQ_LEN_1024, sizeof (struct oce_nic_rx_cqe), 832 B_FALSE, B_TRUE, B_FALSE, 3); 833 834 if (cq == NULL) { 835 return (DDI_FAILURE); 836 } 837 838 /* now fill the command */ 839 bzero(&mbx, sizeof (struct oce_mbx)); 840 fwcmd = (struct mbx_create_nic_rq *)&mbx.payload; 841 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 842 MBX_SUBSYSTEM_NIC, 843 OPCODE_CREATE_NIC_RQ, MBX_TIMEOUT_SEC, 844 sizeof (struct mbx_create_nic_rq)); 845 846 fwcmd->params.req.num_pages = rq->ring->dbuf->num_pages; 847 fwcmd->params.req.frag_size = OCE_LOG2(rq->cfg.frag_size); 848 fwcmd->params.req.cq_id = cq->cq_id; 849 oce_page_list(rq->ring->dbuf, fwcmd->params.req.pages, 850 rq->ring->dbuf->num_pages); 851 852 fwcmd->params.req.if_id = if_id; 853 fwcmd->params.req.max_frame_size = (uint16_t)rq->cfg.mtu; 854 fwcmd->params.req.is_rss_queue = rq->cfg.is_rss_queue; 855 856 /* fill rest of mbx */ 857 mbx.u0.s.embedded = 1; 858 mbx.payload_length = sizeof (struct mbx_create_nic_rq); 859 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 860 861 /* now post the command */ 862 ret = oce_mbox_post(dev, &mbx, NULL); 863 if (ret != 0) { 864 oce_log(dev, CE_WARN, MOD_CONFIG, 865 "RQ create failed: %d", ret); 866 oce_cq_del(dev, cq); 867 return (ret); 868 } 869 870 /* interpret the response */ 871 rq->rq_id = LE_16(fwcmd->params.rsp.u0.s.rq_id); 872 rq->rss_cpuid = fwcmd->params.rsp.u0.s.rss_cpuid; 873 rq->cfg.if_id = if_id; 874 rq->qstate = QCREATED; 875 rq->cq = cq; 876 877 /* set the Completion Handler */ 878 rq->cq->cq_handler = oce_drain_rq_cq; 879 rq->cq->cb_arg = (void *)rq; 880 /* reset the indicies */ 881 rq->ring->cidx = 0; 882 rq->ring->pidx = 0; 883 rq->buf_avail = 0; 884 oce_log(dev, CE_NOTE, MOD_CONFIG, "RQ created, RQID : %d", rq->rq_id); 885 return (0); 886 887 } 888 889 /* 890 * function to delete an RQ 891 * 892 * dev - software handle to the device 893 * rq - RQ to delete 894 * 895 * return none 896 */ 897 static void 898 oce_rq_del(struct oce_dev *dev, struct oce_rq *rq) 899 { 900 struct oce_mbx mbx; 901 struct mbx_delete_nic_rq *fwcmd; 902 903 ASSERT(dev != NULL); 904 ASSERT(rq != NULL); 905 906 bzero(&mbx, sizeof (struct oce_mbx)); 907 908 /* delete the Queue */ 909 if (rq->qstate == QCREATED) { 910 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 911 fwcmd->params.req.rq_id = rq->rq_id; 912 (void) oce_destroy_q(dev, &mbx, 913 sizeof (struct mbx_delete_nic_rq), QTYPE_RQ); 914 rq->qstate = QDELETED; 915 oce_clean_rq(rq); 916 /* Delete the associated CQ */ 917 oce_cq_del(dev, rq->cq); 918 rq->cq = NULL; 919 /* free up the posted buffers */ 920 oce_rq_discharge(rq); 921 } 922 } /* oce_rq_del */ 923 924 /* 925 * function to arm an EQ so that it can generate events 926 * 927 * dev - software handle to the device 928 * qid - id of the EQ returned by the fw at the time of creation 929 * npopped - number of EQEs to arm with 930 * rearm - rearm bit 931 * clearint - bit to clear the interrupt condition because of which 932 * EQEs are generated 933 * 934 * return none 935 */ 936 void 937 oce_arm_eq(struct oce_dev *dev, int16_t qid, int npopped, 938 boolean_t rearm, boolean_t clearint) 939 { 940 eq_db_t eq_db = {0}; 941 942 eq_db.bits.rearm = rearm; 943 eq_db.bits.event = B_TRUE; 944 eq_db.bits.num_popped = npopped; 945 eq_db.bits.clrint = clearint; 946 eq_db.bits.qid = qid; 947 OCE_DB_WRITE32(dev, PD_EQ_DB, eq_db.dw0); 948 } 949 950 /* 951 * function to arm a CQ with CQEs 952 * 953 * dev - software handle to the device 954 * qid - the id of the CQ returned by the fw at the time of creation 955 * npopped - number of CQEs to arm with 956 * rearm - rearm bit enable/disable 957 * 958 * return none 959 */ 960 void 961 oce_arm_cq(struct oce_dev *dev, int16_t qid, int npopped, 962 boolean_t rearm) 963 { 964 cq_db_t cq_db = {0}; 965 cq_db.bits.rearm = rearm; 966 cq_db.bits.num_popped = npopped; 967 cq_db.bits.event = 0; 968 cq_db.bits.qid = qid; 969 OCE_DB_WRITE32(dev, PD_CQ_DB, cq_db.dw0); 970 } 971 972 973 /* 974 * function to delete a EQ, CQ, MQ, WQ or RQ 975 * 976 * dev - sofware handle to the device 977 * mbx - mbox command to send to the fw to delete the queue 978 * mbx contains the queue information to delete 979 * req_size - the size of the mbx payload dependent on the qtype 980 * qtype - the type of queue i.e. EQ, CQ, MQ, WQ or RQ 981 * 982 * return DDI_SUCCESS => success, failure otherwise 983 */ 984 int 985 oce_destroy_q(struct oce_dev *dev, struct oce_mbx *mbx, size_t req_size, 986 enum qtype qtype) 987 { 988 struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload; 989 int opcode; 990 int subsys; 991 int ret; 992 993 switch (qtype) { 994 case QTYPE_EQ: { 995 opcode = OPCODE_DESTROY_COMMON_EQ; 996 subsys = MBX_SUBSYSTEM_COMMON; 997 break; 998 } 999 case QTYPE_CQ: { 1000 opcode = OPCODE_DESTROY_COMMON_CQ; 1001 subsys = MBX_SUBSYSTEM_COMMON; 1002 break; 1003 } 1004 case QTYPE_MQ: { 1005 opcode = OPCODE_DESTROY_COMMON_MQ; 1006 subsys = MBX_SUBSYSTEM_COMMON; 1007 break; 1008 } 1009 case QTYPE_WQ: { 1010 opcode = OPCODE_DELETE_NIC_WQ; 1011 subsys = MBX_SUBSYSTEM_NIC; 1012 break; 1013 } 1014 case QTYPE_RQ: { 1015 opcode = OPCODE_DELETE_NIC_RQ; 1016 subsys = MBX_SUBSYSTEM_NIC; 1017 break; 1018 } 1019 default: { 1020 ASSERT(0); 1021 break; 1022 } 1023 } 1024 1025 mbx_common_req_hdr_init(hdr, 0, 0, subsys, 1026 opcode, MBX_TIMEOUT_SEC, req_size); 1027 1028 /* fill rest of mbx */ 1029 mbx->u0.s.embedded = 1; 1030 mbx->payload_length = (uint32_t)req_size; 1031 DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ); 1032 1033 /* send command */ 1034 ret = oce_mbox_post(dev, mbx, NULL); 1035 1036 if (ret != 0) { 1037 oce_log(dev, CE_WARN, MOD_CONFIG, "%s", 1038 "Failed to del q "); 1039 } 1040 return (ret); 1041 } 1042 1043 /* 1044 * function to set the delay parameter in the EQ for interrupt coalescing 1045 * 1046 * dev - software handle to the device 1047 * eq_arr - array of EQ ids to delete 1048 * eq_cnt - number of elements in eq_arr 1049 * eq_delay - delay parameter 1050 * 1051 * return DDI_SUCCESS => success, failure otherwise 1052 */ 1053 int 1054 oce_set_eq_delay(struct oce_dev *dev, uint32_t *eq_arr, 1055 uint32_t eq_cnt, uint32_t eq_delay) 1056 { 1057 struct oce_mbx mbx; 1058 struct mbx_modify_common_eq_delay *fwcmd; 1059 int ret; 1060 int neq; 1061 1062 bzero(&mbx, sizeof (struct oce_mbx)); 1063 fwcmd = (struct mbx_modify_common_eq_delay *)&mbx.payload; 1064 1065 /* fill the command */ 1066 fwcmd->params.req.num_eq = eq_cnt; 1067 for (neq = 0; neq < eq_cnt; neq++) { 1068 fwcmd->params.req.delay[neq].eq_id = eq_arr[neq]; 1069 fwcmd->params.req.delay[neq].phase = 0; 1070 fwcmd->params.req.delay[neq].dm = eq_delay; 1071 1072 } 1073 1074 /* initialize the ioctl header */ 1075 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 1076 MBX_SUBSYSTEM_COMMON, 1077 OPCODE_MODIFY_COMMON_EQ_DELAY, 1078 MBX_TIMEOUT_SEC, 1079 sizeof (struct mbx_modify_common_eq_delay)); 1080 1081 /* fill rest of mbx */ 1082 mbx.u0.s.embedded = 1; 1083 mbx.payload_length = sizeof (struct mbx_modify_common_eq_delay); 1084 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 1085 1086 /* post the command */ 1087 ret = oce_mbox_post(dev, &mbx, NULL); 1088 if (ret != 0) { 1089 oce_log(dev, CE_WARN, MOD_CONFIG, 1090 "Failed to set EQ delay %d", ret); 1091 } 1092 1093 return (ret); 1094 } /* oce_set_eq_delay */ 1095 1096 /* 1097 * function to cleanup the eqs used during stop 1098 * 1099 * eq - pointer to event queue structure 1100 * 1101 * return none 1102 */ 1103 void 1104 oce_drain_eq(struct oce_eq *eq) 1105 { 1106 struct oce_eqe *eqe; 1107 uint16_t num_eqe = 0; 1108 struct oce_dev *dev; 1109 1110 dev = eq->parent; 1111 /* get the first item in eq to process */ 1112 eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe); 1113 1114 while (eqe->u0.dw0) { 1115 eqe->u0.dw0 = LE_32(eqe->u0.dw0); 1116 1117 /* clear valid bit */ 1118 eqe->u0.dw0 = 0; 1119 1120 /* process next eqe */ 1121 RING_GET(eq->ring, 1); 1122 1123 eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe); 1124 num_eqe++; 1125 } /* for all EQEs */ 1126 if (num_eqe) { 1127 oce_arm_eq(dev, eq->eq_id, num_eqe, B_FALSE, B_TRUE); 1128 } 1129 } /* oce_drain_eq */ 1130 1131 1132 int 1133 oce_init_txrx(struct oce_dev *dev) 1134 { 1135 int qid = 0; 1136 1137 /* enable RSS if rx queues > 1 */ 1138 dev->rss_enable = (dev->rx_rings > 1) ? B_TRUE : B_FALSE; 1139 1140 for (qid = 0; qid < dev->tx_rings; qid++) { 1141 dev->wq[qid] = oce_wq_init(dev, dev->tx_ring_size, 1142 NIC_WQ_TYPE_STANDARD); 1143 if (dev->wq[qid] == NULL) { 1144 goto queue_fail; 1145 } 1146 } 1147 1148 /* Now create the Rx Queues */ 1149 /* qid 0 is always default non rss queue for rss */ 1150 dev->rq[0] = oce_rq_init(dev, dev->rx_ring_size, dev->rq_frag_size, 1151 OCE_MAX_JUMBO_FRAME_SIZE, B_FALSE); 1152 if (dev->rq[0] == NULL) { 1153 goto queue_fail; 1154 } 1155 1156 for (qid = 1; qid < dev->rx_rings; qid++) { 1157 dev->rq[qid] = oce_rq_init(dev, dev->rx_ring_size, 1158 dev->rq_frag_size, OCE_MAX_JUMBO_FRAME_SIZE, 1159 dev->rss_enable); 1160 if (dev->rq[qid] == NULL) { 1161 goto queue_fail; 1162 } 1163 } 1164 1165 return (DDI_SUCCESS); 1166 queue_fail: 1167 oce_fini_txrx(dev); 1168 return (DDI_FAILURE); 1169 } 1170 void 1171 oce_fini_txrx(struct oce_dev *dev) 1172 { 1173 int qid; 1174 int nqs; 1175 1176 /* free all the tx rings */ 1177 /* nwqs is decremented in fini so copy count first */ 1178 nqs = dev->nwqs; 1179 for (qid = 0; qid < nqs; qid++) { 1180 if (dev->wq[qid] != NULL) { 1181 oce_wq_fini(dev, dev->wq[qid]); 1182 dev->wq[qid] = NULL; 1183 } 1184 } 1185 /* free all the rx rings */ 1186 nqs = dev->nrqs; 1187 for (qid = 0; qid < nqs; qid++) { 1188 if (dev->rq[qid] != NULL) { 1189 oce_rq_fini(dev, dev->rq[qid]); 1190 dev->rq[qid] = NULL; 1191 } 1192 } 1193 } 1194 1195 int 1196 oce_create_queues(struct oce_dev *dev) 1197 { 1198 1199 int i; 1200 struct oce_eq *eq; 1201 struct oce_mq *mq; 1202 1203 for (i = 0; i < dev->num_vectors; i++) { 1204 eq = oce_eq_create(dev, EQ_LEN_1024, EQE_SIZE_4, 0); 1205 if (eq == NULL) { 1206 goto rings_fail; 1207 } 1208 dev->eq[i] = eq; 1209 } 1210 for (i = 0; i < dev->nwqs; i++) { 1211 if (oce_wq_create(dev->wq[i], dev->eq[0]) != 0) 1212 goto rings_fail; 1213 } 1214 1215 for (i = 0; i < dev->nrqs; i++) { 1216 if (oce_rq_create(dev->rq[i], dev->if_id, 1217 dev->neqs > 1 ? dev->eq[1 + i] : dev->eq[0]) != 0) 1218 goto rings_fail; 1219 } 1220 mq = oce_mq_create(dev, dev->eq[0], 64); 1221 if (mq == NULL) 1222 goto rings_fail; 1223 dev->mq = mq; 1224 return (DDI_SUCCESS); 1225 rings_fail: 1226 oce_delete_queues(dev); 1227 return (DDI_FAILURE); 1228 1229 } 1230 1231 void 1232 oce_delete_queues(struct oce_dev *dev) 1233 { 1234 int i; 1235 int neqs = dev->neqs; 1236 if (dev->mq != NULL) { 1237 oce_mq_del(dev, dev->mq); 1238 dev->mq = NULL; 1239 } 1240 1241 for (i = 0; i < dev->nrqs; i++) { 1242 oce_rq_del(dev, dev->rq[i]); 1243 } 1244 for (i = 0; i < dev->nwqs; i++) { 1245 oce_wq_del(dev, dev->wq[i]); 1246 } 1247 /* delete as many eqs as the number of vectors */ 1248 for (i = 0; i < neqs; i++) { 1249 oce_eq_del(dev, dev->eq[i]); 1250 dev->eq[i] = NULL; 1251 } 1252 } 1253 1254 void 1255 oce_dev_rss_ready(struct oce_dev *dev) 1256 { 1257 uint8_t dev_index = 0; 1258 uint8_t adapter_rss = 0; 1259 1260 /* Return if rx_rings <= 1 (No RSS) */ 1261 if (dev->rx_rings <= 1) { 1262 oce_log(dev, CE_NOTE, MOD_CONFIG, 1263 "Rx rings = %d, Not enabling RSS", dev->rx_rings); 1264 return; 1265 } 1266 1267 /* 1268 * Count the number of PCI functions enabling RSS on this 1269 * adapter 1270 */ 1271 while (dev_index < MAX_DEVS) { 1272 if ((oce_dev_list[dev_index] != NULL) && 1273 (dev->pci_bus == oce_dev_list[dev_index]->pci_bus) && 1274 (dev->pci_device == oce_dev_list[dev_index]->pci_device) && 1275 (oce_dev_list[dev_index]->rss_enable)) { 1276 adapter_rss++; 1277 } 1278 dev_index++; 1279 } 1280 1281 /* 1282 * If there are already MAX_RSS_PER_ADAPTER PCI functions using 1283 * RSS on this adapter, reduce the number of rx rings to 1 1284 * (No RSS) 1285 */ 1286 if (adapter_rss >= MAX_RSS_PER_ADAPTER) { 1287 dev->rx_rings = 1; 1288 } 1289 } 1290