net/nfp: update descriptors logic

Message ID 20221122130948.4100369-1-niklas.soderlund@corigine.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series net/nfp: update descriptors logic |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/github-robot: build success github build: passed
ci/iol-aarch64-unit-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS

Commit Message

Niklas Söderlund Nov. 22, 2022, 1:09 p.m. UTC
  From: Jin Liu <jin.liu@corigine.com>

The minimum value of TX/RX descriptors for NFP3800 card is not same
with NFP4000 card, the minimum value of NFP4000 card is 256 while
NFP3800 card is 512, add the minimum descriptor macro for NFP3800
card.

Modify the logic of get descriptor value, assign the value of descriptor
for the corresponding network card according to its type.

In TX stage, firmware with NFD3 use one descriptor per packet while
firmware with NFDk use two descriptors. In order to be consistent
with the kernel driver, the number of descriptor of firmware with
NFDk should be divided by 2.

Signed-off-by: Jin Liu <jin.liu@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
Signed-off-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/nfp_common.c | 86 ++++++++++++++++++++++++++++++++++--
 drivers/net/nfp/nfp_common.h |  6 +++
 drivers/net/nfp/nfp_rxtx.c   | 51 ++++++++++++++-------
 drivers/net/nfp/nfp_rxtx.h   |  3 ++
 4 files changed, 127 insertions(+), 19 deletions(-)
  

Comments

Ferruh Yigit Jan. 19, 2023, 12:41 p.m. UTC | #1
On 11/22/2022 1:09 PM, Niklas Söderlund wrote:
> From: Jin Liu <jin.liu@corigine.com>
> 
> The minimum value of TX/RX descriptors for NFP3800 card is not same
> with NFP4000 card, the minimum value of NFP4000 card is 256 while
> NFP3800 card is 512, add the minimum descriptor macro for NFP3800
> card.
> 
> Modify the logic of get descriptor value, assign the value of descriptor
> for the corresponding network card according to its type.
> 
> In TX stage, firmware with NFD3 use one descriptor per packet while
> firmware with NFDk use two descriptors. In order to be consistent
> with the kernel driver, the number of descriptor of firmware with
> NFDk should be divided by 2.
> 
> Signed-off-by: Jin Liu <jin.liu@corigine.com>
> Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
> Signed-off-by: Niklas Söderlund <niklas.soderlund@corigine.com>

Applied to dpdk-next-net/main, thanks.
  

Patch

diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c
index 71711bfa228e..4defd6d93871 100644
--- a/drivers/net/nfp/nfp_common.c
+++ b/drivers/net/nfp/nfp_common.c
@@ -697,13 +697,91 @@  nfp_net_stats_reset(struct rte_eth_dev *dev)
 	return 0;
 }
 
+int
+nfp_net_rx_desc_limits(struct nfp_net_hw *hw,
+		uint16_t *min_rx_desc,
+		uint16_t *max_rx_desc)
+{
+	*max_rx_desc = NFP_NET_MAX_RX_DESC;
+
+	switch (hw->device_id) {
+	case PCI_DEVICE_ID_NFP3800_PF_NIC:
+	case PCI_DEVICE_ID_NFP3800_VF_NIC:
+		*min_rx_desc = NFP3800_NET_MIN_RX_DESC;
+		return 0;
+	case PCI_DEVICE_ID_NFP4000_PF_NIC:
+	case PCI_DEVICE_ID_NFP6000_PF_NIC:
+	case PCI_DEVICE_ID_NFP6000_VF_NIC:
+		*min_rx_desc = NFP_NET_MIN_RX_DESC;
+		return 0;
+	default:
+		PMD_DRV_LOG(ERR, "Unknown NFP device id.");
+		return -EINVAL;
+	}
+}
+
+int
+nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
+		uint16_t *min_tx_desc,
+		uint16_t *max_tx_desc)
+{
+	uint16_t tx_dpp;
+
+	switch (NFD_CFG_CLASS_VER_of(hw->ver)) {
+	case NFP_NET_CFG_VERSION_DP_NFD3:
+		tx_dpp = NFD3_TX_DESC_PER_SIMPLE_PKT;
+		break;
+	case NFP_NET_CFG_VERSION_DP_NFDK:
+		if (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 5) {
+			PMD_DRV_LOG(ERR, "NFDK must use ABI 5 or newer, found: %d",
+				NFD_CFG_MAJOR_VERSION_of(hw->ver));
+			return -EINVAL;
+		}
+		tx_dpp = NFDK_TX_DESC_PER_SIMPLE_PKT;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "The version of firmware is not correct.");
+		return -EINVAL;
+	}
+
+	*max_tx_desc = NFP_NET_MAX_TX_DESC / tx_dpp;
+
+	switch (hw->device_id) {
+	case PCI_DEVICE_ID_NFP3800_PF_NIC:
+	case PCI_DEVICE_ID_NFP3800_VF_NIC:
+		*min_tx_desc = NFP3800_NET_MIN_TX_DESC / tx_dpp;
+		return 0;
+	case PCI_DEVICE_ID_NFP4000_PF_NIC:
+	case PCI_DEVICE_ID_NFP6000_PF_NIC:
+	case PCI_DEVICE_ID_NFP6000_VF_NIC:
+		*min_tx_desc = NFP_NET_MIN_TX_DESC / tx_dpp;
+		return 0;
+	default:
+		PMD_DRV_LOG(ERR, "Unknown NFP device id.");
+		return -EINVAL;
+	}
+}
+
 int
 nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
