xref: /dpdk/drivers/net/bnxt/bnxt_txq.c (revision 7d32c003ac175d7ac8669dc11684c75cc7eb56b8)
1fd710bb1SScott Branden /* SPDX-License-Identifier: BSD-3-Clause
26d160d77SRandy Schacher  * Copyright(c) 2014-2023 Broadcom
351c87ebaSAjit Khaparde  * All rights reserved.
451c87ebaSAjit Khaparde  */
551c87ebaSAjit Khaparde 
651c87ebaSAjit Khaparde #include <inttypes.h>
751c87ebaSAjit Khaparde 
851c87ebaSAjit Khaparde #include <rte_malloc.h>
951c87ebaSAjit Khaparde 
1051c87ebaSAjit Khaparde #include "bnxt.h"
110105ea12SAjit Khaparde #include "bnxt_hwrm.h"
1251c87ebaSAjit Khaparde #include "bnxt_ring.h"
1351c87ebaSAjit Khaparde #include "bnxt_txq.h"
146eb3cc22SAjit Khaparde #include "bnxt_txr.h"
1551c87ebaSAjit Khaparde 
1651c87ebaSAjit Khaparde /*
1751c87ebaSAjit Khaparde  * TX Queues
1851c87ebaSAjit Khaparde  */
1951c87ebaSAjit Khaparde 
2047a956a8SKalesh AP uint64_t bnxt_get_tx_port_offloads(struct bnxt *bp)
2147a956a8SKalesh AP {
2247a956a8SKalesh AP 	uint64_t tx_offload_capa;
2347a956a8SKalesh AP 
2447a956a8SKalesh AP 	tx_offload_capa = RTE_ETH_TX_OFFLOAD_IPV4_CKSUM  |
2547a956a8SKalesh AP 			  RTE_ETH_TX_OFFLOAD_UDP_CKSUM   |
2647a956a8SKalesh AP 			  RTE_ETH_TX_OFFLOAD_TCP_CKSUM   |
2747a956a8SKalesh AP 			  RTE_ETH_TX_OFFLOAD_TCP_TSO     |
2847a956a8SKalesh AP 			  RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
2947a956a8SKalesh AP 			  RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
3047a956a8SKalesh AP 
3147a956a8SKalesh AP 	if (bp->fw_cap & BNXT_FW_CAP_VLAN_TX_INSERT)
3247a956a8SKalesh AP 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_VLAN_INSERT;
3347a956a8SKalesh AP 
34c0278f6eSKalesh AP 	if (BNXT_TUNNELED_OFFLOADS_CAP_ALL_EN(bp))
35c0278f6eSKalesh AP 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
36c0278f6eSKalesh AP 
37c0278f6eSKalesh AP 	if (BNXT_TUNNELED_OFFLOADS_CAP_VXLAN_EN(bp))
38c0278f6eSKalesh AP 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO;
39c0278f6eSKalesh AP 	if (BNXT_TUNNELED_OFFLOADS_CAP_GRE_EN(bp))
40c0278f6eSKalesh AP 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO;
41c0278f6eSKalesh AP 	if (BNXT_TUNNELED_OFFLOADS_CAP_NGE_EN(bp))
42c0278f6eSKalesh AP 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
43c0278f6eSKalesh AP 	if (BNXT_TUNNELED_OFFLOADS_CAP_IPINIP_EN(bp))
44c0278f6eSKalesh AP 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO;
4567ae7016SAjit Khaparde 	if (bp->fw_cap & BNXT_FW_CAP_UDP_GSO)
4667ae7016SAjit Khaparde 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_UDP_TSO;
47c0278f6eSKalesh AP 
4847a956a8SKalesh AP 	return tx_offload_capa;
4947a956a8SKalesh AP }
5047a956a8SKalesh AP 
5151c87ebaSAjit Khaparde void bnxt_free_txq_stats(struct bnxt_tx_queue *txq)
5251c87ebaSAjit Khaparde {
53f7b36e8fSRahul Gupta 	if (txq && txq->cp_ring && txq->cp_ring->hw_stats)
54f7b36e8fSRahul Gupta 		txq->cp_ring->hw_stats = NULL;
5551c87ebaSAjit Khaparde }
5651c87ebaSAjit Khaparde 
576eb3cc22SAjit Khaparde static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq)
5851c87ebaSAjit Khaparde {
59527b1008SLance Richardson 	struct rte_mbuf **sw_ring;
606eb3cc22SAjit Khaparde 	uint16_t i;
616eb3cc22SAjit Khaparde 
6297c32717SSomnath Kotur 	if (!txq || !txq->tx_ring)
63f7b36e8fSRahul Gupta 		return;
64f7b36e8fSRahul Gupta 
656eb3cc22SAjit Khaparde 	sw_ring = txq->tx_ring->tx_buf_ring;
666eb3cc22SAjit Khaparde 	if (sw_ring) {
676eb3cc22SAjit Khaparde 		for (i = 0; i < txq->tx_ring->tx_ring_struct->ring_size; i++) {
68527b1008SLance Richardson 			if (sw_ring[i]) {
69527b1008SLance Richardson 				rte_pktmbuf_free_seg(sw_ring[i]);
70527b1008SLance Richardson 				sw_ring[i] = NULL;
716eb3cc22SAjit Khaparde 			}
726eb3cc22SAjit Khaparde 		}
736eb3cc22SAjit Khaparde 	}
7451c87ebaSAjit Khaparde }
7551c87ebaSAjit Khaparde 
7651c87ebaSAjit Khaparde void bnxt_free_tx_mbufs(struct bnxt *bp)
7751c87ebaSAjit Khaparde {
7851c87ebaSAjit Khaparde 	struct bnxt_tx_queue *txq;
7951c87ebaSAjit Khaparde 	int i;
8051c87ebaSAjit Khaparde 
8151c87ebaSAjit Khaparde 	for (i = 0; i < (int)bp->tx_nr_rings; i++) {
8251c87ebaSAjit Khaparde 		txq = bp->tx_queues[i];
8351c87ebaSAjit Khaparde 		bnxt_tx_queue_release_mbufs(txq);
8451c87ebaSAjit Khaparde 	}
8551c87ebaSAjit Khaparde }
8651c87ebaSAjit Khaparde 
877483341aSXueming Li void bnxt_tx_queue_release_op(struct rte_eth_dev *dev, uint16_t queue_idx)
8851c87ebaSAjit Khaparde {
897483341aSXueming Li 	struct bnxt_tx_queue *txq = dev->data->tx_queues[queue_idx];
9051c87ebaSAjit Khaparde 
9151c87ebaSAjit Khaparde 	if (txq) {
921bf01f51SKalesh AP 		if (is_bnxt_in_error(txq->bp))
931bf01f51SKalesh AP 			return;
941bf01f51SKalesh AP 
956eb3cc22SAjit Khaparde 		/* Free TX ring hardware descriptors */
960105ea12SAjit Khaparde 		bnxt_free_hwrm_tx_ring(txq->bp, txq->queue_id);
976eb3cc22SAjit Khaparde 		bnxt_tx_queue_release_mbufs(txq);
9897c32717SSomnath Kotur 		if (txq->tx_ring) {
996eb3cc22SAjit Khaparde 			bnxt_free_ring(txq->tx_ring->tx_ring_struct);
10097c32717SSomnath Kotur 			rte_free(txq->tx_ring->tx_ring_struct);
101925cd070SSomnath Kotur 			rte_free(txq->tx_ring->nr_bds);
10297c32717SSomnath Kotur 			rte_free(txq->tx_ring);
10397c32717SSomnath Kotur 		}
1046eb3cc22SAjit Khaparde 
1056eb3cc22SAjit Khaparde 		/* Free TX completion ring hardware descriptors */
10697c32717SSomnath Kotur 		if (txq->cp_ring) {
107f83823f9SKishore Padmanabha 			bnxt_free_txq_stats(txq);
1086eb3cc22SAjit Khaparde 			bnxt_free_ring(txq->cp_ring->cp_ring_struct);
10997c32717SSomnath Kotur 			rte_free(txq->cp_ring->cp_ring_struct);
11097c32717SSomnath Kotur 			rte_free(txq->cp_ring);
11197c32717SSomnath Kotur 		}
1126eb3cc22SAjit Khaparde 
11323460b4cSAjit Khaparde 		rte_memzone_free(txq->mz);
11423460b4cSAjit Khaparde 		txq->mz = NULL;
1156eb3cc22SAjit Khaparde 
1165ef3592cSAjit Khaparde 		rte_free(txq->free);
117d46406c7SAjit Khaparde 		pthread_mutex_destroy(&txq->txq_lock);
11851c87ebaSAjit Khaparde 		rte_free(txq);
1197483341aSXueming Li 		dev->data->tx_queues[queue_idx] = NULL;
12051c87ebaSAjit Khaparde 	}
12151c87ebaSAjit Khaparde }
12251c87ebaSAjit Khaparde 
12351c87ebaSAjit Khaparde int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
12451c87ebaSAjit Khaparde 			       uint16_t queue_idx,
12551c87ebaSAjit Khaparde 			       uint16_t nb_desc,
12651c87ebaSAjit Khaparde 			       unsigned int socket_id,
12751c87ebaSAjit Khaparde 			       const struct rte_eth_txconf *tx_conf)
12851c87ebaSAjit Khaparde {
12978466c95SStephen Hemminger 	struct bnxt *bp = eth_dev->data->dev_private;
13051c87ebaSAjit Khaparde 	struct bnxt_tx_queue *txq;
1312bb1d5dbSAjit Khaparde 	int rc = 0;
13251c87ebaSAjit Khaparde 
1331bf01f51SKalesh AP 	rc = is_bnxt_in_error(bp);
1341bf01f51SKalesh AP 	if (rc)
1351bf01f51SKalesh AP 		return rc;
1361bf01f51SKalesh AP 
137c72fe7acSSriharsha Basavapatna 	if (queue_idx >= bnxt_max_rings(bp)) {
138e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR,
139e99981afSDavid Marchand 			"Cannot create Tx ring %d. Only %d rings available",
140f10d5282SAjit Khaparde 			queue_idx, bp->max_tx_rings);
141a42b152aSJay Ding 		return -EINVAL;
142f10d5282SAjit Khaparde 	}
143f10d5282SAjit Khaparde 
144cec43bbfSLance Richardson 	if (nb_desc < BNXT_MIN_RING_DESC || nb_desc > MAX_TX_DESC_CNT) {
145e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "nb_desc %d is invalid", nb_desc);
14697c32717SSomnath Kotur 		return -EINVAL;
14751c87ebaSAjit Khaparde 	}
14851c87ebaSAjit Khaparde 
14951c87ebaSAjit Khaparde 	if (eth_dev->data->tx_queues) {
15051c87ebaSAjit Khaparde 		txq = eth_dev->data->tx_queues[queue_idx];
1517483341aSXueming Li 		if (txq)
1527483341aSXueming Li 			bnxt_tx_queue_release_op(eth_dev, queue_idx);
15351c87ebaSAjit Khaparde 	}
15451c87ebaSAjit Khaparde 	txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue),
15551c87ebaSAjit Khaparde 				 RTE_CACHE_LINE_SIZE, socket_id);
1562bb1d5dbSAjit Khaparde 	if (!txq) {
157e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "bnxt_tx_queue allocation failed!");
15897c32717SSomnath Kotur 		return -ENOMEM;
15951c87ebaSAjit Khaparde 	}
1605ef3592cSAjit Khaparde 
1617483341aSXueming Li 	txq->bp = bp;
1627483341aSXueming Li 	eth_dev->data->tx_queues[queue_idx] = txq;
1637483341aSXueming Li 
1645ef3592cSAjit Khaparde 	txq->free = rte_zmalloc_socket(NULL,
1655ef3592cSAjit Khaparde 				       sizeof(struct rte_mbuf *) * nb_desc,
1665ef3592cSAjit Khaparde 				       RTE_CACHE_LINE_SIZE, socket_id);
1675ef3592cSAjit Khaparde 	if (!txq->free) {
168e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "allocation of tx mbuf free array failed!");
1695ef3592cSAjit Khaparde 		rc = -ENOMEM;
17097c32717SSomnath Kotur 		goto err;
1715ef3592cSAjit Khaparde 	}
17251c87ebaSAjit Khaparde 	txq->nb_tx_desc = nb_desc;
173cec43bbfSLance Richardson 	txq->tx_free_thresh =
174cec43bbfSLance Richardson 		RTE_MIN(rte_align32pow2(nb_desc) / 4, RTE_BNXT_MAX_TX_BURST);
175369f6077SLance Richardson 	txq->offloads = eth_dev->data->dev_conf.txmode.offloads |
176369f6077SLance Richardson 			tx_conf->offloads;
177cec43bbfSLance Richardson 
1782171e66fSKalesh AP 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
17951c87ebaSAjit Khaparde 
1802bb1d5dbSAjit Khaparde 	rc = bnxt_init_tx_ring_struct(txq, socket_id);
1812bb1d5dbSAjit Khaparde 	if (rc)
18297c32717SSomnath Kotur 		goto err;
18351c87ebaSAjit Khaparde 
18451c87ebaSAjit Khaparde 	txq->queue_id = queue_idx;
18551c87ebaSAjit Khaparde 	txq->port_id = eth_dev->data->port_id;
18651c87ebaSAjit Khaparde 
1876eb3cc22SAjit Khaparde 	/* Allocate TX ring hardware descriptors */
188c6c90a33SLance Richardson 	if (bnxt_alloc_rings(bp, socket_id, queue_idx, txq, NULL, txq->cp_ring,
189c6c90a33SLance Richardson 			     NULL, "txr")) {
190e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "ring_dma_zone_reserve for tx_ring failed!");
1912bb1d5dbSAjit Khaparde 		rc = -ENOMEM;
19297c32717SSomnath Kotur 		goto err;
1936eb3cc22SAjit Khaparde 	}
19451c87ebaSAjit Khaparde 
1956eb3cc22SAjit Khaparde 	if (bnxt_init_one_tx_ring(txq)) {
196e99981afSDavid Marchand 		PMD_DRV_LOG_LINE(ERR, "bnxt_init_one_tx_ring failed!");
1972bb1d5dbSAjit Khaparde 		rc = -ENOMEM;
19897c32717SSomnath Kotur 		goto err;
1996eb3cc22SAjit Khaparde 	}
20051c87ebaSAjit Khaparde 
201*7d32c003SAriel Otilibili 	return pthread_mutex_init(&txq->txq_lock, NULL);
20297c32717SSomnath Kotur err:
2037483341aSXueming Li 	bnxt_tx_queue_release_op(eth_dev, queue_idx);
2042bb1d5dbSAjit Khaparde 	return rc;
20551c87ebaSAjit Khaparde }
206