[5/5] net/nfp: report packet type by Rx descriptor

Message ID 20230522080500.2014001-6-chaoyong.he@corigine.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series Add support of report packet type |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/intel-Functional success Functional PASS
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS

Commit Message

Chaoyong He May 22, 2023, 8:05 a.m. UTC
  From: Qin Ke <qin.ke@corigine.com>

There are some issues about reporting packet type by hash type of
metadata. And it may cause more performance loss and space wasting.

Parses packet type from Rx descriptor and set it to mbuf. And opens
the feature by default in nfp_net_start().

Signed-off-by: Qin Ke <qin.ke@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/nfp_common.c |  42 +++++++++++
 drivers/net/nfp/nfp_common.h |   1 +
 drivers/net/nfp/nfp_ctrl.h   |  16 +++--
 drivers/net/nfp/nfp_ethdev.c |  11 +++
 drivers/net/nfp/nfp_rxtx.c   | 134 +++++++++++++++++++++++++++++++++++
 drivers/net/nfp/nfp_rxtx.h   |  83 ++++++++++++++++++++++
 6 files changed, 283 insertions(+), 4 deletions(-)
  

Patch

diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c
index 0644f6f1a8..0bd95d050e 100644
--- a/drivers/net/nfp/nfp_common.c
+++ b/drivers/net/nfp/nfp_common.c
@@ -301,6 +301,48 @@  nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t ctrl, uint32_t update)
 	return 0;
 }
 
+/**
+ * Reconfigure the NIC for the extend ctrl BAR.
+ *
+ * Write the update word to the BAR and ping the reconfig queue. Then poll
+ * until the firmware has acknowledged the update by zeroing the update word.
+ *
+ * @param hw
+ *   Device to reconfigure.
+ * @param ctrl_ext
+ *   The value for the first word of extend ctrl field in the BAR config.
+ * @param update
+ *   The value for the update field in the BAR config.
+ *
+ * @return
+ *   - (0) if OK to reconfigure the device.
+ *   - (EIO) if I/O err and fail to reconfigure the device.
+ */
+int
+nfp_net_ext_reconfig(struct nfp_net_hw *hw, uint32_t ctrl_ext, uint32_t update)
+{
+	int ret;
+
+	rte_spinlock_lock(&hw->reconfig_lock);
+
+	nn_cfg_writel(hw, NFP_NET_CFG_CTRL_WORD1, ctrl_ext);
+	nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update);
+
+	rte_wmb();
+
+	ret = __nfp_net_reconfig(hw, update);
+
+	rte_spinlock_unlock(&hw->reconfig_lock);
+
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Error nft net ext reconfig: ctrl_ext=%#08x update=%#08x",
+				ctrl_ext, update);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /*
  * Configure an Ethernet device. This function must be invoked first
  * before any other function in the Ethernet API. This function can
diff --git a/drivers/net/nfp/nfp_common.h b/drivers/net/nfp/nfp_common.h
index 47df0510c5..baa6752a44 100644
--- a/drivers/net/nfp/nfp_common.h
+++ b/drivers/net/nfp/nfp_common.h
@@ -423,6 +423,7 @@  nfp_pci_queue(struct rte_pci_device *pdev, uint16_t queue)
 
 /* Prototypes for common NFP functions */
 int nfp_net_reconfig(struct nfp_net_hw *hw, uint32_t ctrl, uint32_t update);
+int nfp_net_ext_reconfig(struct nfp_net_hw *hw, uint32_t ctrl_ext, uint32_t update);
 int nfp_net_configure(struct rte_eth_dev *dev);
 void nfp_net_log_device_information(const struct nfp_net_hw *hw);
 void nfp_net_enable_queues(struct rte_eth_dev *dev);
diff --git a/drivers/net/nfp/nfp_ctrl.h b/drivers/net/nfp/nfp_ctrl.h
index bca31ac311..ce31dea609 100644
--- a/drivers/net/nfp/nfp_ctrl.h
+++ b/drivers/net/nfp/nfp_ctrl.h
@@ -214,11 +214,19 @@ 
 /* Offload definitions */
 #define NFP_NET_N_VXLAN_PORTS  (NFP_NET_CFG_VXLAN_SZ / sizeof(uint16_t))
 
