oce_queue.c (331722) | oce_queue.c (338938) |
---|---|
1/*- 2 * Copyright (C) 2013 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, --- 22 unchanged lines hidden (view full) --- 31 * Contact Information: 32 * freebsd-drivers@emulex.com 33 * 34 * Emulex 35 * 3333 Susan Street 36 * Costa Mesa, CA 92626 37 */ 38 | 1/*- 2 * Copyright (C) 2013 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, --- 22 unchanged lines hidden (view full) --- 31 * Contact Information: 32 * freebsd-drivers@emulex.com 33 * 34 * Emulex 35 * 3333 Susan Street 36 * Costa Mesa, CA 92626 37 */ 38 |
39/* $FreeBSD: stable/11/sys/dev/oce/oce_queue.c 331722 2018-03-29 02:50:57Z eadler $ */ | 39/* $FreeBSD: stable/11/sys/dev/oce/oce_queue.c 338938 2018-09-25 23:48:43Z jpaetzel $ */ |
40 41#include "oce_if.h" 42 43/***************************************************** 44 * local queue functions 45 *****************************************************/ 46 47static struct oce_wq *oce_wq_init(POCE_SOFTC sc, --- 13 unchanged lines hidden (view full) --- 61 uint32_t item_size, 62 uint32_t eq_delay, 63 uint32_t vector); 64static void oce_eq_del(struct oce_eq *eq); 65static struct oce_mq *oce_mq_create(POCE_SOFTC sc, 66 struct oce_eq *eq, uint32_t q_len); 67static void oce_mq_free(struct oce_mq *mq); 68static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx | 40 41#include "oce_if.h" 42 43/***************************************************** 44 * local queue functions 45 *****************************************************/ 46 47static struct oce_wq *oce_wq_init(POCE_SOFTC sc, --- 13 unchanged lines hidden (view full) --- 61 uint32_t item_size, 62 uint32_t eq_delay, 63 uint32_t vector); 64static void oce_eq_del(struct oce_eq *eq); 65static struct oce_mq *oce_mq_create(POCE_SOFTC sc, 66 struct oce_eq *eq, uint32_t q_len); 67static void oce_mq_free(struct oce_mq *mq); 68static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx |
69 *mbx, size_t req_size, enum qtype qtype); | 69 *mbx, size_t req_size, enum qtype qtype, int version); |
70struct oce_cq *oce_cq_create(POCE_SOFTC sc, 71 struct oce_eq *eq, 72 uint32_t q_len, 73 uint32_t item_size, 74 uint32_t sol_event, 75 uint32_t is_eventable, 76 uint32_t nodelay, uint32_t ncoalesce); 77static void oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq); --- 37 unchanged lines hidden (view full) --- 115 /* create all of the event queues */ 116 for (vector = 0; vector < sc->intr_count; vector++) { 117 /* setup aic defaults for each event queue */ 118 aic = &sc->aic_obj[vector]; 119 aic->max_eqd = OCE_MAX_EQD; 120 aic->min_eqd = OCE_MIN_EQD; 121 aic->et_eqd = OCE_MIN_EQD; 122 aic->enable = TRUE; | 70struct oce_cq *oce_cq_create(POCE_SOFTC sc, 71 struct oce_eq *eq, 72 uint32_t q_len, 73 uint32_t item_size, 74 uint32_t sol_event, 75 uint32_t is_eventable, 76 uint32_t nodelay, uint32_t ncoalesce); 77static void oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq); --- 37 unchanged lines hidden (view full) --- 115 /* create all of the event queues */ 116 for (vector = 0; vector < sc->intr_count; vector++) { 117 /* setup aic defaults for each event queue */ 118 aic = &sc->aic_obj[vector]; 119 aic->max_eqd = OCE_MAX_EQD; 120 aic->min_eqd = OCE_MIN_EQD; 121 aic->et_eqd = OCE_MIN_EQD; 122 aic->enable = TRUE; |
123 124 sc->eq[vector] = oce_eq_create(sc, sc->enable_hwlro ? EQ_LEN_2048 : EQ_LEN_1024, 125 EQE_SIZE_4,0, vector); |
|
123 | 126 |
124 sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4, 125 0, vector); | |
126 if (!sc->eq[vector]) 127 goto error; 128 } 129 130 /* create Tx, Rx and mcc queues */ 131 for_all_wq_queues(sc, wq, i) { 132 rc = oce_wq_create(wq, sc->eq[i]); 133 if (rc) --- 30 unchanged lines hidden (view full) --- 164void 165oce_queue_release_all(POCE_SOFTC sc) 166{ 167 int i = 0; 168 struct oce_wq *wq; 169 struct oce_rq *rq; 170 struct oce_eq *eq; 171 | 127 if (!sc->eq[vector]) 128 goto error; 129 } 130 131 /* create Tx, Rx and mcc queues */ 132 for_all_wq_queues(sc, wq, i) { 133 rc = oce_wq_create(wq, sc->eq[i]); 134 if (rc) --- 30 unchanged lines hidden (view full) --- 165void 166oce_queue_release_all(POCE_SOFTC sc) 167{ 168 int i = 0; 169 struct oce_wq *wq; 170 struct oce_rq *rq; 171 struct oce_eq *eq; 172 |
173 /* before deleting lro queues, we have to disable hwlro */ 174 if(sc->enable_hwlro) 175 oce_mbox_nic_set_iface_lro_config(sc, 0); 176 |
|
172 for_all_rq_queues(sc, rq, i) { 173 if (rq) { 174 oce_rq_del(sc->rq[i]); 175 oce_rq_free(sc->rq[i]); 176 } 177 } 178 179 for_all_wq_queues(sc, wq, i) { --- 69 unchanged lines hidden (view full) --- 249 } 250 251 wq->ring = oce_create_ring_buffer(sc, q_len, NIC_WQE_SIZE); 252 if (!wq->ring) 253 goto free_wq; 254 255 256 LOCK_CREATE(&wq->tx_lock, "TX_lock"); | 177 for_all_rq_queues(sc, rq, i) { 178 if (rq) { 179 oce_rq_del(sc->rq[i]); 180 oce_rq_free(sc->rq[i]); 181 } 182 } 183 184 for_all_wq_queues(sc, wq, i) { --- 69 unchanged lines hidden (view full) --- 254 } 255 256 wq->ring = oce_create_ring_buffer(sc, q_len, NIC_WQE_SIZE); 257 if (!wq->ring) 258 goto free_wq; 259 260 261 LOCK_CREATE(&wq->tx_lock, "TX_lock"); |
262 LOCK_CREATE(&wq->tx_compl_lock, "WQ_HANDLER_LOCK"); |
|
257 258#if __FreeBSD_version >= 800000 259 /* Allocate buf ring for multiqueue*/ 260 wq->br = buf_ring_alloc(4096, M_DEVBUF, 261 M_WAITOK, &wq->tx_lock.mutex); 262 if (!wq->br) 263 goto free_wq; 264#endif --- 34 unchanged lines hidden (view full) --- 299 } 300 301 if (wq->tag != NULL) 302 bus_dma_tag_destroy(wq->tag); 303 if (wq->br != NULL) 304 buf_ring_free(wq->br, M_DEVBUF); 305 306 LOCK_DESTROY(&wq->tx_lock); | 263 264#if __FreeBSD_version >= 800000 265 /* Allocate buf ring for multiqueue*/ 266 wq->br = buf_ring_alloc(4096, M_DEVBUF, 267 M_WAITOK, &wq->tx_lock.mutex); 268 if (!wq->br) 269 goto free_wq; 270#endif --- 34 unchanged lines hidden (view full) --- 305 } 306 307 if (wq->tag != NULL) 308 bus_dma_tag_destroy(wq->tag); 309 if (wq->br != NULL) 310 buf_ring_free(wq->br, M_DEVBUF); 311 312 LOCK_DESTROY(&wq->tx_lock); |
313 LOCK_DESTROY(&wq->tx_compl_lock); |
|
307 free(wq, M_DEVBUF); 308} 309 310 311 312/** 313 * @brief Create a work queue 314 * @param wq pointer to work queue --- 54 unchanged lines hidden (view full) --- 369 POCE_SOFTC sc = (POCE_SOFTC) wq->parent; 370 371 if (wq->qstate == QCREATED) { 372 bzero(&mbx, sizeof(struct oce_mbx)); 373 /* now fill the command */ 374 fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload; 375 fwcmd->params.req.wq_id = wq->wq_id; 376 (void)oce_destroy_q(sc, &mbx, | 314 free(wq, M_DEVBUF); 315} 316 317 318 319/** 320 * @brief Create a work queue 321 * @param wq pointer to work queue --- 54 unchanged lines hidden (view full) --- 376 POCE_SOFTC sc = (POCE_SOFTC) wq->parent; 377 378 if (wq->qstate == QCREATED) { 379 bzero(&mbx, sizeof(struct oce_mbx)); 380 /* now fill the command */ 381 fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload; 382 fwcmd->params.req.wq_id = wq->wq_id; 383 (void)oce_destroy_q(sc, &mbx, |
377 sizeof(struct mbx_delete_nic_wq), QTYPE_WQ); | 384 sizeof(struct mbx_delete_nic_wq), QTYPE_WQ, 0); |
378 wq->qstate = QDELETED; 379 } 380 381 if (wq->cq != NULL) { 382 oce_cq_del(sc, wq->cq); 383 wq->cq = NULL; 384 } 385} --- 31 unchanged lines hidden (view full) --- 417 418 419 rq->cfg.q_len = q_len; 420 rq->cfg.frag_size = frag_size; 421 rq->cfg.mtu = mtu; 422 rq->cfg.eqd = 0; 423 rq->lro_pkts_queued = 0; 424 rq->cfg.is_rss_queue = rss; | 385 wq->qstate = QDELETED; 386 } 387 388 if (wq->cq != NULL) { 389 oce_cq_del(sc, wq->cq); 390 wq->cq = NULL; 391 } 392} --- 31 unchanged lines hidden (view full) --- 424 425 426 rq->cfg.q_len = q_len; 427 rq->cfg.frag_size = frag_size; 428 rq->cfg.mtu = mtu; 429 rq->cfg.eqd = 0; 430 rq->lro_pkts_queued = 0; 431 rq->cfg.is_rss_queue = rss; |
425 rq->packets_in = 0; 426 rq->packets_out = 0; | |
427 rq->pending = 0; 428 429 rq->parent = (void *)sc; 430 431 rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev), | 432 rq->pending = 0; 433 434 rq->parent = (void *)sc; 435 436 rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev), |
432 1, 0, 433 BUS_SPACE_MAXADDR, 434 BUS_SPACE_MAXADDR, 435 NULL, NULL, 436 OCE_MAX_RX_SIZE, 437 1, PAGE_SIZE, 0, NULL, NULL, &rq->tag); 438 | 437 1, 0, 438 BUS_SPACE_MAXADDR, 439 BUS_SPACE_MAXADDR, 440 NULL, NULL, 441 oce_rq_buf_size, 442 1, oce_rq_buf_size, 0, NULL, NULL, &rq->tag); |
439 if (rc) 440 goto free_rq; 441 442 for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) { 443 rc = bus_dmamap_create(rq->tag, 0, &rq->pckts[i].map); 444 if (rc) 445 goto free_rq; 446 } --- 60 unchanged lines hidden (view full) --- 507 * @param eq pointer to event queue 508 */ 509static int 510oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq) 511{ 512 POCE_SOFTC sc = rq->parent; 513 struct oce_cq *cq; 514 | 443 if (rc) 444 goto free_rq; 445 446 for (i = 0; i < OCE_RQ_PACKET_ARRAY_SIZE; i++) { 447 rc = bus_dmamap_create(rq->tag, 0, &rq->pckts[i].map); 448 if (rc) 449 goto free_rq; 450 } --- 60 unchanged lines hidden (view full) --- 511 * @param eq pointer to event queue 512 */ 513static int 514oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq) 515{ 516 POCE_SOFTC sc = rq->parent; 517 struct oce_cq *cq; 518 |
515 cq = oce_cq_create(sc, 516 eq, 517 CQ_LEN_1024, 518 sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3); | 519 cq = oce_cq_create(sc, eq, 520 sc->enable_hwlro ? CQ_LEN_2048 : CQ_LEN_1024, 521 sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3); 522 |
519 if (!cq) 520 return ENXIO; 521 522 rq->cq = cq; 523 rq->cfg.if_id = if_id; 524 525 /* Dont create RQ here. Create in if_activate */ 526 rq->qstate = 0; --- 16 unchanged lines hidden (view full) --- 543 * @param rq receive queue 544 */ 545static void 546oce_rq_del(struct oce_rq *rq) 547{ 548 POCE_SOFTC sc = (POCE_SOFTC) rq->parent; 549 struct oce_mbx mbx; 550 struct mbx_delete_nic_rq *fwcmd; | 523 if (!cq) 524 return ENXIO; 525 526 rq->cq = cq; 527 rq->cfg.if_id = if_id; 528 529 /* Dont create RQ here. Create in if_activate */ 530 rq->qstate = 0; --- 16 unchanged lines hidden (view full) --- 547 * @param rq receive queue 548 */ 549static void 550oce_rq_del(struct oce_rq *rq) 551{ 552 POCE_SOFTC sc = (POCE_SOFTC) rq->parent; 553 struct oce_mbx mbx; 554 struct mbx_delete_nic_rq *fwcmd; |
555 struct mbx_delete_nic_rq_v1 *fwcmd1; |
|
551 552 if (rq->qstate == QCREATED) { 553 bzero(&mbx, sizeof(mbx)); | 556 557 if (rq->qstate == QCREATED) { 558 bzero(&mbx, sizeof(mbx)); |
554 555 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 556 fwcmd->params.req.rq_id = rq->rq_id; 557 (void)oce_destroy_q(sc, &mbx, 558 sizeof(struct mbx_delete_nic_rq), QTYPE_RQ); | 559 if(!rq->islro) { 560 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 561 fwcmd->params.req.rq_id = rq->rq_id; 562 (void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq), QTYPE_RQ, 0); 563 }else { 564 fwcmd1 = (struct mbx_delete_nic_rq_v1 *)&mbx.payload; 565 fwcmd1->params.req.rq_id = rq->rq_id; 566 fwcmd1->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO); 567 (void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq_v1), QTYPE_RQ, 1); 568 } |
559 rq->qstate = QDELETED; 560 } 561 562 if (rq->cq != NULL) { 563 oce_cq_del(sc, rq->cq); 564 rq->cq = NULL; 565 } 566} --- 60 unchanged lines hidden (view full) --- 627 struct mbx_destroy_common_eq *fwcmd; 628 POCE_SOFTC sc = (POCE_SOFTC) eq->parent; 629 630 if (eq->eq_id != 0xffff) { 631 bzero(&mbx, sizeof(mbx)); 632 fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload; 633 fwcmd->params.req.id = eq->eq_id; 634 (void)oce_destroy_q(sc, &mbx, | 569 rq->qstate = QDELETED; 570 } 571 572 if (rq->cq != NULL) { 573 oce_cq_del(sc, rq->cq); 574 rq->cq = NULL; 575 } 576} --- 60 unchanged lines hidden (view full) --- 637 struct mbx_destroy_common_eq *fwcmd; 638 POCE_SOFTC sc = (POCE_SOFTC) eq->parent; 639 640 if (eq->eq_id != 0xffff) { 641 bzero(&mbx, sizeof(mbx)); 642 fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload; 643 fwcmd->params.req.id = eq->eq_id; 644 (void)oce_destroy_q(sc, &mbx, |
635 sizeof(struct mbx_destroy_common_eq), QTYPE_EQ); | 645 sizeof(struct mbx_destroy_common_eq), QTYPE_EQ, 0); |
636 } 637 638 if (eq->ring != NULL) { 639 oce_destroy_ring_buffer(sc, eq->ring); 640 eq->ring = NULL; 641 } 642 643 free(eq, M_DEVBUF); --- 134 unchanged lines hidden (view full) --- 778 oce_destroy_ring_buffer(sc, mq->ring); 779 mq->ring = NULL; 780 if (mq->qstate == QCREATED) { 781 bzero(&mbx, sizeof (struct oce_mbx)); 782 fwcmd = (struct mbx_destroy_common_mq *)&mbx.payload; 783 fwcmd->params.req.id = mq->mq_id; 784 (void) oce_destroy_q(sc, &mbx, 785 sizeof (struct mbx_destroy_common_mq), | 646 } 647 648 if (eq->ring != NULL) { 649 oce_destroy_ring_buffer(sc, eq->ring); 650 eq->ring = NULL; 651 } 652 653 free(eq, M_DEVBUF); --- 134 unchanged lines hidden (view full) --- 788 oce_destroy_ring_buffer(sc, mq->ring); 789 mq->ring = NULL; 790 if (mq->qstate == QCREATED) { 791 bzero(&mbx, sizeof (struct oce_mbx)); 792 fwcmd = (struct mbx_destroy_common_mq *)&mbx.payload; 793 fwcmd->params.req.id = mq->mq_id; 794 (void) oce_destroy_q(sc, &mbx, 795 sizeof (struct mbx_destroy_common_mq), |
786 QTYPE_MQ); | 796 QTYPE_MQ, 0); |
787 } 788 mq->qstate = QDELETED; 789 } 790 791 if (mq->cq != NULL) { 792 oce_cq_del(sc, mq->cq); 793 mq->cq = NULL; 794 } --- 10 unchanged lines hidden (view full) --- 805 * @param mbx mailbox command to send to the fw to delete the queue 806 * (mbx contains the queue information to delete) 807 * @param req_size the size of the mbx payload dependent on the qtype 808 * @param qtype the type of queue i.e. EQ, CQ, MQ, WQ or RQ 809 * @returns 0 on success, failure otherwise 810 */ 811static int 812oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size, | 797 } 798 mq->qstate = QDELETED; 799 } 800 801 if (mq->cq != NULL) { 802 oce_cq_del(sc, mq->cq); 803 mq->cq = NULL; 804 } --- 10 unchanged lines hidden (view full) --- 815 * @param mbx mailbox command to send to the fw to delete the queue 816 * (mbx contains the queue information to delete) 817 * @param req_size the size of the mbx payload dependent on the qtype 818 * @param qtype the type of queue i.e. EQ, CQ, MQ, WQ or RQ 819 * @returns 0 on success, failure otherwise 820 */ 821static int 822oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size, |
813 enum qtype qtype) | 823 enum qtype qtype, int version) |
814{ 815 struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload; 816 int opcode; 817 int subsys; 818 int rc = 0; 819 820 switch (qtype) { 821 case QTYPE_EQ: --- 17 unchanged lines hidden (view full) --- 839 subsys = MBX_SUBSYSTEM_NIC; 840 break; 841 default: 842 return EINVAL; 843 } 844 845 mbx_common_req_hdr_init(hdr, 0, 0, subsys, 846 opcode, MBX_TIMEOUT_SEC, req_size, | 824{ 825 struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload; 826 int opcode; 827 int subsys; 828 int rc = 0; 829 830 switch (qtype) { 831 case QTYPE_EQ: --- 17 unchanged lines hidden (view full) --- 849 subsys = MBX_SUBSYSTEM_NIC; 850 break; 851 default: 852 return EINVAL; 853 } 854 855 mbx_common_req_hdr_init(hdr, 0, 0, subsys, 856 opcode, MBX_TIMEOUT_SEC, req_size, |
847 OCE_MBX_VER_V0); | 857 version); |
848 849 mbx->u0.s.embedded = 1; 850 mbx->payload_length = (uint32_t) req_size; 851 DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ); 852 853 rc = oce_mbox_post(sc, mbx, NULL); 854 if (!rc) 855 rc = hdr->u0.rsp.status; --- 71 unchanged lines hidden (view full) --- 927 928 if (cq->ring != NULL) { 929 930 bzero(&mbx, sizeof(struct oce_mbx)); 931 /* now fill the command */ 932 fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload; 933 fwcmd->params.req.id = cq->cq_id; 934 (void)oce_destroy_q(sc, &mbx, | 858 859 mbx->u0.s.embedded = 1; 860 mbx->payload_length = (uint32_t) req_size; 861 DW_SWAP(u32ptr(mbx), mbx->payload_length + OCE_BMBX_RHDR_SZ); 862 863 rc = oce_mbox_post(sc, mbx, NULL); 864 if (!rc) 865 rc = hdr->u0.rsp.status; --- 71 unchanged lines hidden (view full) --- 937 938 if (cq->ring != NULL) { 939 940 bzero(&mbx, sizeof(struct oce_mbx)); 941 /* now fill the command */ 942 fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload; 943 fwcmd->params.req.id = cq->cq_id; 944 (void)oce_destroy_q(sc, &mbx, |
935 sizeof(struct mbx_destroy_common_cq), QTYPE_CQ); | 945 sizeof(struct mbx_destroy_common_cq), QTYPE_CQ, 0); |
936 /*NOW destroy the ring */ 937 oce_destroy_ring_buffer(sc, cq->ring); 938 cq->ring = NULL; 939 } 940 941 free(cq, M_DEVBUF); 942 cq = NULL; 943} 944 945 946 947/** 948 * @brief Start a receive queue 949 * @param rq pointer to a receive queue 950 */ 951int 952oce_start_rq(struct oce_rq *rq) 953{ | 946 /*NOW destroy the ring */ 947 oce_destroy_ring_buffer(sc, cq->ring); 948 cq->ring = NULL; 949 } 950 951 free(cq, M_DEVBUF); 952 cq = NULL; 953} 954 955 956 957/** 958 * @brief Start a receive queue 959 * @param rq pointer to a receive queue 960 */ 961int 962oce_start_rq(struct oce_rq *rq) 963{ |
964 POCE_SOFTC sc = (POCE_SOFTC) rq->parent; |
|
954 int rc; 955 | 965 int rc; 966 |
956 rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len); | 967 if(sc->enable_hwlro) 968 rc = oce_alloc_rx_bufs(rq, 960); 969 else 970 rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len - 1); |
957 958 if (rc == 0) 959 oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE); | 971 972 if (rc == 0) 973 oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE); |
974 |
|
960 return rc; 961} 962 963 964 965/** 966 * @brief Start a work queue 967 * @param wq pointer to a work queue --- 175 unchanged lines hidden (view full) --- 1143 1144void 1145oce_free_posted_rxbuf(struct oce_rq *rq) 1146{ 1147 struct oce_packet_desc *pd; 1148 1149 while (rq->pending) { 1150 | 975 return rc; 976} 977 978 979 980/** 981 * @brief Start a work queue 982 * @param wq pointer to a work queue --- 175 unchanged lines hidden (view full) --- 1158 1159void 1160oce_free_posted_rxbuf(struct oce_rq *rq) 1161{ 1162 struct oce_packet_desc *pd; 1163 1164 while (rq->pending) { 1165 |
1151 pd = &rq->pckts[rq->packets_out]; | 1166 pd = &rq->pckts[rq->ring->cidx]; |
1152 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); 1153 bus_dmamap_unload(rq->tag, pd->map); 1154 if (pd->mbuf != NULL) { 1155 m_freem(pd->mbuf); 1156 pd->mbuf = NULL; 1157 } 1158 | 1167 bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); 1168 bus_dmamap_unload(rq->tag, pd->map); 1169 if (pd->mbuf != NULL) { 1170 m_freem(pd->mbuf); 1171 pd->mbuf = NULL; 1172 } 1173 |
1159 if ((rq->packets_out + 1) == OCE_RQ_PACKET_ARRAY_SIZE) 1160 rq->packets_out = 0; 1161 else 1162 rq->packets_out++; 1163 | 1174 RING_GET(rq->ring,1); |
1164 rq->pending--; 1165 } 1166 1167} 1168 1169void | 1175 rq->pending--; 1176 } 1177 1178} 1179 1180void |
1170oce_stop_rx(POCE_SOFTC sc) | 1181oce_rx_cq_clean_hwlro(struct oce_rq *rq) |
1171{ | 1182{ |
1172 struct oce_mbx mbx; 1173 struct mbx_delete_nic_rq *fwcmd; 1174 struct oce_rq *rq; 1175 int i = 0; | 1183 struct oce_cq *cq = rq->cq; 1184 POCE_SOFTC sc = rq->parent; 1185 struct nic_hwlro_singleton_cqe *cqe; 1186 struct nic_hwlro_cqe_part2 *cqe2; 1187 int flush_wait = 0; 1188 int flush_compl = 0; 1189 int num_frags = 0; |
1176 | 1190 |
1177 for_all_rq_queues(sc, rq, i) { 1178 if (rq->qstate == QCREATED) { 1179 /* Delete rxq in firmware */ | 1191 for (;;) { 1192 bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); 1193 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe); 1194 if(cqe->valid) { 1195 if(cqe->cqe_type == 0) { /* singleton cqe */ 1196 /* we should not get singleton cqe after cqe1 on same rq */ 1197 if(rq->cqe_firstpart != NULL) { 1198 device_printf(sc->dev, "Got singleton cqe after cqe1 \n"); 1199 goto exit_rx_cq_clean_hwlro; 1200 } 1201 num_frags = cqe->pkt_size / rq->cfg.frag_size; 1202 if(cqe->pkt_size % rq->cfg.frag_size) 1203 num_frags++; 1204 oce_discard_rx_comp(rq, num_frags); 1205 /* Check if CQE is flush completion */ 1206 if(!cqe->pkt_size) 1207 flush_compl = 1; 1208 cqe->valid = 0; 1209 RING_GET(cq->ring, 1); 1210 }else if(cqe->cqe_type == 0x1) { /* first part */ 1211 /* we should not get cqe1 after cqe1 on same rq */ 1212 if(rq->cqe_firstpart != NULL) { 1213 device_printf(sc->dev, "Got cqe1 after cqe1 \n"); 1214 goto exit_rx_cq_clean_hwlro; 1215 } 1216 rq->cqe_firstpart = (struct nic_hwlro_cqe_part1 *)cqe; 1217 RING_GET(cq->ring, 1); 1218 }else if(cqe->cqe_type == 0x2) { /* second part */ 1219 cqe2 = (struct nic_hwlro_cqe_part2 *)cqe; 1220 /* We should not get cqe2 without cqe1 */ 1221 if(rq->cqe_firstpart == NULL) { 1222 device_printf(sc->dev, "Got cqe2 without cqe1 \n"); 1223 goto exit_rx_cq_clean_hwlro; 1224 } 1225 num_frags = cqe2->coalesced_size / rq->cfg.frag_size; 1226 if(cqe2->coalesced_size % rq->cfg.frag_size) 1227 num_frags++; 1228 1229 /* Flush completion will always come in singleton CQE */ 1230 oce_discard_rx_comp(rq, num_frags); |
1180 | 1231 |
1181 bzero(&mbx, sizeof(mbx)); 1182 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 1183 fwcmd->params.req.rq_id = rq->rq_id; | 1232 rq->cqe_firstpart->valid = 0; 1233 cqe2->valid = 0; 1234 rq->cqe_firstpart = NULL; 1235 RING_GET(cq->ring, 1); 1236 } 1237 oce_arm_cq(sc, cq->cq_id, 1, FALSE); 1238 if(flush_compl) 1239 break; 1240 }else { 1241 if (flush_wait++ > 100) { 1242 device_printf(sc->dev, "did not receive hwlro flush compl\n"); 1243 break; 1244 } 1245 oce_arm_cq(sc, cq->cq_id, 0, TRUE); 1246 DELAY(1000); 1247 } 1248 } |
1184 | 1249 |
1185 (void)oce_destroy_q(sc, &mbx, 1186 sizeof(struct mbx_delete_nic_rq), QTYPE_RQ); | 1250 /* After cleanup, leave the CQ in unarmed state */ 1251 oce_arm_cq(sc, cq->cq_id, 0, FALSE); |
1187 | 1252 |
1188 rq->qstate = QDELETED; | 1253exit_rx_cq_clean_hwlro: 1254 return; 1255} |
1189 | 1256 |
1190 DELAY(1); | |
1191 | 1257 |
1192 /* Free posted RX buffers that are not used */ 1193 oce_free_posted_rxbuf(rq); | 1258void 1259oce_rx_cq_clean(struct oce_rq *rq) 1260{ 1261 struct oce_nic_rx_cqe *cqe; 1262 struct oce_cq *cq; 1263 POCE_SOFTC sc; 1264 int flush_wait = 0; 1265 int flush_compl = 0; 1266 sc = rq->parent; 1267 cq = rq->cq; 1268 1269 for (;;) { 1270 bus_dmamap_sync(cq->ring->dma.tag, 1271 cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); 1272 cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe); 1273 if(RQ_CQE_VALID(cqe)) { 1274 DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe)); 1275 oce_discard_rx_comp(rq, cqe->u0.s.num_fragments); 1276 /* Check if CQE is flush completion */ 1277 if((cqe->u0.s.num_fragments==0)&&(cqe->u0.s.pkt_size == 0)&&(cqe->u0.s.error == 0)) 1278 flush_compl = 1; 1279 1280 RQ_CQE_INVALIDATE(cqe); 1281 RING_GET(cq->ring, 1); 1282#if defined(INET6) || defined(INET) 1283 if (IF_LRO_ENABLED(sc)) 1284 oce_rx_flush_lro(rq); 1285#endif 1286 oce_arm_cq(sc, cq->cq_id, 1, FALSE); 1287 if(flush_compl) 1288 break; 1289 }else { 1290 if (flush_wait++ > 100) { 1291 device_printf(sc->dev, "did not receive flush compl\n"); 1292 break; 1293 } 1294 oce_arm_cq(sc, cq->cq_id, 0, TRUE); 1295 DELAY(1000); 1296 } 1297 } 1298 1299 /* After cleanup, leave the CQ in unarmed state */ 1300 oce_arm_cq(sc, cq->cq_id, 0, FALSE); 1301} 1302 1303void 1304oce_stop_rx(POCE_SOFTC sc) 1305{ 1306 struct oce_mbx mbx; 1307 struct mbx_delete_nic_rq *fwcmd; 1308 struct mbx_delete_nic_rq_v1 *fwcmd1; 1309 struct oce_rq *rq; 1310 int i = 0; 1311 1312 /* before deleting disable hwlro */ 1313 if(sc->enable_hwlro) 1314 oce_mbox_nic_set_iface_lro_config(sc, 0); 1315 1316 for_all_rq_queues(sc, rq, i) { 1317 if (rq->qstate == QCREATED) { 1318 /* Delete rxq in firmware */ 1319 LOCK(&rq->rx_lock); 1320 1321 bzero(&mbx, sizeof(mbx)); 1322 if(!rq->islro) { 1323 fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; 1324 fwcmd->params.req.rq_id = rq->rq_id; 1325 (void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq), QTYPE_RQ, 0); 1326 }else { 1327 fwcmd1 = (struct mbx_delete_nic_rq_v1 *)&mbx.payload; 1328 fwcmd1->params.req.rq_id = rq->rq_id; 1329 fwcmd1->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO); 1330 1331 (void)oce_destroy_q(sc,&mbx,sizeof(struct mbx_delete_nic_rq_v1),QTYPE_RQ,1); 1332 } 1333 rq->qstate = QDELETED; 1334 1335 DELAY(1000); |
1194 | 1336 |
1195 } 1196 } | 1337 if(!rq->islro) 1338 oce_rx_cq_clean(rq); 1339 else 1340 oce_rx_cq_clean_hwlro(rq); 1341 1342 /* Free posted RX buffers that are not used */ 1343 oce_free_posted_rxbuf(rq); 1344 UNLOCK(&rq->rx_lock); 1345 } 1346 } |
1197} 1198 1199 1200 1201int 1202oce_start_rx(POCE_SOFTC sc) 1203{ 1204 struct oce_rq *rq; 1205 int rc = 0, i; 1206 1207 for_all_rq_queues(sc, rq, i) { 1208 if (rq->qstate == QCREATED) 1209 continue; | 1347} 1348 1349 1350 1351int 1352oce_start_rx(POCE_SOFTC sc) 1353{ 1354 struct oce_rq *rq; 1355 int rc = 0, i; 1356 1357 for_all_rq_queues(sc, rq, i) { 1358 if (rq->qstate == QCREATED) 1359 continue; |
1210 rc = oce_mbox_create_rq(rq); | 1360 if((i == 0) || (!sc->enable_hwlro)) { 1361 rc = oce_mbox_create_rq(rq); 1362 if (rc) 1363 goto error; 1364 rq->islro = 0; 1365 }else { 1366 rc = oce_mbox_create_rq_v2(rq); 1367 if (rc) 1368 goto error; 1369 rq->islro = 1; 1370 } 1371 /* reset queue pointers */ 1372 rq->qstate = QCREATED; 1373 rq->pending = 0; 1374 rq->ring->cidx = 0; 1375 rq->ring->pidx = 0; 1376 } 1377 1378 if(sc->enable_hwlro) { 1379 rc = oce_mbox_nic_set_iface_lro_config(sc, 1); |
1211 if (rc) 1212 goto error; | 1380 if (rc) 1381 goto error; |
1213 /* reset queue pointers */ 1214 rq->qstate = QCREATED; 1215 rq->pending = 0; 1216 rq->ring->cidx = 0; 1217 rq->ring->pidx = 0; 1218 rq->packets_in = 0; 1219 rq->packets_out = 0; | |
1220 } 1221 1222 DELAY(1); 1223 1224 /* RSS config */ 1225 if (is_rss_enabled(sc)) { 1226 rc = oce_config_nic_rss(sc, (uint8_t) sc->if_id, RSS_ENABLE); 1227 if (rc) 1228 goto error; 1229 1230 } 1231 | 1382 } 1383 1384 DELAY(1); 1385 1386 /* RSS config */ 1387 if (is_rss_enabled(sc)) { 1388 rc = oce_config_nic_rss(sc, (uint8_t) sc->if_id, RSS_ENABLE); 1389 if (rc) 1390 goto error; 1391 1392 } 1393 |
1394 DELAY(1); |
|
1232 return rc; 1233error: 1234 device_printf(sc->dev, "Start RX failed\n"); 1235 return rc; 1236 1237} 1238 1239 1240 | 1395 return rc; 1396error: 1397 device_printf(sc->dev, "Start RX failed\n"); 1398 return rc; 1399 1400} 1401 1402 1403 |