From: Peng Zhang <peng.zh...@corigine.com> Control the offload of outer layer VLAN strip in QinQ mode through the RTE_ETH_QINQ_STRIP_OFFLOAD mask bit.
Signed-off-by: Peng Zhang <peng.zh...@corigine.com> Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com> Reviewed-by: Chaoyong He <chaoyong...@corigine.com> --- doc/guides/nics/features/nfp.ini | 1 + doc/guides/nics/nfp.rst | 1 + drivers/net/nfp/nfp_common.c | 19 ++++++++++++++- drivers/net/nfp/nfp_ctrl.h | 1 + drivers/net/nfp/nfp_rxtx.c | 41 ++++++++++++++++++++++++++++++++ drivers/net/nfp/nfp_rxtx.h | 3 ++- 6 files changed, 64 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/nfp.ini b/doc/guides/nics/features/nfp.ini index 9e075a680b..b15a1ec52c 100644 --- a/doc/guides/nics/features/nfp.ini +++ b/doc/guides/nics/features/nfp.ini @@ -17,6 +17,7 @@ RSS key update = Y RSS reta update = Y Flow control = Y VLAN offload = Y +QinQ offload = Y L3 checksum offload = Y L4 checksum offload = Y Basic stats = Y diff --git a/doc/guides/nics/nfp.rst b/doc/guides/nics/nfp.rst index fffff00f1e..2be15b63d3 100644 --- a/doc/guides/nics/nfp.rst +++ b/doc/guides/nics/nfp.rst @@ -293,3 +293,4 @@ Metadata with L2 (1W/4B) Tpid just be stored, now we don't handle it The vlan[0] is the innermost VLAN + The vlan[1] is the QinQ info diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c index f112a70980..d1822f6b71 100644 --- a/drivers/net/nfp/nfp_common.c +++ b/drivers/net/nfp/nfp_common.c @@ -195,7 +195,7 @@ nfp_net_log_device_information(const struct nfp_net_hw *hw) NFD_CFG_MAJOR_VERSION_of(hw->ver), NFD_CFG_MINOR_VERSION_of(hw->ver), hw->max_mtu); - PMD_INIT_LOG(INFO, "CAP: %#x, %s%s%s%s%s%s%s%s%s%s%s%s%s%s", hw->cap, + PMD_INIT_LOG(INFO, "CAP: %#x, %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", hw->cap, hw->cap & NFP_NET_CFG_CTRL_PROMISC ? "PROMISC " : "", hw->cap & NFP_NET_CFG_CTRL_L2BC ? "L2BCFILT " : "", hw->cap & NFP_NET_CFG_CTRL_L2MC ? "L2MCFILT " : "", @@ -203,6 +203,7 @@ nfp_net_log_device_information(const struct nfp_net_hw *hw) hw->cap & NFP_NET_CFG_CTRL_TXCSUM ? "TXCSUM " : "", hw->cap & NFP_NET_CFG_CTRL_RXVLAN ? "RXVLAN " : "", hw->cap & NFP_NET_CFG_CTRL_TXVLAN ? "TXVLAN " : "", + hw->cap & NFP_NET_CFG_CTRL_RXQINQ ? "RXQINQ " : "", hw->cap & NFP_NET_CFG_CTRL_SCATTER ? "SCATTER " : "", hw->cap & NFP_NET_CFG_CTRL_GATHER ? "GATHER " : "", hw->cap & NFP_NET_CFG_CTRL_LIVE_ADDR ? "LIVE_ADDR " : "", @@ -401,6 +402,11 @@ nfp_check_offloads(struct rte_eth_dev *dev) ctrl |= NFP_NET_CFG_CTRL_RXVLAN; } + if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) { + if (hw->cap & NFP_NET_CFG_CTRL_RXQINQ) + ctrl |= NFP_NET_CFG_CTRL_RXQINQ; + } + hw->mtu = dev->data->mtu; if (txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT) @@ -751,6 +757,9 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (hw->cap & NFP_NET_CFG_CTRL_RXVLAN) dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP; + if (hw->cap & NFP_NET_CFG_CTRL_RXQINQ) + dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP; + if (hw->cap & NFP_NET_CFG_CTRL_RXCSUM) dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | RTE_ETH_RX_OFFLOAD_UDP_CKSUM | @@ -1042,6 +1051,14 @@ nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask) new_ctrl &= ~NFP_NET_CFG_CTRL_RXVLAN; } + /* QinQ stripping setting */ + if (mask & RTE_ETH_QINQ_STRIP_MASK) { + if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP) + new_ctrl |= NFP_NET_CFG_CTRL_RXQINQ; + else + new_ctrl &= ~NFP_NET_CFG_CTRL_RXQINQ; + } + if (new_ctrl == hw->ctrl) return 0; diff --git a/drivers/net/nfp/nfp_ctrl.h b/drivers/net/nfp/nfp_ctrl.h index a90846fddf..106779c080 100644 --- a/drivers/net/nfp/nfp_ctrl.h +++ b/drivers/net/nfp/nfp_ctrl.h @@ -93,6 +93,7 @@ #define NFP_NET_CFG_CTRL_SCATTER (0x1 << 8) /* Scatter DMA */ #define NFP_NET_CFG_CTRL_GATHER (0x1 << 9) /* Gather DMA */ #define NFP_NET_CFG_CTRL_LSO (0x1 << 10) /* LSO/TSO */ +#define NFP_NET_CFG_CTRL_RXQINQ (0x1 << 13) /* Enable QINQ strip */ #define NFP_NET_CFG_CTRL_RINGCFG (0x1 << 16) /* Ring runtime changes */ #define NFP_NET_CFG_CTRL_RSS (0x1 << 17) /* RSS */ #define NFP_NET_CFG_CTRL_IRQMOD (0x1 << 18) /* Interrupt moderation */ diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c index fb271e6d96..40f1702bde 100644 --- a/drivers/net/nfp/nfp_rxtx.c +++ b/drivers/net/nfp/nfp_rxtx.c @@ -257,6 +257,46 @@ nfp_net_parse_meta_vlan(const struct nfp_meta_parsed *meta, } } +/* + * nfp_net_parse_meta_qinq() - Set mbuf qinq_strip data based on metadata info + * + * The out VLAN tci are prepended to the packet data. + * Extract and decode it and set the mbuf fields. + * + * If both RTE_MBUF_F_RX_VLAN and NFP_NET_CFG_CTRL_RXQINQ are set, the 2 VLANs + * have been stripped by the hardware and their TCIs are saved in + * mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer). + * If NFP_NET_CFG_CTRL_RXQINQ is set and RTE_MBUF_F_RX_VLAN is unset, only the + * outer VLAN is removed from packet data, but both tci are saved in + * mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer). + * + * qinq set & vlan set : meta->vlan_layer>=2, meta->vlan[0].offload=1, meta->vlan[1].offload=1 + * qinq set & vlan not set: meta->vlan_layer>=2, meta->vlan[1].offload=1,meta->vlan[0].offload=0 + * qinq not set & vlan set: meta->vlan_layer=1, meta->vlan[0].offload=1 + * qinq not set & vlan not set: meta->vlan_layer=0 + */ +static void +nfp_net_parse_meta_qinq(const struct nfp_meta_parsed *meta, + struct nfp_net_rxq *rxq, + struct rte_mbuf *mb) +{ + struct nfp_net_hw *hw = rxq->hw; + + if ((hw->ctrl & NFP_NET_CFG_CTRL_RXQINQ) == 0 || + (hw->cap & NFP_NET_CFG_CTRL_RXQINQ) == 0) + return; + + if (meta->vlan_layer < NFP_META_MAX_VLANS) + return; + + if (meta->vlan[0].offload == 0) + mb->vlan_tci = rte_cpu_to_le_16(meta->vlan[0].tci); + mb->vlan_tci_outer = rte_cpu_to_le_16(meta->vlan[1].tci); + PMD_RX_LOG(DEBUG, "Received outer vlan is %u inter vlan is %u", + mb->vlan_tci_outer, mb->vlan_tci); + mb->ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED; +} + /* * RX path design: * @@ -394,6 +434,7 @@ nfp_net_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 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); /* 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 a24ec9e560..e3e8b00b48 100644 --- a/drivers/net/nfp/nfp_rxtx.h +++ b/drivers/net/nfp/nfp_rxtx.h @@ -43,8 +43,9 @@ * starts at position 0 and only @vlan_layer entries contain valid * information. * - * Currently only 1 layer of vlan is supported, + * Currently only 2 layers of vlan are supported, * vlan[0] - vlan strip info + * vlan[1] - qinq strip info * * @vlan.offload: Flag indicates whether VLAN is offloaded * @vlan.tpid: Vlan TPID -- 2.29.3