+	int ret;
+	uint16_t min_rx_desc;
+	uint16_t max_rx_desc;
+	uint16_t min_tx_desc;
+	uint16_t max_tx_desc;
 	struct nfp_net_hw *hw;
 
 	hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+	ret = nfp_net_rx_desc_limits(hw, &min_rx_desc, &max_rx_desc);
+	if (ret != 0)
+		return ret;
+
+	ret = nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
+	if (ret != 0)
+		return ret;
+
 	dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
 	dev_info->min_rx_bufsize = RTE_ETHER_MIN_MTU;
@@ -764,14 +842,14 @@  nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	};
 
 	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
-		.nb_max = NFP_NET_MAX_RX_DESC,
-		.nb_min = NFP_NET_MIN_RX_DESC,
+		.nb_max = max_rx_desc,
+		.nb_min = min_rx_desc,
 		.nb_align = NFP_ALIGN_RING_DESC,
 	};
 
 	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
-		.nb_max = NFP_NET_MAX_TX_DESC,
-		.nb_min = NFP_NET_MIN_TX_DESC,
+		.nb_max = max_tx_desc,
+		.nb_min = min_tx_desc,
 		.nb_align = NFP_ALIGN_RING_DESC,
 		.nb_seg_max = NFP_TX_MAX_SEG,
 		.nb_mtu_seg_max = NFP_TX_MAX_MTU_SEG,
diff --git a/drivers/net/nfp/nfp_common.h b/drivers/net/nfp/nfp_common.h
index 36c19b47e4d5..a871e437e4d2 100644
--- a/drivers/net/nfp/nfp_common.h
+++ b/drivers/net/nfp/nfp_common.h
@@ -447,6 +447,12 @@  void nfp_net_close_rx_queue(struct rte_eth_dev *dev);
 void nfp_net_stop_tx_queue(struct rte_eth_dev *dev);
 void nfp_net_close_tx_queue(struct rte_eth_dev *dev);
 int nfp_net_set_vxlan_port(struct nfp_net_hw *hw, size_t idx, uint16_t port);