-/**
- * 64B reserved for future use (0x0080 - 0x00c0)
+/*
+ * 3 words reserved for extended ctrl words (0x0098 - 0x00a4)
+ * 3 words reserved for extended cap words (0x00a4 - 0x00b0)
+ * Currently only one word is used, can be extended in future.
  */
-#define NFP_NET_CFG_RESERVED            0x0080
-#define NFP_NET_CFG_RESERVED_SZ         0x0040
+#define NFP_NET_CFG_CTRL_WORD1          0x0098
+#define NFP_NET_CFG_CTRL_PKT_TYPE         (0x1 << 0)
+
+#define NFP_NET_CFG_CAP_WORD1           0x00a4
+
+/* 16B reserved for future use (0x00b0 - 0x00c0). */
+#define NFP_NET_CFG_RESERVED            0x00b0
+#define NFP_NET_CFG_RESERVED_SZ         0x0010
 
 /*
  * RSS configuration (0x0100 - 0x01ac):
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 1ddb7a92ee..bd55a54d58 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -57,6 +57,8 @@  nfp_net_start(struct rte_eth_dev *dev)
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
 	uint32_t new_ctrl, update = 0;
+	uint32_t cap_extend;
+	uint32_t ctrl_extend = 0;
 	struct nfp_net_hw *hw;
 	struct nfp_pf_dev *pf_dev;
 	struct nfp_app_fw_nic *app_fw_nic;
@@ -147,6 +149,15 @@  nfp_net_start(struct rte_eth_dev *dev)
 	if (nfp_net_reconfig(hw, new_ctrl, update) < 0)
 		return -EIO;
 
+	/* Enable packet type offload by extend ctrl word1. */
+	cap_extend = nn_cfg_readl(hw, NFP_NET_CFG_CAP_WORD1);
+	if ((cap_extend & NFP_NET_CFG_CTRL_PKT_TYPE) != 0)
+		ctrl_extend = NFP_NET_CFG_CTRL_PKT_TYPE;
+
+	update = NFP_NET_CFG_UPDATE_GEN;
+	if (nfp_net_ext_reconfig(hw, ctrl_extend, update) < 0)
+		return -EIO;
+
 	/*
 	 * Allocating rte mbufs for configured rx queues.
 	 * This requires queues being enabled before
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index 26bf1543ac..1bf32c4853 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -304,6 +304,138 @@  nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
 	}
 }
 
+/**
+ * Set packet type to mbuf based on parsed structure.
+ *
+ * @param nfp_ptype
+ *   Packet type structure parsing from Rx descriptor.
+ * @param mb
+ *   Mbuf to set the packet type.
+ */
+static void
+nfp_net_set_ptype(const struct nfp_ptype_parsed *nfp_ptype, struct rte_mbuf *mb)
+{
+	uint32_t mbuf_ptype = RTE_PTYPE_L2_ETHER;
+	uint8_t nfp_tunnel_ptype = nfp_ptype->tunnel_ptype;
+
+	if (nfp_tunnel_ptype != NFP_NET_PTYPE_TUNNEL_NONE)
+		mbuf_ptype |= RTE_PTYPE_INNER_L2_ETHER;
+
+	switch (nfp_tunnel_ptype) {
+	case NFP_NET_PTYPE_TUNNEL_NONE:
+		break;
+	case NFP_NET_PTYPE_TUNNEL_VXLAN:
+		mbuf_ptype |= RTE_PTYPE_TUNNEL_VXLAN;
+		break;
+	case NFP_NET_PTYPE_TUNNEL_NVGRE:
+		mbuf_ptype |= RTE_PTYPE_TUNNEL_NVGRE;
+		break;
+	case NFP_NET_PTYPE_TUNNEL_GENEVE:
+		mbuf_ptype |= RTE_PTYPE_TUNNEL_GENEVE;
+		break;
+	default:
+		PMD_RX_LOG(DEBUG, "Unrecognized nfp tunnel packet type: %u",
+				nfp_tunnel_ptype);
+		break;
+	}
+
+	switch (nfp_ptype->l4_ptype) {
+	case NFP_NET_PTYPE_L4_NONE:
+		break;
+	case NFP_NET_PTYPE_L4_TCP:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_TCP);
+		break;
+	case NFP_NET_PTYPE_L4_UDP:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_UDP);
+		break;
+	case NFP_NET_PTYPE_L4_FRAG:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_FRAG);
+		break;
+	case NFP_NET_PTYPE_L4_NONFRAG:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_NONFRAG);
+		break;
+	case NFP_NET_PTYPE_L4_ICMP:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_ICMP);
+		break;
+	case NFP_NET_PTYPE_L4_SCTP:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_SCTP);
+		break;
+	default:
+		PMD_RX_LOG(DEBUG, "Unrecognized nfp layer 4 packet type: %u",
+				nfp_ptype->l4_ptype);
+		break;
+	}
+
+	switch (nfp_ptype->l3_ptype) {
+	case NFP_NET_PTYPE_L3_NONE:
+		break;
+	case NFP_NET_PTYPE_L3_IPV4:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4);
+		break;
+	case NFP_NET_PTYPE_L3_IPV6:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6);
+		break;
+	case NFP_NET_PTYPE_L3_IPV4_EXT:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4_EXT);
+		break;
+	case NFP_NET_PTYPE_L3_IPV6_EXT:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6_EXT);
+		break;
+	case NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4_EXT_UNKNOWN);
+		break;
+	case NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN:
+		mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6_EXT_UNKNOWN);
+		break;
+	default:
+		PMD_RX_LOG(DEBUG, "Unrecognized nfp layer 3 packet type: %u",
+				nfp_ptype->l3_ptype);
+		break;
+	}
+
+	mb->packet_type = mbuf_ptype;
+}
+
+/**
+ * Parse the packet type from Rx descriptor and set to mbuf.
+ *
+ * @param rxds
+ *   Rx descriptor including the offloading info of packet type.
+ * @param hw
+ *   Device.
+ * @param mb
+ *   Mbuf to set the packet type.
+ */
+static void
+nfp_net_parse_ptype(struct nfp_net_rx_desc *rxds,
+		struct nfp_net_hw *hw,
+		struct rte_mbuf *mb)
+{
+	uint32_t cap_extend;
+	uint32_t ctrl_extend;
+	struct nfp_ptype_parsed nfp_ptype;
+	uint16_t rxd_ptype = rxds->rxd.offload_info;
+
+	if (rxd_ptype == 0 || (rxds->rxd.flags & PCIE_DESC_RX_VLAN) != 0)
+		return;
+
+	cap_extend = nn_cfg_readl(hw, NFP_NET_CFG_CAP_WORD1);
+	ctrl_extend = nn_cfg_readl(hw, NFP_NET_CFG_CTRL_WORD1);
+
+	if ((cap_extend & NFP_NET_CFG_CTRL_PKT_TYPE) == 0 ||
+			(ctrl_extend & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
+		return;
+
+	nfp_ptype.l4_ptype = (rxd_ptype & NFP_NET_PTYPE_L4_MASK) >>
+			NFP_NET_PTYPE_L4_OFFSET;
+	nfp_ptype.l3_ptype = (rxd_ptype & NFP_NET_PTYPE_L3_MASK) >>
+			NFP_NET_PTYPE_L3_OFFSET;
+	nfp_ptype.tunnel_ptype = (rxd_ptype & NFP_NET_PTYPE_TUNNEL_MASK) >>
+			NFP_NET_PTYPE_TUNNEL_OFFSET;
+
+	nfp_net_set_ptype(&nfp_ptype, mb);
+}
+
 /*
  * RX path design:
  *
@@ -438,6 +570,8 @@  nfp_net_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 
 		nfp_net_parse_meta(rxds, rxq, hw, mb);
 
+		nfp_net_parse_ptype(rxds, hw, mb);
+
 		/* Checking the checksum flag */
 		nfp_net_rx_cksum(rxq, rxds, mb);
 
diff --git a/drivers/net/nfp/nfp_rxtx.h b/drivers/net/nfp/nfp_rxtx.h
index 73ef0a7c9f..eebe9b3ee2 100644
--- a/drivers/net/nfp/nfp_rxtx.h
+++ b/drivers/net/nfp/nfp_rxtx.h
@@ -170,6 +170,89 @@  struct nfp_net_txq {
 #define PCIE_DESC_RX_L4_CSUM_OK         (PCIE_DESC_RX_TCP_CSUM_OK | \
 					 PCIE_DESC_RX_UDP_CSUM_OK)
 
+/*
+ * The bit format and map of nfp packet type for rxd.offload_info in Rx descriptor.
+ *
+ * Bit format about nfp packet type refers to the following:
+ * ---------------------------------
+ *            1                   0
+ *  5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           |tunnel |  l3 |  l4 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Bit map about nfp packet type refers to the following:
+ *
+ * L4: bit 0~2, used for layer 4 or inner layer 4.
+ * 000: NFP_NET_PTYPE_L4_NONE
+ * 001: NFP_NET_PTYPE_L4_TCP
+ * 010: NFP_NET_PTYPE_L4_UDP
+ * 011: NFP_NET_PTYPE_L4_FRAG
+ * 100: NFP_NET_PTYPE_L4_NONFRAG
+ * 101: NFP_NET_PTYPE_L4_ICMP
+ * 110: NFP_NET_PTYPE_L4_SCTP
+ * 111: reserved
+ *
+ * L3: bit 3~5, used for layer 3 or inner layer 3.
+ * 000: NFP_NET_PTYPE_L3_NONE
+ * 001: NFP_NET_PTYPE_L3_IPV6
+ * 010: NFP_NET_PTYPE_L3_IPV4
+ * 011: NFP_NET_PTYPE_L3_IPV4_EXT
+ * 100: NFP_NET_PTYPE_L3_IPV6_EXT
+ * 101: NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN
+ * 110: NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN
+ * 111: reserved
+ *
+ * Tunnel: bit 6~9, used for tunnel.
+ * 0000: NFP_NET_PTYPE_TUNNEL_NONE
+ * 0001: NFP_NET_PTYPE_TUNNEL_VXLAN
+ * 0100: NFP_NET_PTYPE_TUNNEL_NVGRE
+ * 0101: NFP_NET_PTYPE_TUNNEL_GENEVE
+ * 0010, 0011, 0110~1111: reserved
+ *
+ * Reserved: bit 10~15, used for extension.
+ */
+
+/* Mask and offset about nfp packet type based on the bit map above. */
+#define NFP_NET_PTYPE_L4_MASK                  0x0007
+#define NFP_NET_PTYPE_L3_MASK                  0x0038
+#define NFP_NET_PTYPE_TUNNEL_MASK              0x03c0
+
+#define NFP_NET_PTYPE_L4_OFFSET                0
+#define NFP_NET_PTYPE_L3_OFFSET                3
+#define NFP_NET_PTYPE_TUNNEL_OFFSET            6
+
+/* Case about nfp packet type based on the bit map above. */
+#define NFP_NET_PTYPE_L4_NONE                  0
+#define NFP_NET_PTYPE_L4_TCP                   1
+#define NFP_NET_PTYPE_L4_UDP                   2
+#define NFP_NET_PTYPE_L4_FRAG                  3
+#define NFP_NET_PTYPE_L4_NONFRAG               4
+#define NFP_NET_PTYPE_L4_ICMP                  5
+#define NFP_NET_PTYPE_L4_SCTP                  6
+
+#define NFP_NET_PTYPE_L3_NONE                  0
+#define NFP_NET_PTYPE_L3_IPV6                  1
+#define NFP_NET_PTYPE_L3_IPV4                  2
+#define NFP_NET_PTYPE_L3_IPV4_EXT              3
+#define NFP_NET_PTYPE_L3_IPV6_EXT              4
+#define NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN      5
+#define NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN      6
+
+#define NFP_NET_PTYPE_TUNNEL_NONE              0
+#define NFP_NET_PTYPE_TUNNEL_VXLAN             1
+#define NFP_NET_PTYPE_TUNNEL_NVGRE             4
+#define NFP_NET_PTYPE_TUNNEL_GENEVE            5
+
+#define NFP_PTYPE2RTE(tunnel, type) ((tunnel) ? RTE_PTYPE_INNER_##type : RTE_PTYPE_##type)
+
+/* Record NFP packet type parsed from rxd.offload_info. */
+struct nfp_ptype_parsed {
+	uint8_t l4_ptype;     /**< Packet type of layer 4, or inner layer 4. */
+	uint8_t l3_ptype;     /**< Packet type of layer 3, or inner layer 3. */
+	uint8_t tunnel_ptype; /**< Packet type of tunnel. */
+};
+
 struct nfp_net_rx_desc {
 	union {
 		/** Freelist descriptor. */