X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Fbnxt_txq.c;h=bdc7ffaaabc7b4cf7cdca650af4a5dbbc805f316;hb=f0f5d844d138;hp=892898410f1dc6118654ee3719b3979657b73e7e;hpb=51c87ebafc7d70258aaae54bc047f66ef61e8b5a;p=dpdk.git diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c index 892898410f..bdc7ffaaab 100644 --- a/drivers/net/bnxt/bnxt_txq.c +++ b/drivers/net/bnxt/bnxt_txq.c @@ -1,34 +1,6 @@ -/*- - * BSD LICENSE - * - * Copyright(c) Broadcom Limited. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Broadcom Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2014-2018 Broadcom + * All rights reserved. */ #include @@ -38,6 +10,7 @@ #include "bnxt.h" #include "bnxt_ring.h" #include "bnxt_txq.h" +#include "bnxt_txr.h" /* * TX Queues @@ -45,17 +18,27 @@ void bnxt_free_txq_stats(struct bnxt_tx_queue *txq) { - struct bnxt_cp_ring_info *cpr = txq->cp_ring; - - /* 'Unreserve' rte_memzone */ - - if (cpr->hw_stats) - cpr->hw_stats = NULL; + if (txq && txq->cp_ring && txq->cp_ring->hw_stats) + txq->cp_ring->hw_stats = NULL; } -static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq __rte_unused) +static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq) { - /* TODO: Requires interaction with TX ring */ + struct bnxt_sw_tx_bd *sw_ring; + uint16_t i; + + if (!txq) + return; + + sw_ring = txq->tx_ring->tx_buf_ring; + if (sw_ring) { + for (i = 0; i < txq->tx_ring->tx_ring_struct->ring_size; i++) { + if (sw_ring[i].mbuf) { + rte_pktmbuf_free_seg(sw_ring[i].mbuf); + sw_ring[i].mbuf = NULL; + } + } + } } void bnxt_free_tx_mbufs(struct bnxt *bp) @@ -74,7 +57,21 @@ void bnxt_tx_queue_release_op(void *tx_queue) struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue; if (txq) { - /* TODO: Free ring and stats here */ + if (is_bnxt_in_error(txq->bp)) + return; + + /* Free TX ring hardware descriptors */ + bnxt_tx_queue_release_mbufs(txq); + bnxt_free_ring(txq->tx_ring->tx_ring_struct); + + /* Free TX completion ring hardware descriptors */ + bnxt_free_ring(txq->cp_ring->cp_ring_struct); + + bnxt_free_txq_stats(txq); + rte_memzone_free(txq->mz); + txq->mz = NULL; + + rte_free(txq->free); rte_free(txq); } } @@ -85,14 +82,27 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, unsigned int socket_id, const struct rte_eth_txconf *tx_conf) { - struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; + struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_tx_queue *txq; + int rc = 0; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; - if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) { - RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc); + if (queue_idx >= BNXT_MAX_RINGS(bp)) { + PMD_DRV_LOG(ERR, + "Cannot create Tx ring %d. Only %d rings available\n", + queue_idx, bp->max_tx_rings); return -EINVAL; } + if (nb_desc < BNXT_MIN_RING_DESC || nb_desc > MAX_TX_DESC_CNT) { + PMD_DRV_LOG(ERR, "nb_desc %d is invalid", nb_desc); + rc = -EINVAL; + goto out; + } + if (eth_dev->data->tx_queues) { txq = eth_dev->data->tx_queues[queue_idx]; if (txq) { @@ -102,23 +112,57 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, } txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue), RTE_CACHE_LINE_SIZE, socket_id); - if (txq == NULL) { - RTE_LOG(ERR, PMD, "bnxt_tx_queue allocation failed!"); - return -ENOMEM; + if (!txq) { + PMD_DRV_LOG(ERR, "bnxt_tx_queue allocation failed!"); + rc = -ENOMEM; + goto out; + } + + txq->free = rte_zmalloc_socket(NULL, + sizeof(struct rte_mbuf *) * nb_desc, + RTE_CACHE_LINE_SIZE, socket_id); + if (!txq->free) { + PMD_DRV_LOG(ERR, "allocation of tx mbuf free array failed!"); + rte_free(txq); + rc = -ENOMEM; + goto out; } txq->bp = bp; txq->nb_tx_desc = nb_desc; - txq->tx_free_thresh = tx_conf->tx_free_thresh; + txq->tx_free_thresh = + RTE_MIN(rte_align32pow2(nb_desc) / 4, RTE_BNXT_MAX_TX_BURST); - /* TODO: Initialize ring structure */ + txq->tx_deferred_start = tx_conf->tx_deferred_start; + + rc = bnxt_init_tx_ring_struct(txq, socket_id); + if (rc) + goto out; txq->queue_id = queue_idx; txq->port_id = eth_dev->data->port_id; - /* TODO: Allocate TX ring hardware descriptors */ + /* Allocate TX ring hardware descriptors */ + if (bnxt_alloc_rings(bp, queue_idx, txq, NULL, txq->cp_ring, NULL, + "txr")) { + PMD_DRV_LOG(ERR, "ring_dma_zone_reserve for tx_ring failed!"); + bnxt_tx_queue_release_op(txq); + rc = -ENOMEM; + goto out; + } - /* TODO: Initialize the ring */ + if (bnxt_init_one_tx_ring(txq)) { + PMD_DRV_LOG(ERR, "bnxt_init_one_tx_ring failed!"); + bnxt_tx_queue_release_op(txq); + rc = -ENOMEM; + goto out; + } eth_dev->data->tx_queues[queue_idx] = txq; - return 0; + + if (txq->tx_deferred_start) + txq->tx_started = false; + else + txq->tx_started = true; +out: + return rc; }