1 /*- 2 * Copyright (C) 2012 Emulex 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 are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the Emulex Corporation nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Contact Information: 32 * freebsd-drivers@emulex.com 33 * 34 * Emulex 35 * 3333 Susan Street 36 * Costa Mesa, CA 92626 37 */ 38 39 40 41 /* $FreeBSD$ */ 42 43 44 #include "oce_if.h" 45 46 /***************************************************** 47 * local queue functions 48 *****************************************************/ 49 50 static struct oce_wq *oce_wq_init(POCE_SOFTC sc, 51 uint32_t q_len, uint32_t wq_type); 52 static int oce_wq_create(struct oce_wq *wq, struct oce_eq *eq); 53 static void oce_wq_free(struct oce_wq *wq); 54 static void oce_wq_del(struct oce_wq *wq); 55 static struct oce_rq *oce_rq_init(POCE_SOFTC sc, 56 uint32_t q_len, 57 uint32_t frag_size, 58 uint32_t mtu, uint32_t rss); 59 static int oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq); 60 static void oce_rq_free(struct oce_rq *rq); 61 static void oce_rq_del(struct oce_rq *rq); 62 static struct oce_eq *oce_eq_create(POCE_SOFTC sc, 63 uint32_t q_len, 64 uint32_t item_size, 65 uint32_t eq_delay, 66 uint32_t vector); 67 static void oce_eq_del(struct oce_eq *eq); 68 static struct oce_mq *oce_mq_create(POCE_SOFTC sc, 69 struct oce_eq *eq, uint32_t q_len); 70 static void oce_mq_free(struct oce_mq *mq); 71 static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx 72 *mbx, size_t req_size, enum qtype qtype); 73 struct oce_cq *oce_cq_create(POCE_SOFTC sc, 74 struct oce_eq *eq, 75 uint32_t q_len, 76 uint32_t item_size, 77 uint32_t sol_event, 78 uint32_t is_eventable, 79 uint32_t nodelay, uint32_t ncoalesce); 80 static void oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq); 81 82 83 84 /** 85 * @brief Create and initialize all the queues on the board 86 * @param sc software handle to the device 87 * @returns 0 if successful, or error 88 **/ 89 int 90 oce_queue_init_all(POCE_SOFTC sc) 91 { 92 int rc = 0, i, vector; 93 struct oce_wq *wq; 94 struct oce_rq *rq; 95 96 /* alloc TX/RX queues */ 97 for_all_wq_queues(sc, wq, i) { 98 sc->wq[i] = oce_wq_init(sc, sc->tx_ring_size, 99 NIC_WQ_TYPE_STANDARD); 100 if (!sc->wq[i]) 101 goto error; 102 103 } 104 105 for_all_rq_queues(sc, rq, i) { 106 sc->rq[i] = oce_rq_init(sc, sc->rx_ring_size, sc->rq_frag_size, 107 OCE_MAX_JUMBO_FRAME_SIZE, 108 (i == 0) ? 0 : sc->rss_enable); 109 if (!sc->rq[i]) 110 goto error; 111 } 112 113 /* Create network interface on card */ 114 if (oce_create_nw_interface(sc)) 115 goto error; 116 117 /* create all of the event queues */ 118 for (vector = 0; vector < sc->intr_count; vector++) { 119 sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4, 120 0, vector); 121 if (!sc->eq[vector]) 122 goto error; 123 } 124 125 /* create Tx, Rx and mcc queues */ 126 for_all_wq_queues(sc, wq, i) { 127 rc = oce_wq_create(wq, sc->eq[i]); 128 if (rc) 129 goto error; 130 wq->queue_index = i; 131 TASK_INIT(&wq->txtask, 1, oce_tx_task, wq); 132 } 133 134 for_all_rq_queues(sc, rq, i) { 135 rc = oce_rq_create(rq, sc->if_id, 136 sc->eq[(i == 0) ? 0:(i-1)]); 137 if (rc) 138 goto error; 139 rq->queue_index = i; 140 } 141 142 sc->mq = oce_mq_create(sc, sc->eq[0], 64); 143 if (!sc->mq) 144 goto error; 145 146 return rc; 147 148 error: 149 oce_queue_release_all(sc); 150 return 1; 151 } 152 153 154 155 /** 156 * @brief Releases all mailbox queues created 157 * @param sc software handle to the device 158 */ 159 void 160 oce_queue_release_all(POCE_SOFTC sc) 161 { 162 int i = 0; 163 struct oce_wq *wq; 164 struct oce_rq *rq; 165 struct oce_eq *eq; 166 167 for_all_rq_queues(sc, rq, i) { 168 if (rq) { 169 oce_rq_del(sc->rq[i]); 170 oce_rq_free(sc->rq[i]); 171 } 172 } 173 174 for_all_wq_queues(sc, wq, i) { 175 if (wq) { 176 oce_wq_del(sc->wq[i]); 177 oce_wq_free(sc->wq[i]); 178 } 179 } 180 181 if (sc->mq) 182 oce_mq_free(sc->mq); 183 184 for_all_evnt_queues(sc, eq, i) { 185 if (eq) 186 oce_eq_del(sc->eq[i]); 187 } 188 } 189 190 191 192 /** 193 * @brief Function to create a WQ for NIC Tx 194 * @param sc software handle to the device 195 * @param qlen number of entries in the queue 196 * @param wq_type work queue type 197 * @returns the pointer to the WQ created or NULL on failure 198 */ 199 static struct 200 oce_wq *oce_wq_init(POCE_SOFTC sc, uint32_t q_len, uint32_t wq_type) 201 { 202 struct oce_wq *wq; 203 int rc = 0, i; 204 205 /* q_len must be min 256 and max 2k */ 206 if (q_len < 256 || q_len > 2048) { 207 device_printf(sc->dev, 208 "Invalid q length. Must be " 209 "[256, 2000]: 0x%x\n", q_len); 210 return NULL; 211 } 212 213 /* allocate wq */ 214 wq = malloc(sizeof(struct oce_wq), M_DEVBUF, M_NOWAIT | M_ZERO); 215 if (!wq) 216 return NULL; 217 218 /* Set the wq config */ 219 wq->cfg.q_len = q_len; 220 wq->cfg.wq_type = (uint8_t) wq_type; 221 wq->cfg.eqd = OCE_DEFAULT_WQ_EQD; 222 wq->cfg.nbufs = 2 * wq->cfg.q_len; 223 wq->cfg.nhdl = 2 * wq->cfg.q_len; 224 225 wq->parent = (void *)sc; 226 227 rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 228 1, 0, 229 BUS_SPACE_MAXADDR, 230 BUS_SPACE_MAXADDR, 231 NULL, NULL, 232 OCE_MAX_TX_SIZE, 233 OCE_MAX_TX_ELEMENTS, 234 PAGE_SIZE, 0, NULL, NULL, &wq->tag); 235 236 if (rc) 237 goto free_wq; 238 239 240 for (i = 0; i < OCE_WQ_PACKET_ARRAY_SIZE; i++) { 241 rc = bus_dmamap_create(wq->tag, 0, &wq->pckts[i].map); 242 if (rc) 243 goto free_wq; 244 } 245 246 wq->ring = oce_create_ring_buffer(sc, q_len, NIC_WQE_SIZE); 247 if (!wq->ring) 248 goto free_wq; 249 250 251 LOCK_CREATE(&wq->tx_lock, "TX_lock"); 252 253 #if __FreeBSD_version >= 800000 254 /* Allocate buf ring for multiqueue*/ 255 wq->br = buf_ring_alloc(4096, M_DEVBUF, 256 M_WAITOK, &wq->tx_lock.mutex); 257 if (!wq->br) 258 goto free_wq; 259 #endif 260 return wq; 261 262 263 free_wq: 264 device_printf(sc->dev, "Create WQ failed\n"); 265 oce_wq_free(wq); 266 return NULL; 267 } 268 269 270 271 /** 272 * @brief Frees the work queue 273 * @param wq pointer to work queue to free 274 */ 275 static void 276 oce_wq_free(struct oce_wq *wq) 277 { 278 POCE_SOFTC sc = (POCE_SOFTC) wq->parent; 279 int i; 280 281 taskqueue_drain(taskqueue_swi, &wq->txtask); 282 283 if (wq->ring != NULL) { 284 oce_destroy_ring_buffer(sc, wq->ring); 285 wq->ring = NULL; 286 } 287 288 for (i = 0; i < OCE_WQ_PACKET_ARRAY_SIZE; i++) { 289 if (wq->pckts[i].map != NULL) { 290 bus_dmamap_unload(wq->tag, wq->pckts[i].map); 291 bus_dmamap_destroy(wq->tag, wq->pckts[i].map); 292 wq->pckts[i].map = NULL; 293 } 294 } 295 296 if (wq->tag != NULL) 297 bus_dma_tag_destroy(wq->tag); 298 if (wq->br != NULL) 299 buf_ring_free(wq->br, M_DEVBUF); 300 301 LOCK_DESTROY(&wq->tx_lock); 302 free(wq, M_DEVBUF); 303 } 304 305 306 307 /** 308 * @brief Create a work queue 309 * @param wq pointer to work queue 310 * @param eq pointer to associated event queue 311 */ 312 static int 313 oce_wq_create(struct oce_wq *wq, struct oce_eq *eq) 314 { 315 POCE_SOFTC sc = wq->parent; 316 struct oce_cq *cq; 317 int rc = 0; 318 319 /* create the CQ */ 320 cq = oce_cq_create(sc, 321 eq, 322 CQ_LEN_1024, 323 sizeof(struct oce_nic_tx_cqe), 0, 1, 0, 3); 324 if (!cq) 325 return ENXIO; 326 327 328 wq->cq = cq; 329 330 rc = oce_mbox_create_wq(wq); 331 if (rc) 332 goto error; 333 334 wq->qstate = QCREATED; 335 wq->wq_free = wq->cfg.q_len; 336 wq->ring->cidx = 0; 337 wq->ring->pidx = 0; 338 339 eq->cq[eq->cq_valid] = cq; 340 eq->cq_valid++; 341 cq->cb_arg = wq; 342 cq->cq_handler = oce_wq_handler; 343 344 return 0; 345 346 error: 347 device_printf(sc->dev, "WQ create failed\n"); 348 oce_wq_del(wq); 349 return rc; 350 } 351 352 353 354 355 /** 356 * @brief Delete a work queue 357 * @param wq pointer to work queue 358 */ 359 static void 360 oce_wq_del(struct oce_wq *wq) 361 { 362 struct oce_mbx mbx; 363 struct mbx_delete_nic_wq *fwcmd; 364 POCE_SOFTC sc = (POCE_SOFTC) wq->parent; 365 366 if (wq->qstate == QCREATED) { 367 bzero(&mbx, sizeof(struct oce_mbx)); 368 /* now fill the command */ 369 fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload; 370 fwcmd->params.req.wq_id = wq->wq_id; 371 (void)oce_destroy_q(sc, &mbx, 372 sizeof(struct mbx_delete_nic_wq), QTYPE_WQ); 373 wq->qstate = QDELETED; 374 } 375 376 if (wq->cq != NULL) { 377 oce_cq_del(sc, wq->cq); 378 wq->cq = NULL; 379 } 380 } 381 382 383 384 /** 385 * @brief function to allocate receive queue resources 386 * @param sc software handle to the device 387 * @param q_len length of receive queue 388 * @param frag_size size of an receive queue fragment 389 * @param mtu maximum transmission unit 390 * @param rss is-rss-queue flag 391 * @returns the pointer to the RQ created or NULL on failure 392 */ 393 static struct 394 oce_rq *oce_rq_init(POCE_SOFTC sc, 395 uint32_t q_len, 396 uint32_t frag_size, 397 uint32_t mtu, uint32_t rss) 398 { 399 struct oce_rq *rq; 400 int rc = 0, i; 401 402 if (OCE_LOG2(frag_size) <= 0) 403 return NULL; 404 405 if ((q_len == 0) || (q_len > 1024)) 406 return NULL; 407 408 /* allocate the rq */ 409 rq = malloc(sizeof(struct oce_rq), M_DEVBUF, M_NOWAIT | M_ZERO); 410 if (!rq) 411 return NULL; 412 413 414 rq->cfg.q_len = q_len; 415 rq->cfg.frag_size = frag_size; 416 rq->cfg.mtu = mtu; 417 rq->cfg.eqd = 0; 418 rq->lro_pkts_queued = 0; 419 rq->cfg.is_rss_queue = rss; 420 rq->packets_in = 0; 421 rq->packets_out = 0; 422 rq->pending = 0; 423 424 rq->parent = (void *)sc; 425 426 rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 427 1, 0, 428 BUS_SPACE_MAXADDR, 429 BUS_SPACE_MAXADDR, 430 NULL, NULL, 431 OCE_MAX_RX_SIZE, 432 1, PAGE_SIZE, 0, NULL, NULL, &rq->tag); 433 434 if (rc) 435 goto free_rq; 436 437 for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) { 438 rc = bus_dmamap_create(rq->tag, 0, &rq->pckts[i].map); 439 if (rc) 440 goto free_rq; 441 } 442 443 /* create the ring buffer */ 444 rq->ring = oce_create_ring_buffer(sc, q_len, 445 sizeof(struct oce_nic_rqe)); 446 if (!rq->ring) 447 goto free_rq; 448 449 LOCK_CREATE(&rq->rx_lock, "RX_lock"); 450 451 return rq; 452 453 free_rq: 454 device_printf(sc->dev, "Create RQ failed\n"); 455 oce_rq_free(rq); 456 return NULL; 457 } 458 459 460 461 462 /** 463 * @brief Free a receive queue 464 * @param rq pointer to receive queue 465 */ 466 static void 467 oce_rq_free(struct oce_rq *rq) 468 { 469 POCE_SOFTC sc = (POCE_SOFTC) rq->parent; 470 int i = 0 ; 471 472 if (rq->ring != NULL) { 473 oce_destroy_ring_buffer(sc, rq->ring); 474 rq->ring = NULL; 475 } 476 for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) { 477 if (rq->pckts[i].map != NULL) { 478 bus_dmamap_unload(rq->tag, rq->pckts[i].map); 479 bus_dmamap_destroy(rq->tag, rq->pckts[i].map); 480 rq->pckts[i].map = NULL; 481 } 482 if (rq->pckts[i].mbuf) { 483 m_free(rq->pckts[i].mbuf); 484 rq->pckts[i].mbuf = NULL; 485 } 486 } 487 488 if (rq->tag != NULL) 489 bus_dma_tag_destroy(rq->tag); 490 491 LOCK_DESTROY(&rq->rx_lock); 492 free(rq, M_DEVBUF); 493 } 494 495 496 497 498 /** 499 * @brief Create a receive queue 500 * @param rq receive queue 501 * @param if_id interface identifier index` 502 * @param eq pointer to event queue 503 */ 504 static int 505 oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq) 506 { 507 POCE_SOFTC sc = rq->parent; 508 struct oce_cq *cq; 509 510 cq = oce_cq_create(sc, 511 eq, 512 CQ_LEN_1024, 513 sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3); 514 if (!cq) 515 return ENXIO; 516 517 rq->cq = cq; 518 rq->cfg.if_id = if_id; 519 520 /* Dont create RQ here. Create in if_activate */ 521 rq->qstate = 0; 522 rq->ring->cidx = 0; 523 rq->ring->pidx = 0; 524 eq->cq[eq->cq_valid] = cq; 525 eq->cq_valid++; 526 cq->cb_arg = rq; 527 cq->cq_handler = oce_rq_handler; 528 529 return 0; 530 531 } 532 533 534 535 536 /** 537 * @brief Delete a receive queue 538 * @param rq receive queue 539 */ 540 static void 541 oce_rq_del(struct oce_rq *rq) 542 { 543 POCE_SOFTC sc = (POCE_SOFTC) rq->parent; 544 struct oce_mbx mbx; 545 struct mbx_delete_nic_rq *fwcmd; 546 547 if (rq->qstate == QCREATED) { 548 bzero(&mbx, sizeof(mbx)); 549 550 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 551 fwcmd->params.req.rq_id = rq->rq_id; 552 (void)oce_destroy_q(sc, &mbx, 553 sizeof(struct mbx_delete_nic_rq), QTYPE_RQ); 554 rq->qstate = QDELETED; 555 } 556 557 if (rq->cq != NULL) { 558 oce_cq_del(sc, rq->cq); 559 rq->cq = NULL; 560 } 561 } 562 563 564 565 /** 566 * @brief function to create an event queue 567 * @param sc software handle to the device 568 * @param q_len length of event queue 569 * @param item_size size of an event queue item 570 * @param eq_delay event queue delay 571 * @retval eq success, pointer to event queue 572 * @retval NULL failure 573 */ 574 static struct 575 oce_eq *oce_eq_create(POCE_SOFTC sc, uint32_t q_len, 576 uint32_t item_size, 577 uint32_t eq_delay, 578 uint32_t vector) 579 { 580 struct oce_eq *eq; 581 int rc = 0; 582 583 /* allocate an eq */ 584 eq = malloc(sizeof(struct oce_eq), M_DEVBUF, M_NOWAIT | M_ZERO); 585 if (eq == NULL) 586 return NULL; 587 588 eq->parent = (void *)sc; 589 eq->eq_id = 0xffff; 590 eq->ring = oce_create_ring_buffer(sc, q_len, item_size); 591 if (!eq->ring) 592 goto free_eq; 593 594 eq->eq_cfg.q_len = q_len; 595 eq->eq_cfg.item_size = item_size; 596 eq->eq_cfg.cur_eqd = (uint8_t) eq_delay; 597 598 rc = oce_mbox_create_eq(eq); 599 if (rc) 600 goto free_eq; 601 602 sc->intrs[sc->neqs++].eq = eq; 603 604 return eq; 605 606 free_eq: 607 oce_eq_del(eq); 608 return NULL; 609 } 610 611 612 613 614 /** 615 * @brief Function to delete an event queue 616 * @param eq pointer to an event queue 617 */ 618 static void 619 oce_eq_del(struct oce_eq *eq) 620 { 621 struct oce_mbx mbx; 622 struct mbx_destroy_common_eq *fwcmd; 623 POCE_SOFTC sc = (POCE_SOFTC) eq->parent; 624 625 if (eq->eq_id != 0xffff) { 626 bzero(&mbx, sizeof(mbx)); 627 fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload; 628 fwcmd->params.req.id = eq->eq_id; 629 (void)oce_destroy_q(sc, &mbx, 630 sizeof(struct mbx_destroy_common_eq), QTYPE_EQ); 631 } 632 633 if (eq->ring != NULL) { 634 oce_destroy_ring_buffer(sc, eq->ring); 635 eq->ring = NULL; 636 } 637 638 free(eq, M_DEVBUF); 639 640 } 641 642 643 644 645 /** 646 * @brief Function to create an MQ 647 * @param sc software handle to the device 648 * @param eq the EQ to associate with the MQ for event notification 649 * @param q_len the number of entries to create in the MQ 650 * @returns pointer to the created MQ, failure otherwise 651 */ 652 static struct oce_mq * 653 oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len) 654 { 655 struct oce_mbx mbx; 656 struct mbx_create_common_mq *fwcmd = NULL; 657 struct oce_mq *mq = NULL; 658 int rc = 0; 659 struct oce_cq *cq; 660 oce_mq_ctx_t *ctx; 661 uint32_t num_pages; 662 uint32_t page_size; 663 uint32_t version; 664 665 666 cq = oce_cq_create(sc, eq, CQ_LEN_256, 667 sizeof(struct oce_mq_cqe), 1, 1, 0, 0); 668 if (!cq) 669 return NULL; 670 671 /* allocate the mq */ 672 mq = malloc(sizeof(struct oce_mq), M_DEVBUF, M_NOWAIT | M_ZERO); 673 if (!mq) { 674 oce_cq_del(sc, cq); 675 goto error; 676 } 677 678 mq->parent = sc; 679 680 mq->ring = oce_create_ring_buffer(sc, q_len, sizeof(struct oce_mbx)); 681 if (!mq->ring) 682 goto error; 683 684 bzero(&mbx, sizeof(struct oce_mbx)); 685 686 fwcmd = (struct mbx_create_common_mq *)&mbx.payload; 687 version = OCE_MBX_VER_V0; 688 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, 689 MBX_SUBSYSTEM_COMMON, 690 OPCODE_COMMON_CREATE_MQ, 691 MBX_TIMEOUT_SEC, 692 sizeof(struct mbx_create_common_mq), 693 version); 694 695 num_pages = oce_page_list(mq->ring, &fwcmd->params.req.pages[0]); 696 page_size = mq->ring->num_items * mq->ring->item_size; 697 698 ctx = &fwcmd->params.req.context; 699 ctx->v0.num_pages = num_pages; 700 ctx->v0.cq_id = cq->cq_id; 701 ctx->v0.ring_size = OCE_LOG2(q_len) + 1; 702 ctx->v0.valid = 1; 703 704 mbx.u0.s.embedded = 1; 705 mbx.payload_length = sizeof(struct mbx_create_common_mq); 706 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); 707 708 rc = oce_mbox_post(sc, &mbx, NULL); 709 if (rc) 710 goto error; 711 712 mq->mq_id = LE_16(fwcmd->params.rsp.mq_id); 713 mq->cq = cq; 714 eq->cq[eq->cq_valid] = cq; 715 eq->cq_valid++; 716 mq->cq->eq = eq; 717 mq->cfg.q_len = (uint8_t) q_len; 718 mq->cfg.eqd = 0; 719 mq->qstate = QCREATED; 720 721 mq->cq->cb_arg = mq; 722 mq->cq->cq_handler = oce_mq_handler; 723 724 return mq; 725 726 error: 727 device_printf(sc->dev, "MQ create failed\n"); 728 oce_mq_free(mq); 729 mq = NULL; 730 return mq; 731 } 732 733 734 735 736 737 /** 738 * @brief Function to free a mailbox queue 739 * @param mq pointer to a mailbox queue 740 */ 741 static void 742 oce_mq_free(struct oce_mq *mq) 743 { 744 POCE_SOFTC sc = (POCE_SOFTC) mq->parent; 745 struct oce_mbx mbx; 746 struct mbx_destroy_common_mq *fwcmd; 747 748 if (!mq) 749 return; 750 751 if (mq->ring != NULL) { 752 oce_destroy_ring_buffer(sc, mq->ring); 753 mq->ring = NULL; 754 if (mq->qstate == QCREATED) { 755 bzero(&mbx, sizeof (struct oce_mbx)); 756 fwcmd = (struct mbx_destroy_common_mq *)&mbx.payload; 757 fwcmd->params.req.id = mq->mq_id; 758 (void) oce_destroy_q(sc, &mbx, 759 sizeof (struct mbx_destroy_common_mq), 760 QTYPE_MQ); 761 } 762 mq->qstate = QDELETED; 763 } 764 765 if (mq->cq != NULL) { 766 oce_cq_del(sc, mq->cq); 767 mq->cq = NULL; 768 } 769 770 free(mq, M_DEVBUF); 771 mq = NULL; 772 } 773 774 775 776 /** 777 * @brief Function to delete a EQ, CQ, MQ, WQ or RQ 778 * @param sc sofware handle to the device 779 * @param mbx mailbox command to send to the fw to delete the queue 780 * (mbx contains the queue information to delete) 781 * @param req_size the size of the mbx payload dependent on the qtype 782 * @param qtype the type of queue i.e. EQ, CQ, MQ, WQ or RQ 783 * @returns 0 on success, failure otherwise 784 */ 785 static int 786 oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size, 787 enum qtype qtype) 788 { 789 struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload; 790 int opcode; 791 int subsys; 792 int rc = 0; 793 794 switch (qtype) { 795 case QTYPE_EQ: 796 opcode = OPCODE_COMMON_DESTROY_EQ; 797 subsys = MBX_SUBSYSTEM_COMMON; 798 break; 799 case QTYPE_CQ: 800 opcode = OPCODE_COMMON_DESTROY_CQ; 801 subsys = MBX_SUBSYSTEM_COMMON; 802 break; 803 case QTYPE_MQ: 804 opcode = OPCODE_COMMON_DESTROY_MQ; 805 subsys = MBX_SUBSYSTEM_COMMON; 806 break; 807 case QTYPE_WQ: 808 opcode = NIC_DELETE_WQ; 809 subsys = MBX_SUBSYSTEM_NIC; 810 break; 811 case QTYPE_RQ: 812 opcode = NIC_DELETE_RQ; 813 subsys = MBX_SUBSYSTEM_NIC; 814 break; 815 default: 816 return EINVAL; 817 } 818 819 mbx_common_req_hdr_init(hdr, 0, 0, subsys, 820 opcode, MBX_TIMEOUT_SEC, req_size, 821 OCE_MBX_VER_V0); 822 823 mbx->u0.s.embedded = 1; 824 mbx->payload_length = (uint32_t) req_size; 825 DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ); 826 827 rc = oce_mbox_post(sc, mbx, NULL); 828 829 if (rc != 0) 830 device_printf(sc->dev, "Failed to del q\n"); 831 832 return rc; 833 } 834 835 836 837 /** 838 * @brief Function to create a completion queue 839 * @param sc software handle to the device 840 * @param eq optional eq to be associated with to the cq 841 * @param q_len length of completion queue 842 * @param item_size size of completion queue items 843 * @param sol_event command context event 844 * @param is_eventable event table 845 * @param nodelay no delay flag 846 * @param ncoalesce no coalescence flag 847 * @returns pointer to the cq created, NULL on failure 848 */ 849 struct oce_cq * 850 oce_cq_create(POCE_SOFTC sc, struct oce_eq *eq, 851 uint32_t q_len, 852 uint32_t item_size, 853 uint32_t sol_event, 854 uint32_t is_eventable, 855 uint32_t nodelay, uint32_t ncoalesce) 856 { 857 struct oce_cq *cq = NULL; 858 int rc = 0; 859 860 cq = malloc(sizeof(struct oce_cq), M_DEVBUF, M_NOWAIT | M_ZERO); 861 if (!cq) 862 return NULL; 863 864 cq->ring = oce_create_ring_buffer(sc, q_len, item_size); 865 if (!cq->ring) 866 goto error; 867 868 cq->parent = sc; 869 cq->eq = eq; 870 cq->cq_cfg.q_len = q_len; 871 cq->cq_cfg.item_size = item_size; 872 cq->cq_cfg.nodelay = (uint8_t) nodelay; 873 874 rc = oce_mbox_cq_create(cq, ncoalesce, is_eventable); 875 if (rc) 876 goto error; 877 878 sc->cq[sc->ncqs++] = cq; 879 880 return cq; 881 882 error: 883 device_printf(sc->dev, "CQ create failed\n"); 884 oce_cq_del(sc, cq); 885 return NULL; 886 } 887 888 889 890 /** 891 * @brief Deletes the completion queue 892 * @param sc software handle to the device 893 * @param cq pointer to a completion queue 894 */ 895 static void 896 oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq) 897 { 898 struct oce_mbx mbx; 899 struct mbx_destroy_common_cq *fwcmd; 900 901 if (cq->ring != NULL) { 902 903 bzero(&mbx, sizeof(struct oce_mbx)); 904 /* now fill the command */ 905 fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload; 906 fwcmd->params.req.id = cq->cq_id; 907 (void)oce_destroy_q(sc, &mbx, 908 sizeof(struct mbx_destroy_common_cq), QTYPE_CQ); 909 /*NOW destroy the ring */ 910 oce_destroy_ring_buffer(sc, cq->ring); 911 cq->ring = NULL; 912 } 913 914 free(cq, M_DEVBUF); 915 cq = NULL; 916 } 917 918 919 920 /** 921 * @brief Start a receive queue 922 * @param rq pointer to a receive queue 923 */ 924 int 925 oce_start_rq(struct oce_rq *rq) 926 { 927 int rc; 928 929 rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len); 930 931 if (rc == 0) 932 oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE); 933 return rc; 934 } 935 936 937 938 /** 939 * @brief Start a work queue 940 * @param wq pointer to a work queue 941 */ 942 int 943 oce_start_wq(struct oce_wq *wq) 944 { 945 oce_arm_cq(wq->parent, wq->cq->cq_id, 0, TRUE); 946 return 0; 947 } 948 949 950 951 /** 952 * @brief Start a mailbox queue 953 * @param mq pointer to a mailbox queue 954 */ 955 int 956 oce_start_mq(struct oce_mq *mq) 957 { 958 oce_arm_cq(mq->parent, mq->cq->cq_id, 0, TRUE); 959 return 0; 960 } 961 962 963 964 /** 965 * @brief Function to arm an EQ so that it can generate events 966 * @param sc software handle to the device 967 * @param qid id of the EQ returned by the fw at the time of creation 968 * @param npopped number of EQEs to arm 969 * @param rearm rearm bit enable/disable 970 * @param clearint bit to clear the interrupt condition because of which 971 * EQEs are generated 972 */ 973 void 974 oce_arm_eq(POCE_SOFTC sc, 975 int16_t qid, int npopped, uint32_t rearm, uint32_t clearint) 976 { 977 eq_db_t eq_db = { 0 }; 978 979 eq_db.bits.rearm = rearm; 980 eq_db.bits.event = 1; 981 eq_db.bits.num_popped = npopped; 982 eq_db.bits.clrint = clearint; 983 eq_db.bits.qid = qid; 984 OCE_WRITE_REG32(sc, db, PD_EQ_DB, eq_db.dw0); 985 986 } 987 988 989 990 991 /** 992 * @brief Function to arm a CQ with CQEs 993 * @param sc software handle to the device 994 * @param qid id of the CQ returned by the fw at the time of creation 995 * @param npopped number of CQEs to arm 996 * @param rearm rearm bit enable/disable 997 */ 998 void oce_arm_cq(POCE_SOFTC sc, int16_t qid, int npopped, uint32_t rearm) 999 { 1000 cq_db_t cq_db = { 0 }; 1001 1002 cq_db.bits.rearm = rearm; 1003 cq_db.bits.num_popped = npopped; 1004 cq_db.bits.event = 0; 1005 cq_db.bits.qid = qid; 1006 OCE_WRITE_REG32(sc, db, PD_CQ_DB, cq_db.dw0); 1007 1008 } 1009 1010 1011 1012 1013 /* 1014 * @brief function to cleanup the eqs used during stop 1015 * @param eq pointer to event queue structure 1016 * @returns the number of EQs processed 1017 */ 1018 void 1019 oce_drain_eq(struct oce_eq *eq) 1020 { 1021 1022 struct oce_eqe *eqe; 1023 uint16_t num_eqe = 0; 1024 POCE_SOFTC sc = eq->parent; 1025 1026 do { 1027 eqe = RING_GET_CONSUMER_ITEM_VA(eq->ring, struct oce_eqe); 1028 if (eqe->evnt == 0) 1029 break; 1030 eqe->evnt = 0; 1031 bus_dmamap_sync(eq->ring->dma.tag, eq->ring->dma.map, 1032 BUS_DMASYNC_POSTWRITE); 1033 num_eqe++; 1034 RING_GET(eq->ring, 1); 1035 1036 } while (TRUE); 1037 1038 oce_arm_eq(sc, eq->eq_id, num_eqe, FALSE, TRUE); 1039 1040 } 1041 1042 1043 1044 void 1045 oce_drain_wq_cq(struct oce_wq *wq) 1046 { 1047 POCE_SOFTC sc = wq->parent; 1048 struct oce_cq *cq = wq->cq; 1049 struct oce_nic_tx_cqe *cqe; 1050 int num_cqes = 0; 1051 1052 bus_dmamap_sync(cq->ring->dma.tag, cq->ring->dma.map, 1053 BUS_DMASYNC_POSTWRITE); 1054 1055 do { 1056 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe); 1057 if (cqe->u0.dw[3] == 0) 1058 break; 1059 cqe->u0.dw[3] = 0; 1060 bus_dmamap_sync(cq->ring->dma.tag, cq->ring->dma.map, 1061 BUS_DMASYNC_POSTWRITE); 1062 RING_GET(cq->ring, 1); 1063 num_cqes++; 1064 1065 } while (TRUE); 1066 1067 oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); 1068 1069 } 1070 1071 1072 /* 1073 * @brief function to drain a MCQ and process its CQEs 1074 * @param dev software handle to the device 1075 * @param cq pointer to the cq to drain 1076 * @returns the number of CQEs processed 1077 */ 1078 void 1079 oce_drain_mq_cq(void *arg) 1080 { 1081 /* TODO: additional code. */ 1082 return; 1083 } 1084 1085 1086 1087 /** 1088 * @brief function to process a Recieve queue 1089 * @param arg pointer to the RQ to charge 1090 * @return number of cqes processed 1091 */ 1092 void 1093 oce_drain_rq_cq(struct oce_rq *rq) 1094 { 1095 struct oce_nic_rx_cqe *cqe; 1096 uint16_t num_cqe = 0; 1097 struct oce_cq *cq; 1098 POCE_SOFTC sc; 1099 1100 sc = rq->parent; 1101 cq = rq->cq; 1102 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe); 1103 /* dequeue till you reach an invalid cqe */ 1104 while (RQ_CQE_VALID(cqe)) { 1105 RQ_CQE_INVALIDATE(cqe); 1106 RING_GET(cq->ring, 1); 1107 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, 1108 struct oce_nic_rx_cqe); 1109 num_cqe++; 1110 } 1111 oce_arm_cq(sc, cq->cq_id, num_cqe, FALSE); 1112 1113 return; 1114 } 1115 1116 1117 void 1118 oce_free_posted_rxbuf(struct oce_rq *rq) 1119 { 1120 struct oce_packet_desc *pd; 1121 1122 while (rq->pending) { 1123 1124 pd = &rq->pckts[rq->packets_out]; 1125 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); 1126 bus_dmamap_unload(rq->tag, pd->map); 1127 if (pd->mbuf != NULL) { 1128 m_freem(pd->mbuf); 1129 pd->mbuf = NULL; 1130 } 1131 1132 if ((rq->packets_out + 1) == OCE_RQ_PACKET_ARRAY_SIZE) 1133 rq->packets_out = 0; 1134 else 1135 rq->packets_out++; 1136 1137 rq->pending--; 1138 } 1139 1140 } 1141 1142 void 1143 oce_stop_rx(POCE_SOFTC sc) 1144 { 1145 struct oce_mbx mbx; 1146 struct mbx_delete_nic_rq *fwcmd; 1147 struct oce_rq *rq; 1148 int i = 0; 1149 1150 for_all_rq_queues(sc, rq, i) { 1151 if (rq->qstate == QCREATED) { 1152 /* Delete rxq in firmware */ 1153 1154 bzero(&mbx, sizeof(mbx)); 1155 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 1156 fwcmd->params.req.rq_id = rq->rq_id; 1157 1158 (void)oce_destroy_q(sc, &mbx, 1159 sizeof(struct mbx_delete_nic_rq), QTYPE_RQ); 1160 1161 rq->qstate = QDELETED; 1162 1163 DELAY(1); 1164 1165 /* Free posted RX buffers that are not used */ 1166 oce_free_posted_rxbuf(rq); 1167 1168 } 1169 } 1170 } 1171 1172 1173 1174 int 1175 oce_start_rx(POCE_SOFTC sc) 1176 { 1177 struct oce_rq *rq; 1178 int rc = 0, i; 1179 1180 for_all_rq_queues(sc, rq, i) { 1181 if (rq->qstate == QCREATED) 1182 continue; 1183 rc = oce_mbox_create_rq(rq); 1184 if (rc) 1185 goto error; 1186 /* reset queue pointers */ 1187 rq->qstate = QCREATED; 1188 rq->pending = 0; 1189 rq->ring->cidx = 0; 1190 rq->ring->pidx = 0; 1191 rq->packets_in = 0; 1192 rq->packets_out = 0; 1193 } 1194 1195 DELAY(1); 1196 1197 /* RSS config */ 1198 if (sc->rss_enable) { 1199 rc = oce_config_nic_rss(sc, (uint8_t) sc->if_id, RSS_ENABLE); 1200 if (rc) 1201 goto error; 1202 1203 } 1204 1205 return rc; 1206 error: 1207 device_printf(sc->dev, "Start RX failed\n"); 1208 return rc; 1209 1210 } 1211 1212 1213 1214