diff --git a/doc/guides/nics/enic.rst b/doc/guides/nics/enic.rst index 5e80398bf3..fbc001d222 100644 --- a/doc/guides/nics/enic.rst +++ b/doc/guides/nics/enic.rst @@ -310,6 +310,18 @@ it through ``rte_eth_dev_udp_tunnel_port_{add,delete}``. However, as the current NIC has a single VXLAN port number, the user cannot configure multiple port numbers. +Geneve headers with non-zero options are not supported by default. To +use Geneve with options, update the VIC firmware to the latest version +and then set ``devargs`` parameter ``geneve-opt=1``. When Geneve with +options is enabled, flow API cannot be used as the features are +currently mutually exclusive. When this feature is successfully +enabled, PMD prints the following message. + +.. code-block:: console + + Geneve with options is enabled + + Ingress VLAN Rewrite -------------------- diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 74cbfc953d..e9930ce93f 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -65,6 +65,10 @@ New Features The lock-free stack implementation is enabled for aarch64 platforms. +* **Updated the enic driver.** + + * Added support for Geneve with options offload. + * **Added Hisilicon hns3 PMD.** Added the new ``hns3`` net driver for the inbuilt Hisilicon Network diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c index 8e190687d2..807d4096f8 100644 --- a/drivers/net/enic/base/vnic_dev.c +++ b/drivers/net/enic/base/vnic_dev.c @@ -1120,3 +1120,14 @@ int vnic_dev_capable_vxlan(struct vnic_dev *vdev) (a1 & (FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ)) == (FEATURE_VXLAN_IPV6 | FEATURE_VXLAN_MULTI_WQ); } + +int vnic_dev_capable_geneve(struct vnic_dev *vdev) +{ + u64 a0 = VIC_FEATURE_GENEVE; + u64 a1 = 0; + int wait = 1000; + int ret; + + ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait); + return ret == 0 && (a1 & FEATURE_GENEVE_OPTIONS); +} diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h index 270a47bd23..8a13634867 100644 --- a/drivers/net/enic/base/vnic_dev.h +++ b/drivers/net/enic/base/vnic_dev.h @@ -187,4 +187,5 @@ int vnic_dev_overlay_offload_ctrl(struct vnic_dev *vdev, int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay, u16 vxlan_udp_port_number); int vnic_dev_capable_vxlan(struct vnic_dev *vdev); +int vnic_dev_capable_geneve(struct vnic_dev *vdev); #endif /* _VNIC_DEV_H_ */ diff --git a/drivers/net/enic/base/vnic_devcmd.h b/drivers/net/enic/base/vnic_devcmd.h index fffe307e02..da60be7b0f 100644 --- a/drivers/net/enic/base/vnic_devcmd.h +++ b/drivers/net/enic/base/vnic_devcmd.h @@ -537,6 +537,7 @@ enum vnic_devcmd_cmd { * Control (Enable/Disable) overlay offloads on the given vnic * in: (u8) a0 = OVERLAY_FEATURE_NVGRE : NVGRE * a0 = OVERLAY_FEATURE_VXLAN : VxLAN + * a0 = OVERLAY_FEATURE_GENEVE : Geneve * in: (u8) a1 = OVERLAY_OFFLOAD_ENABLE : Enable or * a1 = OVERLAY_OFFLOAD_DISABLE : Disable or * a1 = OVERLAY_OFFLOAD_ENABLE_V2 : Enable with version 2 @@ -547,6 +548,7 @@ enum vnic_devcmd_cmd { /* * Configuration of overlay offloads feature on a given vNIC * in: (u8) a0 = OVERLAY_CFG_VXLAN_PORT_UPDATE : VxLAN + * OVERLAY_CFG_GENEVE_PORT_UPDATE : Geneve * in: (u16) a1 = unsigned short int port information */ CMD_OVERLAY_OFFLOAD_CFG = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 73), @@ -1081,6 +1083,7 @@ struct devcmd2_result { typedef enum { OVERLAY_FEATURE_NVGRE = 1, OVERLAY_FEATURE_VXLAN, + OVERLAY_FEATURE_GENEVE, OVERLAY_FEATURE_MAX, } overlay_feature_t; @@ -1089,6 +1092,7 @@ typedef enum { #define OVERLAY_OFFLOAD_ENABLE_V2 2 #define OVERLAY_CFG_VXLAN_PORT_UPDATE 0 +#define OVERLAY_CFG_GENEVE_PORT_UPDATE 1 /* * Use this enum to get the supported versions for each of these features @@ -1098,6 +1102,7 @@ typedef enum { typedef enum { VIC_FEATURE_VXLAN, VIC_FEATURE_RDMA, + VIC_FEATURE_GENEVE, VIC_FEATURE_MAX, } vic_feature_t; @@ -1112,6 +1117,8 @@ typedef enum { #define FEATURE_VXLAN_IPV6 (FEATURE_VXLAN_IPV6_INNER | \ FEATURE_VXLAN_IPV6_OUTER) +/* Support Geneve option bytes */ +#define FEATURE_GENEVE_OPTIONS (1 << 0) /* * CMD_CONFIG_GRPINTR subcommands diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index fac8d57fa2..6be52f9f15 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -133,6 +133,9 @@ struct enic { bool vxlan; bool disable_overlay; /* devargs disable_overlay=1 */ uint8_t enable_avx2_rx; /* devargs enable-avx2-rx=1 */ + uint8_t geneve_opt_avail; /* Geneve with options offload available */ + uint8_t geneve_opt_enabled; /* Geneve with options offload enabled */ + uint8_t geneve_opt_request; /* devargs geneve-opt=1 */ 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 */ diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c index 562401ae76..5b6b004c64 100644 --- a/drivers/net/enic/enic_ethdev.c +++ b/drivers/net/enic/enic_ethdev.c @@ -68,6 +68,7 @@ static const struct vic_speed_capa { #define ENIC_DEVARG_DISABLE_OVERLAY "disable-overlay" #define ENIC_DEVARG_ENABLE_AVX2_RX "enable-avx2-rx" +#define ENIC_DEVARG_GENEVE_OPT "geneve-opt" #define ENIC_DEVARG_IG_VLAN_REWRITE "ig-vlan-rewrite" RTE_INIT(enicpmd_init_log) @@ -128,10 +129,17 @@ enicpmd_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_op filter_op, void *arg) { + struct enic *enic = pmd_priv(dev); int ret = 0; ENICPMD_FUNC_TRACE(); + /* + * Currently, when Geneve with options offload is enabled, host + * cannot insert match-action rules. + */ + if (enic->geneve_opt_enabled) + return -ENOTSUP; switch (filter_type) { case RTE_ETH_FILTER_GENERIC: if (filter_op != RTE_ETH_FILTER_GET) @@ -1144,6 +1152,8 @@ static int enic_parse_zero_one(const char *key, enic->disable_overlay = b; if (strcmp(key, ENIC_DEVARG_ENABLE_AVX2_RX) == 0) enic->enable_avx2_rx = b; + if (strcmp(key, ENIC_DEVARG_GENEVE_OPT) == 0) + enic->geneve_opt_request = b; return 0; } @@ -1185,6 +1195,7 @@ static int enic_check_devargs(struct rte_eth_dev *dev) static const char *const valid_keys[] = { ENIC_DEVARG_DISABLE_OVERLAY, ENIC_DEVARG_ENABLE_AVX2_RX, + ENIC_DEVARG_GENEVE_OPT, ENIC_DEVARG_IG_VLAN_REWRITE, NULL}; struct enic *enic = pmd_priv(dev); @@ -1194,6 +1205,7 @@ static int enic_check_devargs(struct rte_eth_dev *dev) enic->disable_overlay = false; enic->enable_avx2_rx = false; + enic->geneve_opt_request = false; enic->ig_vlan_rewrite_mode = IG_VLAN_REWRITE_MODE_PASS_THRU; if (!dev->device->devargs) return 0; @@ -1204,6 +1216,8 @@ static int enic_check_devargs(struct rte_eth_dev *dev) enic_parse_zero_one, enic) < 0 || rte_kvargs_process(kvlist, ENIC_DEVARG_ENABLE_AVX2_RX, enic_parse_zero_one, enic) < 0 || + rte_kvargs_process(kvlist, ENIC_DEVARG_GENEVE_OPT, + enic_parse_zero_one, enic) < 0 || rte_kvargs_process(kvlist, ENIC_DEVARG_IG_VLAN_REWRITE, enic_parse_ig_vlan_rewrite, enic) < 0) { rte_kvargs_free(kvlist); @@ -1280,4 +1294,5 @@ RTE_PMD_REGISTER_KMOD_DEP(net_enic, "* igb_uio | uio_pci_generic | vfio-pci"); RTE_PMD_REGISTER_PARAM_STRING(net_enic, ENIC_DEVARG_DISABLE_OVERLAY "=0|1 " ENIC_DEVARG_ENABLE_AVX2_RX "=0|1 " + ENIC_DEVARG_GENEVE_OPT "=0|1 " ENIC_DEVARG_IG_VLAN_REWRITE "=trunk|untag|priority|pass"); diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index ce89b81549..6d17d04de9 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1704,6 +1704,16 @@ static int enic_dev_init(struct enic *enic) /* set up link status checking */ vnic_dev_notify_set(enic->vdev, -1); /* No Intr for notify */ + /* + * When Geneve with options offload is available, always disable it + * first as it can interfere with user flow rules. + */ + if (enic->geneve_opt_avail && + vnic_dev_overlay_offload_ctrl(enic->vdev, + OVERLAY_FEATURE_GENEVE, + OVERLAY_OFFLOAD_DISABLE)) { + dev_err(enic, "failed to disable geneve+option\n"); + } enic->overlay_offload = false; if (enic->disable_overlay && enic->vxlan) { /* @@ -1735,6 +1745,18 @@ static int enic_dev_init(struct enic *enic) enic->overlay_offload = true; dev_info(enic, "Overlay offload is enabled\n"); } + /* Geneve with options offload requires overlay offload */ + if (enic->overlay_offload && enic->geneve_opt_avail && + enic->geneve_opt_request) { + if (vnic_dev_overlay_offload_ctrl(enic->vdev, + OVERLAY_FEATURE_GENEVE, + OVERLAY_OFFLOAD_ENABLE)) { + dev_err(enic, "failed to enable geneve+option\n"); + } else { + enic->geneve_opt_enabled = 1; + dev_info(enic, "Geneve with options is enabled\n"); + } + } /* * Reset the vxlan port if HW vxlan parsing is available. It * is always enabled regardless of overlay offload diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 9405e1933e..742999cd05 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -179,6 +179,10 @@ int enic_get_vnic_config(struct enic *enic) enic->vxlan = ENIC_SETTING(enic, VXLAN) && vnic_dev_capable_vxlan(enic->vdev); + if (vnic_dev_capable_geneve(enic->vdev)) { + dev_info(NULL, "Geneve with options offload available\n"); + enic->geneve_opt_avail = 1; + } /* * Default hardware capabilities. enic_dev_init() may add additional * flags if it enables overlay offloads.