Add the logics to support the feature of RSS packets based on the inner layer of VXLAN tunnel.
Signed-off-by: Chaoyong He <chaoyong...@corigine.com> Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com> * Changes since v1 - Don't expose the dependency relation of header files to source files. Depends-on: series-24819 ("preparation for the rte_flow offload of nfp PMD") --- drivers/net/nfp/flower/nfp_flower.c | 1 - drivers/net/nfp/flower/nfp_flower_ctrl.c | 1 - drivers/net/nfp/flower/nfp_flower_representor.c | 1 - drivers/net/nfp/nfp_common.c | 33 ++++++- drivers/net/nfp/nfp_common.h | 6 ++ drivers/net/nfp/nfp_ethdev.c | 111 +++++++++++++++++++++++- drivers/net/nfp/nfp_ethdev_vf.c | 1 - drivers/net/nfp/nfp_rxtx.c | 1 - 8 files changed, 148 insertions(+), 7 deletions(-) diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c index 3e97f5c..53d378c 100644 --- a/drivers/net/nfp/flower/nfp_flower.c +++ b/drivers/net/nfp/flower/nfp_flower.c @@ -12,7 +12,6 @@ #include "../nfp_common.h" #include "../nfp_logs.h" -#include "../nfp_ctrl.h" #include "../nfp_cpp_bridge.h" #include "../nfp_rxtx.h" #include "../nfpcore/nfp_mip.h" diff --git a/drivers/net/nfp/flower/nfp_flower_ctrl.c b/drivers/net/nfp/flower/nfp_flower_ctrl.c index df908ef..19ac8b0 100644 --- a/drivers/net/nfp/flower/nfp_flower_ctrl.c +++ b/drivers/net/nfp/flower/nfp_flower_ctrl.c @@ -8,7 +8,6 @@ #include "../nfp_common.h" #include "../nfp_logs.h" -#include "../nfp_ctrl.h" #include "../nfp_rxtx.h" #include "nfp_flower.h" #include "nfp_flower_ctrl.h" diff --git a/drivers/net/nfp/flower/nfp_flower_representor.c b/drivers/net/nfp/flower/nfp_flower_representor.c index 0e60f50..a73cf80 100644 --- a/drivers/net/nfp/flower/nfp_flower_representor.c +++ b/drivers/net/nfp/flower/nfp_flower_representor.c @@ -8,7 +8,6 @@ #include "../nfp_common.h" #include "../nfp_logs.h" -#include "../nfp_ctrl.h" #include "../nfp_rxtx.h" #include "../nfpcore/nfp_mip.h" #include "../nfpcore/nfp_rtsym.h" diff --git a/drivers/net/nfp/nfp_common.c b/drivers/net/nfp/nfp_common.c index 07781a1..53d134e 100644 --- a/drivers/net/nfp/nfp_common.c +++ b/drivers/net/nfp/nfp_common.c @@ -38,7 +38,6 @@ #include "nfpcore/nfp_nsp.h" #include "nfp_common.h" -#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" #include "nfp_cpp_bridge.h" @@ -1370,6 +1369,38 @@ } } +int +nfp_net_set_vxlan_port(struct nfp_net_hw *hw, + size_t idx, + uint16_t port) +{ + int ret; + uint32_t i; + + if (idx > NFP_NET_N_VXLAN_PORTS) { + PMD_DRV_LOG(ERR, "The idx value is out of range."); + return -ERANGE; + } + + hw->vxlan_ports[idx] = port; + + for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i += 2) { + nn_cfg_writel(hw, NFP_NET_CFG_VXLAN_PORT + i * sizeof(port), + (hw->vxlan_ports[i + 1] << 16) | 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_net_reconfig(hw, NFP_NET_CFG_UPDATE_VXLAN); + + rte_spinlock_unlock(&hw->reconfig_lock); + + return ret; +} + RTE_LOG_REGISTER_SUFFIX(nfp_logtype_init, init, NOTICE); RTE_LOG_REGISTER_SUFFIX(nfp_logtype_driver, driver, NOTICE); RTE_LOG_REGISTER_SUFFIX(nfp_logtype_cpp, cpp, NOTICE); diff --git a/drivers/net/nfp/nfp_common.h b/drivers/net/nfp/nfp_common.h index 27ea9c2..d7861a2 100644 --- a/drivers/net/nfp/nfp_common.h +++ b/drivers/net/nfp/nfp_common.h @@ -14,6 +14,8 @@ #ifndef _NFP_COMMON_H_ #define _NFP_COMMON_H_ +#include "nfp_ctrl.h" + #define NFP_NET_PMD_VERSION "0.1" #define PCI_VENDOR_ID_NETRONOME 0x19ee #define PCI_VENDOR_ID_CORIGINE 0x1da8 @@ -209,6 +211,9 @@ struct nfp_net_hw { int stride_rx; int stride_tx; + uint16_t vxlan_ports[NFP_NET_N_VXLAN_PORTS]; + uint8_t vxlan_usecnt[NFP_NET_N_VXLAN_PORTS]; + uint8_t *qcp_cfg; rte_spinlock_t reconfig_lock; @@ -438,6 +443,7 @@ int nfp_net_rss_hash_conf_get(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); #define NFP_NET_DEV_PRIVATE_TO_HW(adapter)\ (&((struct nfp_net_adapter *)adapter)->hw) diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index e131021..d938e01 100644 --- a/drivers/net/nfp/nfp_ethdev.c +++ b/drivers/net/nfp/nfp_ethdev.c @@ -33,7 +33,6 @@ #include "nfpcore/nfp_nsp.h" #include "nfp_common.h" -#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" #include "nfp_cpp_bridge.h" @@ -138,6 +137,10 @@ update |= NFP_NET_CFG_UPDATE_GEN | NFP_NET_CFG_UPDATE_RING; + /* Enable vxlan */ + new_ctrl |= NFP_NET_CFG_CTRL_VXLAN; + update |= NFP_NET_CFG_UPDATE_VXLAN; + if (hw->cap & NFP_NET_CFG_CTRL_RINGCFG) new_ctrl |= NFP_NET_CFG_CTRL_RINGCFG; @@ -319,6 +322,110 @@ return 0; } +static int +nfp_net_find_vxlan_idx(struct nfp_net_hw *hw, + uint16_t port, + uint32_t *idx) +{ + uint32_t i; + int free_idx = -1; + + for (i = 0; i < NFP_NET_N_VXLAN_PORTS; i++) { + if (hw->vxlan_ports[i] == port) { + free_idx = i; + break; + } + + if (hw->vxlan_usecnt[i] == 0) { + free_idx = i; + break; + } + } + + if (free_idx == -1) + return -EINVAL; + + *idx = free_idx; + + return 0; +} + +static int +nfp_udp_tunnel_port_add(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *tunnel_udp) +{ + int ret; + uint32_t idx; + uint16_t vxlan_port; + struct nfp_net_hw *hw; + enum rte_eth_tunnel_type tnl_type; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + vxlan_port = tunnel_udp->udp_port; + tnl_type = tunnel_udp->prot_type; + + if (tnl_type != RTE_ETH_TUNNEL_TYPE_VXLAN) { + PMD_DRV_LOG(ERR, "Not VXLAN tunnel"); + return -ENOTSUP; + } + + ret = nfp_net_find_vxlan_idx(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 (ret != 0) { + PMD_DRV_LOG(ERR, "Failed set vxlan port"); + return -EINVAL; + } + } + + hw->vxlan_usecnt[idx]++; + + return 0; +} + +static int +nfp_udp_tunnel_port_del(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *tunnel_udp) +{ + int ret; + uint32_t idx; + uint16_t vxlan_port; + struct nfp_net_hw *hw; + enum rte_eth_tunnel_type tnl_type; + + hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private); + vxlan_port = tunnel_udp->udp_port; + tnl_type = tunnel_udp->prot_type; + + if (tnl_type != RTE_ETH_TUNNEL_TYPE_VXLAN) { + PMD_DRV_LOG(ERR, "Not VXLAN tunnel"); + return -ENOTSUP; + } + + ret = nfp_net_find_vxlan_idx(hw, vxlan_port, &idx); + if (ret != 0 || hw->vxlan_usecnt[idx] == 0) { + PMD_DRV_LOG(ERR, "Failed find valid vxlan idx"); + return -EINVAL; + } + + hw->vxlan_usecnt[idx]--; + + if (hw->vxlan_usecnt[idx] == 0) { + ret = nfp_net_set_vxlan_port(hw, idx, 0); + if (ret != 0) { + PMD_DRV_LOG(ERR, "Failed set vxlan port"); + return -EINVAL; + } + } + + return 0; +} + /* Initialise and register driver with DPDK Application */ static const struct eth_dev_ops nfp_net_eth_dev_ops = { .dev_configure = nfp_net_configure, @@ -347,6 +454,8 @@ .tx_queue_release = nfp_net_tx_queue_release, .rx_queue_intr_enable = nfp_rx_queue_intr_enable, .rx_queue_intr_disable = nfp_rx_queue_intr_disable, + .udp_tunnel_port_add = nfp_udp_tunnel_port_add, + .udp_tunnel_port_del = nfp_udp_tunnel_port_del, }; static inline int diff --git a/drivers/net/nfp/nfp_ethdev_vf.c b/drivers/net/nfp/nfp_ethdev_vf.c index 6c6caef..6556dfe 100644 --- a/drivers/net/nfp/nfp_ethdev_vf.c +++ b/drivers/net/nfp/nfp_ethdev_vf.c @@ -19,7 +19,6 @@ #include "nfpcore/nfp_rtsym.h" #include "nfp_common.h" -#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c index b8c874d..9e4fa8d 100644 --- a/drivers/net/nfp/nfp_rxtx.c +++ b/drivers/net/nfp/nfp_rxtx.c @@ -17,7 +17,6 @@ #include <ethdev_pci.h> #include "nfp_common.h" -#include "nfp_ctrl.h" #include "nfp_rxtx.h" #include "nfp_logs.h" #include "nfpcore/nfp_mip.h" -- 1.8.3.1