From: Long Wu <long...@corigine.com> The initial logic only support the single type metadata and this commit add the support of chained type metadata. This commit also make the relation between the RSS capability (v1/v2) and these two types of metadata more clear.
Signed-off-by: Long Wu <long...@corigine.com> Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com> Reviewed-by: Chaoyong He <chaoyong...@corigine.com> --- drivers/net/nfp/nfp_common.c | 23 +++++++ drivers/net/nfp/nfp_common.h | 7 +++ drivers/net/nfp/nfp_ctrl.h | 18 +++++- drivers/net/nfp/nfp_ethdev.c | 7 +-- drivers/net/nfp/nfp_ethdev_vf.c | 7 +-- drivers/net/nfp/nfp_rxtx.c | 108 ++++++++++++++++++++------------ 6 files changed, 121 insertions(+), 49 deletions(-) diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c index a545a10013..a1e37ada11 100644 --- a/drivers/net/nfp/nfp_common.c +++ b/drivers/net/nfp/nfp_common.c @@ -1584,6 +1584,29 @@ nfp_net_check_dma_mask(struct nfp_net_hw *hw, char *name) return 0; } +void +nfp_net_init_metadata_format(struct nfp_net_hw *hw) +{ + /* + * ABI 4.x and ctrl vNIC always use chained metadata, in other cases we allow use of + * single metadata if only RSS(v1) is supported by hw capability, and RSS(v2) + * also indicate that we are using chained metadata. + */ + if (NFD_CFG_MAJOR_VERSION_of(hw->ver) == 4) { + hw->meta_format = NFP_NET_METAFORMAT_CHANINED; + } else if ((hw->cap & NFP_NET_CFG_CTRL_CHAIN_META) != 0) { + hw->meta_format = NFP_NET_METAFORMAT_CHANINED; + /* + * RSS is incompatible with chained metadata. hw->cap just represents + * firmware's ability rather than the firmware's configuration. We decide + * to reduce the confusion to allow us can use hw->cap to identify RSS later. + */ + hw->cap &= ~NFP_NET_CFG_CTRL_RSS; + } else { + hw->meta_format = NFP_NET_METAFORMAT_SINGLE; + } +} + /* * Local variables: * c-file-style: "Linux" diff --git a/drivers/net/nfp/nfp_common.h b/drivers/net/nfp/nfp_common.h index 980f3cad89..d33675eb99 100644 --- a/drivers/net/nfp/nfp_common.h +++ b/drivers/net/nfp/nfp_common.h @@ -127,6 +127,11 @@ enum nfp_qcp_ptr { NFP_QCP_WRITE_PTR }; +enum nfp_net_meta_format { + NFP_NET_METAFORMAT_SINGLE, + NFP_NET_METAFORMAT_CHANINED, +}; + struct nfp_pf_dev { /* Backpointer to associated pci device */ struct rte_pci_device *pci_dev; @@ -203,6 +208,7 @@ struct nfp_net_hw { uint32_t max_mtu; uint32_t mtu; uint32_t rx_offset; + enum nfp_net_meta_format meta_format; /* Current values for control */ uint32_t ctrl; @@ -455,6 +461,7 @@ int nfp_net_tx_desc_limits(struct nfp_net_hw *hw, uint16_t *min_tx_desc, uint16_t *max_tx_desc); int nfp_net_check_dma_mask(struct nfp_net_hw *hw, char *name); +void nfp_net_init_metadata_format(struct nfp_net_hw *hw); #define NFP_NET_DEV_PRIVATE_TO_HW(adapter)\ (&((struct nfp_net_adapter *)adapter)->hw) diff --git a/drivers/net/nfp/nfp_ctrl.h b/drivers/net/nfp/nfp_ctrl.h index 1069ff9485..bdc39f8974 100644 --- a/drivers/net/nfp/nfp_ctrl.h +++ b/drivers/net/nfp/nfp_ctrl.h @@ -110,6 +110,7 @@ #define NFP_NET_CFG_CTRL_MSIX_TX_OFF (0x1 << 26) /* Disable MSIX for TX */ #define NFP_NET_CFG_CTRL_LSO2 (0x1 << 28) /* LSO/TSO (version 2) */ #define NFP_NET_CFG_CTRL_RSS2 (0x1 << 29) /* RSS (version 2) */ +#define NFP_NET_CFG_CTRL_CSUM_COMPLETE (0x1 << 30) /* Checksum complete */ #define NFP_NET_CFG_CTRL_LIVE_ADDR (0x1U << 31)/* live MAC addr change */ #define NFP_NET_CFG_UPDATE 0x0004 #define NFP_NET_CFG_UPDATE_GEN (0x1 << 0) /* General update */ @@ -135,6 +136,8 @@ #define NFP_NET_CFG_CTRL_LSO_ANY (NFP_NET_CFG_CTRL_LSO | NFP_NET_CFG_CTRL_LSO2) #define NFP_NET_CFG_CTRL_RSS_ANY (NFP_NET_CFG_CTRL_RSS | NFP_NET_CFG_CTRL_RSS2) +#define NFP_NET_CFG_CTRL_CHAIN_META (NFP_NET_CFG_CTRL_RSS2 | \ + NFP_NET_CFG_CTRL_CSUM_COMPLETE) /* * Read-only words (0x0030 - 0x0050): * @NFP_NET_CFG_VERSION: Firmware version number @@ -218,7 +221,7 @@ /* * RSS configuration (0x0100 - 0x01ac): - * Used only when NFP_NET_CFG_CTRL_RSS is enabled + * Used only when NFP_NET_CFG_CTRL_RSS_ANY is enabled * @NFP_NET_CFG_RSS_CFG: RSS configuration word * @NFP_NET_CFG_RSS_KEY: RSS "secret" key * @NFP_NET_CFG_RSS_ITBL: RSS indirection table @@ -334,6 +337,19 @@ /* PF multiport offset */ #define NFP_PF_CSR_SLICE_SIZE (32 * 1024) +/* + * nfp_net_cfg_ctrl_rss() - Get RSS flag based on firmware's capability + * @hw_cap: The firmware's capabilities + */ +static inline uint32_t +nfp_net_cfg_ctrl_rss(uint32_t hw_cap) +{ + if ((hw_cap & NFP_NET_CFG_CTRL_RSS2) != 0) + return NFP_NET_CFG_CTRL_RSS2; + + return NFP_NET_CFG_CTRL_RSS; +} + #endif /* _NFP_CTRL_H_ */ /* * Local variables: diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index fed7b1ab13..47d5dff16c 100644 --- a/drivers/net/nfp/nfp_ethdev.c +++ b/drivers/net/nfp/nfp_ethdev.c @@ -134,10 +134,7 @@ nfp_net_start(struct rte_eth_dev *dev) if (rxmode->mq_mode & RTE_ETH_MQ_RX_RSS) { nfp_net_rss_config_default(dev); update |= NFP_NET_CFG_UPDATE_RSS; - if (hw->cap & NFP_NET_CFG_CTRL_RSS2) - new_ctrl |= NFP_NET_CFG_CTRL_RSS2; - else - new_ctrl |= NFP_NET_CFG_CTRL_RSS; + new_ctrl |= nfp_net_cfg_ctrl_rss(hw->cap); } /* Enable device */ @@ -611,6 +608,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev) if (hw->cap & NFP_NET_CFG_CTRL_LSO2) hw->cap &= ~NFP_NET_CFG_CTRL_TXVLAN; + nfp_net_init_metadata_format(hw); + if (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 2) hw->rx_offset = NFP_NET_RX_OFFSET; else diff --git a/drivers/net/nfp/nfp_ethdev_vf.c b/drivers/net/nfp/nfp_ethdev_vf.c index c1f8a0fa0f..7834b2ee0c 100644 --- a/drivers/net/nfp/nfp_ethdev_vf.c +++ b/drivers/net/nfp/nfp_ethdev_vf.c @@ -95,10 +95,7 @@ nfp_netvf_start(struct rte_eth_dev *dev) if (rxmode->mq_mode & RTE_ETH_MQ_RX_RSS) { nfp_net_rss_config_default(dev); update |= NFP_NET_CFG_UPDATE_RSS; - if (hw->cap & NFP_NET_CFG_CTRL_RSS2) - new_ctrl |= NFP_NET_CFG_CTRL_RSS2; - else - new_ctrl |= NFP_NET_CFG_CTRL_RSS; + new_ctrl |= nfp_net_cfg_ctrl_rss(hw->cap); } /* Enable device */ @@ -373,6 +370,8 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev) if (hw->cap & NFP_NET_CFG_CTRL_LSO2) hw->cap &= ~NFP_NET_CFG_CTRL_TXVLAN; + nfp_net_init_metadata_format(hw); + if (NFD_CFG_MAJOR_VERSION_of(hw->ver) < 2) hw->rx_offset = NFP_NET_RX_OFFSET; else diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c index 17a04cec5e..1c5a230145 100644 --- a/drivers/net/nfp/nfp_rxtx.c +++ b/drivers/net/nfp/nfp_rxtx.c @@ -116,26 +116,18 @@ nfp_net_rx_queue_count(void *rx_queue) return count; } -/* nfp_net_parse_meta() - Parse the metadata from packet */ -static void -nfp_net_parse_meta(struct nfp_meta_parsed *meta, - struct nfp_net_rx_desc *rxd, - struct nfp_net_rxq *rxq, - struct rte_mbuf *mbuf) +/* nfp_net_parse_chained_meta() - Parse the chained metadata from packet */ +static bool +nfp_net_parse_chained_meta(uint8_t *meta_base, + rte_be32_t meta_header, + struct nfp_meta_parsed *meta) { + uint8_t *meta_offset; uint32_t meta_info; uint32_t vlan_info; - uint8_t *meta_offset; - struct nfp_net_hw *hw = rxq->hw; - if (unlikely((NFD_CFG_MAJOR_VERSION_of(hw->ver) < 2) || - NFP_DESC_META_LEN(rxd) == 0)) - return; - - meta_offset = rte_pktmbuf_mtod(mbuf, uint8_t *); - meta_offset -= NFP_DESC_META_LEN(rxd); - meta_info = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset); - meta_offset += 4; + meta_info = rte_be_to_cpu_32(meta_header); + meta_offset = meta_base + 4; for (; meta_info != 0; meta_info >>= NFP_NET_META_FIELD_SIZE, meta_offset += 4) { switch (meta_info & NFP_NET_META_FIELD_MASK) { @@ -157,9 +149,11 @@ nfp_net_parse_meta(struct nfp_meta_parsed *meta, break; default: /* Unsupported metadata can be a performance issue */ - return; + return false; } } + + return true; } /* @@ -170,33 +164,18 @@ nfp_net_parse_meta(struct nfp_meta_parsed *meta, */ static void nfp_net_parse_meta_hash(const struct nfp_meta_parsed *meta, - struct nfp_net_rx_desc *rxd, struct nfp_net_rxq *rxq, struct rte_mbuf *mbuf) { - uint32_t hash; - uint32_t hash_type; struct nfp_net_hw *hw = rxq->hw; if ((hw->ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0) return; - if (likely((hw->cap & NFP_NET_CFG_CTRL_RSS_ANY) != 0 && - NFP_DESC_META_LEN(rxd) != 0)) { - hash = meta->hash; - hash_type = meta->hash_type; - } else { - if ((rxd->rxd.flags & PCIE_DESC_RX_RSS) == 0) - return; - - hash = rte_be_to_cpu_32(*(uint32_t *)NFP_HASH_OFFSET); - hash_type = rte_be_to_cpu_32(*(uint32_t *)NFP_HASH_TYPE_OFFSET); - } - - mbuf->hash.rss = hash; + mbuf->hash.rss = meta->hash; mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH; - switch (hash_type) { + switch (meta->hash_type) { case NFP_NET_RSS_IPV4: mbuf->packet_type |= RTE_PTYPE_INNER_L3_IPV4; break; @@ -223,6 +202,21 @@ nfp_net_parse_meta_hash(const struct nfp_meta_parsed *meta, } } +/* + * nfp_net_parse_single_meta() - Parse the single metadata + * + * The RSS hash and hash-type are prepended to the packet data. + * Get it from metadata area. + */ +static inline void +nfp_net_parse_single_meta(uint8_t *meta_base, + rte_be32_t meta_header, + struct nfp_meta_parsed *meta) +{ + meta->hash_type = rte_be_to_cpu_32(meta_header); + meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)(meta_base + 4)); +} + /* * nfp_net_parse_meta_vlan() - Set mbuf vlan_strip data based on metadata info * @@ -304,6 +298,45 @@ nfp_net_parse_meta_qinq(const struct nfp_meta_parsed *meta, mb->ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED; } +/* nfp_net_parse_meta() - Parse the metadata from packet */ +static void +nfp_net_parse_meta(struct nfp_net_rx_desc *rxds, + struct nfp_net_rxq *rxq, + struct nfp_net_hw *hw, + struct rte_mbuf *mb) +{ + uint8_t *meta_base; + rte_be32_t meta_header; + struct nfp_meta_parsed meta = {}; + + if (unlikely(NFP_DESC_META_LEN(rxds) == 0)) + return; + + meta_base = rte_pktmbuf_mtod(mb, uint8_t *); + meta_base -= NFP_DESC_META_LEN(rxds); + meta_header = *(rte_be32_t *)meta_base; + + switch (hw->meta_format) { + case NFP_NET_METAFORMAT_CHANINED: + if (nfp_net_parse_chained_meta(meta_base, meta_header, &meta)) { + nfp_net_parse_meta_hash(&meta, rxq, mb); + nfp_net_parse_meta_vlan(&meta, rxds, rxq, mb); + nfp_net_parse_meta_qinq(&meta, rxq, mb); + } else { + PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!"); + } + break; + case NFP_NET_METAFORMAT_SINGLE: + if ((rxds->rxd.flags & PCIE_DESC_RX_RSS) != 0) { + nfp_net_parse_single_meta(meta_base, meta_header, &meta); + nfp_net_parse_meta_hash(&meta, rxq, mb); + } + break; + default: + PMD_RX_LOG(DEBUG, "RX metadata do not exist."); + } +} + /* * RX path design: * @@ -341,7 +374,6 @@ nfp_net_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) struct nfp_net_hw *hw; struct rte_mbuf *mb; struct rte_mbuf *new_mb; - struct nfp_meta_parsed meta; uint16_t nb_hold; uint64_t dma_addr; uint16_t avail; @@ -437,11 +469,7 @@ nfp_net_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) mb->next = NULL; mb->port = rxq->port_id; - memset(&meta, 0, sizeof(meta)); - nfp_net_parse_meta(&meta, rxds, rxq, mb); - nfp_net_parse_meta_hash(&meta, rxds, rxq, mb); - nfp_net_parse_meta_vlan(&meta, rxds, rxq, mb); - nfp_net_parse_meta_qinq(&meta, rxq, mb); + nfp_net_parse_meta(rxds, rxq, hw, mb); /* Checking the checksum flag */ nfp_net_rx_cksum(rxq, rxds, mb); -- 2.29.3