+int nfp_net_rx_desc_limits(struct nfp_net_hw *hw,
+		uint16_t *min_rx_desc,
+		uint16_t *max_rx_desc);
+int nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
+		uint16_t *min_tx_desc,
+		uint16_t *max_tx_desc);
 
 #define NFP_NET_DEV_PRIVATE_TO_HW(adapter)\
 	(&((struct nfp_net_adapter *)adapter)->hw)
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index 01cffdfde0b4..0de7312e217d 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -439,6 +439,9 @@  nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 		       const struct rte_eth_rxconf *rx_conf,
 		       struct rte_mempool *mp)
 {
+	int ret;
+	uint16_t min_rx_desc;
+	uint16_t max_rx_desc;
 	const struct rte_memzone *tz;
 	struct nfp_net_rxq *rxq;
 	struct nfp_net_hw *hw;
@@ -448,11 +451,14 @@  nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
+	ret = nfp_net_rx_desc_limits(hw, &min_rx_desc, &max_rx_desc);
+	if (ret != 0)
+		return ret;
+
 	/* Validating number of descriptors */
 	rx_desc_sz = nb_desc * sizeof(struct nfp_net_rx_desc);
 	if (rx_desc_sz % NFP_ALIGN_RING_DESC != 0 ||
-	    nb_desc > NFP_NET_MAX_RX_DESC ||
-	    nb_desc < NFP_NET_MIN_RX_DESC) {
+	    nb_desc > max_rx_desc || nb_desc < min_rx_desc) {
 		PMD_DRV_LOG(ERR, "Wrong nb_desc value");
 		return -EINVAL;
 	}
@@ -502,7 +508,7 @@  nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	 */
 	tz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
 				   sizeof(struct nfp_net_rx_desc) *
-				   NFP_NET_MAX_RX_DESC, NFP_MEMZONE_ALIGN,
+				   max_rx_desc, NFP_MEMZONE_ALIGN,
 				   socket_id);
 
 	if (tz == NULL) {
@@ -628,6 +634,9 @@  nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		       uint16_t nb_desc, unsigned int socket_id,
 		       const struct rte_eth_txconf *tx_conf)
 {
+	int ret;
+	uint16_t min_tx_desc;
+	uint16_t max_tx_desc;
 	const struct rte_memzone *tz;
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
@@ -638,11 +647,14 @@  nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 
 	PMD_INIT_FUNC_TRACE();
 
+	ret = nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
+	if (ret != 0)
+		return ret;
+
 	/* Validating number of descriptors */
 	tx_desc_sz = nb_desc * sizeof(struct nfp_net_nfd3_tx_desc);
-	if (tx_desc_sz % NFP_ALIGN_RING_DESC != 0 ||
-	    nb_desc > NFP_NET_MAX_TX_DESC ||
-	    nb_desc < NFP_NET_MIN_TX_DESC) {
+	if ((NFD3_TX_DESC_PER_SIMPLE_PKT * tx_desc_sz) % NFP_ALIGN_RING_DESC != 0 ||
+	     nb_desc > max_tx_desc || nb_desc < min_tx_desc) {
 		PMD_DRV_LOG(ERR, "Wrong nb_desc value");
 		return -EINVAL;
 	}
@@ -688,7 +700,8 @@  nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	 */
 	tz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx,
 				   sizeof(struct nfp_net_nfd3_tx_desc) *
-				   NFP_NET_MAX_TX_DESC, NFP_MEMZONE_ALIGN,
+				   NFD3_TX_DESC_PER_SIMPLE_PKT *
+				   max_tx_desc, NFP_MEMZONE_ALIGN,
 				   socket_id);
 	if (tz == NULL) {
 		PMD_DRV_LOG(ERR, "Error allocating tx dma");
@@ -697,7 +710,7 @@  nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 		return -ENOMEM;
 	}
 
-	txq->tx_count = nb_desc;
+	txq->tx_count = nb_desc * NFD3_TX_DESC_PER_SIMPLE_PKT;
 	txq->tx_free_thresh = tx_free_thresh;
 	txq->tx_pthresh = tx_conf->tx_thresh.pthresh;
 	txq->tx_hthresh = tx_conf->tx_thresh.hthresh;
@@ -716,7 +729,7 @@  nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 
 	/* mbuf pointers array for referencing mbufs linked to TX descriptors */
 	txq->txbufs = rte_zmalloc_socket("txq->txbufs",
-					 sizeof(*txq->txbufs) * nb_desc,
+					 sizeof(*txq->txbufs) * txq->tx_count,
 					 RTE_CACHE_LINE_SIZE, socket_id);
 	if (txq->txbufs == NULL) {
 		nfp_net_tx_queue_release(dev, queue_idx);
@@ -735,7 +748,7 @@  nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	 * of descriptors in log2 format
 	 */
 	nn_cfg_writeq(hw, NFP_NET_CFG_TXR_ADDR(queue_idx), txq->dma);
-	nn_cfg_writeb(hw, NFP_NET_CFG_TXR_SZ(queue_idx), rte_log2_u32(nb_desc));
+	nn_cfg_writeb(hw, NFP_NET_CFG_TXR_SZ(queue_idx), rte_log2_u32(txq->tx_count));
 
 	return 0;
 }
@@ -760,7 +773,8 @@  nfp_net_nfd3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pk
 	PMD_TX_LOG(DEBUG, "working for queue %u at pos %d and %u packets",
 		   txq->qidx, txq->wr_p, nb_pkts);
 
-	if ((nfp_net_nfd3_free_tx_desc(txq) < nb_pkts) || (nfp_net_nfd3_txq_full(txq)))
+	if (nfp_net_nfd3_free_tx_desc(txq) < NFD3_TX_DESC_PER_SIMPLE_PKT * nb_pkts ||
+	    nfp_net_nfd3_txq_full(txq))
 		nfp_net_tx_free_bufs(txq);
 
 	free_descs = (uint16_t)nfp_net_nfd3_free_tx_desc(txq);
@@ -879,6 +893,9 @@  nfp_net_nfdk_tx_queue_setup(struct rte_eth_dev *dev,
 		unsigned int socket_id,
 		const struct rte_eth_txconf *tx_conf)
 {
+	int ret;
+	uint16_t min_tx_desc;
+	uint16_t max_tx_desc;
 	const struct rte_memzone *tz;
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
@@ -889,11 +906,15 @@  nfp_net_nfdk_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
+	ret = nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
+	if (ret != 0)
+		return ret;
+
 	/* Validating number of descriptors */
 	tx_desc_sz = nb_desc * sizeof(struct nfp_net_nfdk_tx_desc);
-	if (((NFDK_TX_DESC_PER_SIMPLE_PKT * tx_desc_sz) % NFP_ALIGN_RING_DESC) != 0 ||
-	    ((NFDK_TX_DESC_PER_SIMPLE_PKT * nb_desc) % NFDK_TX_DESC_BLOCK_CNT) != 0 ||
-	      nb_desc > NFP_NET_MAX_TX_DESC || nb_desc < NFP_NET_MIN_TX_DESC) {
+	if ((NFDK_TX_DESC_PER_SIMPLE_PKT * tx_desc_sz) % NFP_ALIGN_RING_DESC != 0 ||
+	    (NFDK_TX_DESC_PER_SIMPLE_PKT * nb_desc) % NFDK_TX_DESC_BLOCK_CNT != 0 ||
+	     nb_desc > max_tx_desc || nb_desc < min_tx_desc) {
 		PMD_DRV_LOG(ERR, "Wrong nb_desc value");
 		return -EINVAL;
 	}
@@ -938,7 +959,7 @@  nfp_net_nfdk_tx_queue_setup(struct rte_eth_dev *dev,
 	tz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx,
 				sizeof(struct nfp_net_nfdk_tx_desc) *
 				NFDK_TX_DESC_PER_SIMPLE_PKT *
-				NFP_NET_MAX_TX_DESC, NFP_MEMZONE_ALIGN,
+				max_tx_desc, NFP_MEMZONE_ALIGN,
 				socket_id);
 	if (tz == NULL) {
 		PMD_DRV_LOG(ERR, "Error allocating tx dma");
diff --git a/drivers/net/nfp/nfp_rxtx.h b/drivers/net/nfp/nfp_rxtx.h
index ced05fde908d..4f0de5e93227 100644
--- a/drivers/net/nfp/nfp_rxtx.h
+++ b/drivers/net/nfp/nfp_rxtx.h
@@ -31,9 +31,11 @@ 
  */
 #define NFP_NET_MAX_TX_DESC (32 * 1024)
 #define NFP_NET_MIN_TX_DESC 256
+#define NFP3800_NET_MIN_TX_DESC 512
 
 #define NFP_NET_MAX_RX_DESC (32 * 1024)
 #define NFP_NET_MIN_RX_DESC 256
+#define NFP3800_NET_MIN_RX_DESC 512
 
 /* Descriptor alignment */
 #define NFP_ALIGN_RING_DESC 128
@@ -57,6 +59,7 @@ 
 #define NFDK_DESC_TX_DMA_LEN_HEAD       0x0fff
 #define NFDK_DESC_TX_TYPE_HEAD          0xf000
 #define NFDK_DESC_TX_DMA_LEN            0x3fff
+#define NFD3_TX_DESC_PER_SIMPLE_PKT     1
 #define NFDK_TX_DESC_PER_SIMPLE_PKT     2
 #define NFDK_DESC_TX_TYPE_TSO           2
 #define NFDK_DESC_TX_TYPE_SIMPLE        8