@@ -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
@@ -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);
@@ -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):
@@ -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
@@ -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);
@@ -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. */