From 79e7b4f698bdd8a921801dafeccd45b19d0e96ca Mon Sep 17 00:00:00 2001 From: Long Wu Date: Wed, 16 Oct 2024 16:17:59 +0800 Subject: [PATCH] net/nfp: fix RSS failed on VXLAN inner layer Before the commit 5126a904fae0 ("net/nfp: use offload flag to control VXLAN configuration"), in the initial logic 'nfp_net_start()' will enable the NFP_NET_CFG_CTRL_VXLAN flag if hardware has the capability, 'udp_tunnel_port_add()' and 'udp_tunnel_port_del()' just do the port add and delete action. But the commit 5126a904fae0 ("net/nfp: use offload flag to control VXLAN configuration") added another limitation of RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO over the VXLAN inner RSS flag of Tx wrongly, which caused the NFP_NET_CFG_CTRL_VXLAN cannot be enable, thus 'udp_tunnel_port_add()' and 'udp_tunnel_port_del()' can not done their works. This commit fix the problem and do a little of enhancement to the initial logic, move the logic of enable NFP_NET_CFG_CTRL_VXLAN into the 'udp_tunnel_port_add()', and add the logic of disable NFP_NET_CFG_CTRL_VXLAN into the 'udp_tunnel_port_del()', thus the whole solution more complete and easier to understand. Fixes: 5126a904fae0 ("net/nfp: use offload flag to control VXLAN configuration") Cc: stable@dpdk.org Signed-off-by: Long Wu Reviewed-by: Chaoyong He Reviewed-by: Peng Zhang --- drivers/net/nfp/nfp_ethdev.c | 47 ++++++++++++++++++-------------- drivers/net/nfp/nfp_net_common.c | 15 ++-------- drivers/net/nfp/nfp_net_common.h | 5 +++- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index b16fbe7db79..28161f56344 100644 --- a/drivers/net/nfp/nfp_ethdev.c +++ b/drivers/net/nfp/nfp_ethdev.c @@ -443,13 +443,6 @@ nfp_net_start(struct rte_eth_dev *dev) update |= NFP_NET_CFG_UPDATE_GEN | NFP_NET_CFG_UPDATE_RING; txmode = &dev->data->dev_conf.txmode; - /* Enable vxlan */ - if ((txmode->offloads & RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO) != 0) { - if ((hw->cap & NFP_NET_CFG_CTRL_VXLAN) != 0) { - new_ctrl |= NFP_NET_CFG_CTRL_VXLAN; - update |= NFP_NET_CFG_UPDATE_VXLAN; - } - } if ((hw->cap & NFP_NET_CFG_CTRL_RINGCFG) != 0) new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG; @@ -854,11 +847,13 @@ nfp_udp_tunnel_port_add(struct rte_eth_dev *dev, { int ret; uint32_t idx; + uint32_t ctrl; + struct nfp_hw *hw; uint16_t vxlan_port; - struct nfp_net_hw *hw; + struct nfp_net_hw *net_hw; enum rte_eth_tunnel_type tnl_type; - hw = dev->data->dev_private; + net_hw = dev->data->dev_private; vxlan_port = tunnel_udp->udp_port; tnl_type = tunnel_udp->prot_type; @@ -867,21 +862,26 @@ nfp_udp_tunnel_port_add(struct rte_eth_dev *dev, return -ENOTSUP; } - ret = nfp_net_find_vxlan_idx(hw, vxlan_port, &idx); + ret = nfp_net_find_vxlan_idx(net_hw, vxlan_port, &idx); if (ret != 0) { PMD_DRV_LOG(ERR, "Failed find valid vxlan idx"); return -EINVAL; } - if (hw->vxlan_usecnt[idx] == 0) { - ret = nfp_net_set_vxlan_port(hw, idx, vxlan_port); + if (net_hw->vxlan_usecnt[idx] == 0) { + hw = &net_hw->super; + ctrl = hw->ctrl | NFP_NET_CFG_CTRL_VXLAN; + + ret = nfp_net_set_vxlan_port(net_hw, idx, vxlan_port, ctrl); if (ret != 0) { PMD_DRV_LOG(ERR, "Failed set vxlan port"); return -EINVAL; } + + hw->ctrl = ctrl; } - hw->vxlan_usecnt[idx]++; + net_hw->vxlan_usecnt[idx]++; return 0; } @@ -892,11 +892,13 @@ nfp_udp_tunnel_port_del(struct rte_eth_dev *dev, { int ret; uint32_t idx; + uint32_t ctrl; + struct nfp_hw *hw; uint16_t vxlan_port; - struct nfp_net_hw *hw; + struct nfp_net_hw *net_hw; enum rte_eth_tunnel_type tnl_type; - hw = dev->data->dev_private; + net_hw = dev->data->dev_private; vxlan_port = tunnel_udp->udp_port; tnl_type = tunnel_udp->prot_type; @@ -905,20 +907,25 @@ nfp_udp_tunnel_port_del(struct rte_eth_dev *dev, return -ENOTSUP; } - ret = nfp_net_find_vxlan_idx(hw, vxlan_port, &idx); - if (ret != 0 || hw->vxlan_usecnt[idx] == 0) { + ret = nfp_net_find_vxlan_idx(net_hw, vxlan_port, &idx); + if (ret != 0 || net_hw->vxlan_usecnt[idx] == 0) { PMD_DRV_LOG(ERR, "Failed find valid vxlan idx"); return -EINVAL; } - hw->vxlan_usecnt[idx]--; + net_hw->vxlan_usecnt[idx]--; - if (hw->vxlan_usecnt[idx] == 0) { - ret = nfp_net_set_vxlan_port(hw, idx, 0); + if (net_hw->vxlan_usecnt[idx] == 0) { + hw = &net_hw->super; + ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_VXLAN; + + ret = nfp_net_set_vxlan_port(net_hw, idx, 0, ctrl); if (ret != 0) { PMD_DRV_LOG(ERR, "Failed set vxlan port"); return -EINVAL; } + + hw->ctrl = ctrl; } return 0; diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c index f76d5a68956..3ded3956b73 100644 --- a/drivers/net/nfp/nfp_net_common.c +++ b/drivers/net/nfp/nfp_net_common.c @@ -2154,9 +2154,9 @@ nfp_net_close_tx_queue(struct rte_eth_dev *dev) int nfp_net_set_vxlan_port(struct nfp_net_hw *net_hw, size_t idx, - uint16_t port) + uint16_t port, + uint32_t ctrl) { - int ret; uint32_t i; struct nfp_hw *hw = &net_hw->super; @@ -2172,16 +2172,7 @@ nfp_net_set_vxlan_port(struct nfp_net_hw *net_hw, (net_hw->vxlan_ports[i + 1] << 16) | net_hw->vxlan_ports[i]); } - rte_spinlock_lock(&hw->reconfig_lock); - - nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, NFP_NET_CFG_UPDATE_VXLAN); - rte_wmb(); - - ret = nfp_reconfig_real(hw, NFP_NET_CFG_UPDATE_VXLAN); - - rte_spinlock_unlock(&hw->reconfig_lock); - - return ret; + return nfp_reconfig(hw, ctrl, NFP_NET_CFG_UPDATE_VXLAN); } /* diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h index 6291a794b2b..64b8a38918e 100644 --- a/drivers/net/nfp/nfp_net_common.h +++ b/drivers/net/nfp/nfp_net_common.h @@ -345,7 +345,10 @@ void nfp_net_stop_rx_queue(struct rte_eth_dev *dev); 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_set_vxlan_port(struct nfp_net_hw *hw, + size_t idx, + uint16_t port, + uint32_t ctrl); void nfp_net_rx_desc_limits(struct nfp_net_hw_priv *hw_priv, uint16_t *min_rx_desc, uint16_t *max_rx_desc);