Deleted Added
full compact
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