From 8a4efd17410c7896c78d7204219eca8b9d4a88d4 Mon Sep 17 00:00:00 2001 From: Hyong Youb Kim Date: Fri, 29 Jun 2018 02:29:36 -0700 Subject: [PATCH] net/enic: add handlers to add/delete vxlan port number The NIC has one configurable VXLAN port, which is set to the default 4789 upon vNIC reset. Adding a non-default port replaces this single VXLAN port. Deleting the previously added non-default port restores the VXLAN port to the hardware default. Signed-off-by: Hyong Youb Kim Reviewed-by: John Daley --- drivers/net/enic/enic.h | 4 ++ drivers/net/enic/enic_ethdev.c | 75 ++++++++++++++++++++++++++++++++++ drivers/net/enic/enic_main.c | 1 + 3 files changed, 80 insertions(+) diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f1895fe708..b611f0a24d 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -50,6 +50,9 @@ #define ENICPMD_FDIR_MAX 64 +/* HW default VXLAN port */ +#define ENIC_DEFAULT_VXLAN_PORT 4789 + /* * Interrupt 0: LSC and errors * Interrupt 1: rx queue 0 @@ -126,6 +129,7 @@ struct enic { bool nic_cfg_chk; /* NIC_CFG_CHK available */ bool udp_rss_weak; /* Bodega style UDP RSS */ uint8_t ig_vlan_rewrite_mode; /* devargs ig-vlan-rewrite */ + uint16_t vxlan_port; /* current vxlan port pushed to NIC */ unsigned int flags; unsigned int priv_flags; diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c index 111bdc82c7..117b362de3 100644 --- a/drivers/net/enic/enic_ethdev.c +++ b/drivers/net/enic/enic_ethdev.c @@ -789,6 +789,79 @@ static int enicpmd_dev_rx_queue_intr_disable(struct rte_eth_dev *eth_dev, return 0; } +static int udp_tunnel_common_check(struct enic *enic, + struct rte_eth_udp_tunnel *tnl) +{ + if (tnl->prot_type != RTE_TUNNEL_TYPE_VXLAN) + return -ENOTSUP; + if (!enic->overlay_offload) { + PMD_INIT_LOG(DEBUG, " vxlan (overlay offload) is not " + "supported\n"); + return -ENOTSUP; + } + return 0; +} + +static int update_vxlan_port(struct enic *enic, uint16_t port) +{ + if (vnic_dev_overlay_offload_cfg(enic->vdev, + OVERLAY_CFG_VXLAN_PORT_UPDATE, + port)) { + PMD_INIT_LOG(DEBUG, " failed to update vxlan port\n"); + return -EINVAL; + } + PMD_INIT_LOG(DEBUG, " updated vxlan port to %u\n", port); + enic->vxlan_port = port; + return 0; +} + +static int enicpmd_dev_udp_tunnel_port_add(struct rte_eth_dev *eth_dev, + struct rte_eth_udp_tunnel *tnl) +{ + struct enic *enic = pmd_priv(eth_dev); + int ret; + + ENICPMD_FUNC_TRACE(); + ret = udp_tunnel_common_check(enic, tnl); + if (ret) + return ret; + /* + * The NIC has 1 configurable VXLAN port number. "Adding" a new port + * number replaces it. + */ + if (tnl->udp_port == enic->vxlan_port || tnl->udp_port == 0) { + PMD_INIT_LOG(DEBUG, " %u is already configured or invalid\n", + tnl->udp_port); + return -EINVAL; + } + return update_vxlan_port(enic, tnl->udp_port); +} + +static int enicpmd_dev_udp_tunnel_port_del(struct rte_eth_dev *eth_dev, + struct rte_eth_udp_tunnel *tnl) +{ + struct enic *enic = pmd_priv(eth_dev); + int ret; + + ENICPMD_FUNC_TRACE(); + ret = udp_tunnel_common_check(enic, tnl); + if (ret) + return ret; + /* + * Clear the previously set port number and restore the + * hardware default port number. Some drivers disable VXLAN + * offloads when there are no configured port numbers. But + * enic does not do that as VXLAN is part of overlay offload, + * which is tied to inner RSS and TSO. + */ + if (tnl->udp_port != enic->vxlan_port) { + PMD_INIT_LOG(DEBUG, " %u is not a configured vxlan port\n", + tnl->udp_port); + return -EINVAL; + } + return update_vxlan_port(enic, ENIC_DEFAULT_VXLAN_PORT); +} + static const struct eth_dev_ops enicpmd_eth_dev_ops = { .dev_configure = enicpmd_dev_configure, .dev_start = enicpmd_dev_start, @@ -838,6 +911,8 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = { .reta_update = enicpmd_dev_rss_reta_update, .rss_hash_conf_get = enicpmd_dev_rss_hash_conf_get, .rss_hash_update = enicpmd_dev_rss_hash_update, + .udp_tunnel_port_add = enicpmd_dev_udp_tunnel_port_add, + .udp_tunnel_port_del = enicpmd_dev_udp_tunnel_port_del, }; static int enic_parse_disable_overlay(__rte_unused const char *key, diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 24de38d5e4..e202569860 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1585,6 +1585,7 @@ static int enic_dev_init(struct enic *enic) PKT_TX_OUTER_IP_CKSUM | PKT_TX_TUNNEL_MASK; enic->overlay_offload = true; + enic->vxlan_port = ENIC_DEFAULT_VXLAN_PORT; dev_info(enic, "Overlay offload is enabled\n"); } -- 2.20.1