numam-dpdk/drivers/net/bnxt/bnxt_txq.c
Xueming Li 7483341ae5 ethdev: change queue release callback
Currently, most ethdev callback API use queue ID as parameter, but Rx
and Tx queue release callback use queue object which is used by Rx and
Tx burst data plane callback.

To align with other eth device queue configuration callbacks:
- queue release callbacks are changed to use queue ID
- all drivers are adapted

Signed-off-by: Xueming Li <xuemingl@nvidia.com>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Acked-by: Somnath Kotur <somnath.kotur@broadcom.com>
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
2021-10-06 19:16:03 +02:00

173 lines
3.9 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2014-2021 Broadcom
* All rights reserved.
*/
#include <inttypes.h>
#include <rte_malloc.h>
#include "bnxt.h"
#include "bnxt_hwrm.h"
#include "bnxt_ring.h"
#include "bnxt_txq.h"
#include "bnxt_txr.h"
/*
* TX Queues
*/
void bnxt_free_txq_stats(struct bnxt_tx_queue *txq)
{
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)
{
struct rte_mbuf **sw_ring;
uint16_t i;
if (!txq || !txq->tx_ring)
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]) {
rte_pktmbuf_free_seg(sw_ring[i]);
sw_ring[i] = NULL;
}
}
}
}
void bnxt_free_tx_mbufs(struct bnxt *bp)
{
struct bnxt_tx_queue *txq;
int i;
for (i = 0; i < (int)bp->tx_nr_rings; i++) {
txq = bp->tx_queues[i];
bnxt_tx_queue_release_mbufs(txq);
}
}
void bnxt_tx_queue_release_op(struct rte_eth_dev *dev, uint16_t queue_idx)
{
struct bnxt_tx_queue *txq = dev->data->tx_queues[queue_idx];
if (txq) {
if (is_bnxt_in_error(txq->bp))
return;
/* Free TX ring hardware descriptors */
bnxt_free_hwrm_tx_ring(txq->bp, txq->queue_id);
bnxt_tx_queue_release_mbufs(txq);
if (txq->tx_ring) {
bnxt_free_ring(txq->tx_ring->tx_ring_struct);
rte_free(txq->tx_ring->tx_ring_struct);
rte_free(txq->tx_ring);
}
/* Free TX completion ring hardware descriptors */
if (txq->cp_ring) {
bnxt_free_ring(txq->cp_ring->cp_ring_struct);
rte_free(txq->cp_ring->cp_ring_struct);
rte_free(txq->cp_ring);
}
bnxt_free_txq_stats(txq);
rte_memzone_free(txq->mz);
txq->mz = NULL;
rte_free(txq->free);
rte_free(txq);
dev->data->tx_queues[queue_idx] = NULL;
}
}
int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
uint16_t queue_idx,
uint16_t nb_desc,
unsigned int socket_id,
const struct rte_eth_txconf *tx_conf)
{
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 (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);
return -EINVAL;
}
if (eth_dev->data->tx_queues) {
txq = eth_dev->data->tx_queues[queue_idx];
if (txq)
bnxt_tx_queue_release_op(eth_dev, queue_idx);
}
txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue),
RTE_CACHE_LINE_SIZE, socket_id);
if (!txq) {
PMD_DRV_LOG(ERR, "bnxt_tx_queue allocation failed!");
return -ENOMEM;
}
txq->bp = bp;
eth_dev->data->tx_queues[queue_idx] = txq;
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!");
rc = -ENOMEM;
goto err;
}
txq->nb_tx_desc = nb_desc;
txq->tx_free_thresh =
RTE_MIN(rte_align32pow2(nb_desc) / 4, RTE_BNXT_MAX_TX_BURST);
txq->offloads = eth_dev->data->dev_conf.txmode.offloads |
tx_conf->offloads;
txq->tx_deferred_start = tx_conf->tx_deferred_start;
rc = bnxt_init_tx_ring_struct(txq, socket_id);
if (rc)
goto err;
txq->queue_id = queue_idx;
txq->port_id = eth_dev->data->port_id;
/* Allocate TX ring hardware descriptors */
if (bnxt_alloc_rings(bp, socket_id, queue_idx, txq, NULL, txq->cp_ring,
NULL, "txr")) {
PMD_DRV_LOG(ERR, "ring_dma_zone_reserve for tx_ring failed!");
rc = -ENOMEM;
goto err;
}
if (bnxt_init_one_tx_ring(txq)) {
PMD_DRV_LOG(ERR, "bnxt_init_one_tx_ring failed!");
rc = -ENOMEM;
goto err;
}
return 0;
err:
bnxt_tx_queue_release_op(eth_dev, queue_idx);
return rc;
}