summaryrefslogtreecommitdiffstats
path: root/src/plugins/dpdk
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2022-01-13 00:28:14 +0100
committerDamjan Marion <damarion@cisco.com>2022-01-14 18:37:55 +0100
commit549838c81bd0d995f2b8569955afc33132582c77 (patch)
tree2b5317407fca2e8e53e44eb11ed6da758cf5fc75 /src/plugins/dpdk
parentf8dd9d8af135363631e4d3a366e6ccd89431aa99 (diff)
dpdk: refactor device setup
Type: improvement Change-Id: I9772088bca176fd0fdb162677ec55c59aa8f3adf Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/plugins/dpdk')
-rw-r--r--src/plugins/dpdk/CMakeLists.txt1
-rw-r--r--src/plugins/dpdk/device/device.c2
-rw-r--r--src/plugins/dpdk/device/dpdk.h107
-rw-r--r--src/plugins/dpdk/device/dpdk_priv.h2
-rw-r--r--src/plugins/dpdk/device/driver.c145
-rw-r--r--src/plugins/dpdk/device/format.c159
-rw-r--r--src/plugins/dpdk/device/init.c452
7 files changed, 328 insertions, 540 deletions
diff --git a/src/plugins/dpdk/CMakeLists.txt b/src/plugins/dpdk/CMakeLists.txt
index b53f4ad2375..91cf236ea05 100644
--- a/src/plugins/dpdk/CMakeLists.txt
+++ b/src/plugins/dpdk/CMakeLists.txt
@@ -134,6 +134,7 @@ add_vpp_plugin(dpdk
device/cli.c
device/common.c
device/device.c
+ device/driver.c
device/flow.c
device/format.c
device/init.c
diff --git a/src/plugins/dpdk/device/device.c b/src/plugins/dpdk/device/device.c
index b8418278fba..c9061a9949a 100644
--- a/src/plugins/dpdk/device/device.c
+++ b/src/plugins/dpdk/device/device.c
@@ -547,7 +547,7 @@ dpdk_subif_add_del_function (vnet_main_t * vnm,
xd->num_subifs--;
/* currently we program VLANS only for IXGBE VF */
- if (xd->pmd != VNET_DPDK_PMD_IXGBEVF)
+ if (xd->driver->program_vlans == 0)
goto done;
if (t->sub.eth.flags.no_tags == 1)
diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h
index 1ebda6c5677..f1cd17da1cd 100644
--- a/src/plugins/dpdk/device/dpdk.h
+++ b/src/plugins/dpdk/device/dpdk.h
@@ -45,79 +45,6 @@ extern vnet_device_class_t dpdk_device_class;
extern vlib_node_registration_t dpdk_input_node;
extern vlib_node_registration_t admin_up_down_process_node;
-#if RTE_VERSION < RTE_VERSION_NUM(20, 8, 0, 0)
-#define DPDK_MLX5_PMD_NAME "net_mlx5"
-#else
-#define DPDK_MLX5_PMD_NAME "mlx5_pci"
-#endif
-
-#define foreach_dpdk_pmd \
- _ ("net_thunderx", THUNDERX) \
- _ ("net_e1000_em", E1000EM) \
- _ ("net_e1000_igb", IGB) \
- _ ("net_e1000_igb_vf", IGBVF) \
- _ ("net_ixgbe", IXGBE) \
- _ ("net_ixgbe_vf", IXGBEVF) \
- _ ("net_i40e", I40E) \
- _ ("net_i40e_vf", I40EVF) \
- _ ("net_ice", ICE) \
- _ ("net_iavf", IAVF) \
- _ ("net_igc", IGC) \
- _ ("net_virtio", VIRTIO) \
- _ ("net_enic", ENIC) \
- _ ("net_vmxnet3", VMXNET3) \
- _ ("AF_PACKET PMD", AF_PACKET) \
- _ ("net_fm10k", FM10K) \
- _ ("net_cxgbe", CXGBE) \
- _ ("net_mlx4", MLX4) \
- _ (DPDK_MLX5_PMD_NAME, MLX5) \
- _ ("net_dpaa2", DPAA2) \
- _ ("net_virtio_user", VIRTIO_USER) \
- _ ("net_vhost", VHOST_ETHER) \
- _ ("net_ena", ENA) \
- _ ("net_failsafe", FAILSAFE) \
- _ ("net_liovf", LIOVF_ETHER) \
- _ ("net_qede", QEDE) \
- _ ("net_netvsc", NETVSC) \
- _ ("net_bnxt", BNXT)
-
-typedef enum
-{
- VNET_DPDK_PMD_NONE,
-#define _(s,f) VNET_DPDK_PMD_##f,
- foreach_dpdk_pmd
-#undef _
- VNET_DPDK_PMD_UNKNOWN, /* must be last */
-} dpdk_pmd_t;
-
-#define forach_dpdk_port_type \
- _ (ETH_1G, "GigabitEthernet") \
- _ (ETH_2_5G, "Two_FiveGigabitEthernet") \
- _ (ETH_5G, "FiveGigabitEthernet") \
- _ (ETH_10G, "TenGigabitEthernet") \
- _ (ETH_20G, "TwentyGigabitEthernet") \
- _ (ETH_25G, "TwentyFiveGigabitEthernet") \
- _ (ETH_40G, "FortyGigabitEthernet") \
- _ (ETH_50G, "FiftyGigabitEthernet") \
- _ (ETH_56G, "FiftySixGigabitEthernet") \
- _ (ETH_100G, "HundredGigabitEthernet") \
- _ (ETH_200G, "TwoHundredGigabitEthernet") \
- _ (ETH_SWITCH, "EthernetSwitch") \
- _ (ETH_VF, "VirtualFunctionEthernet") \
- _ (AF_PACKET, "af_packet") \
- _ (VIRTIO_USER, "VirtioUser") \
- _ (VHOST_ETHER, "VhostEthernet") \
- _ (FAILSAFE, "FailsafeEthernet") \
- _ (NETVSC, "NetVSC")
-
-typedef enum
-{
- VNET_DPDK_PORT_TYPE_UNKNOWN = 0,
-#define _(n, s) VNET_DPDK_PORT_TYPE_##n,
- forach_dpdk_port_type
-#undef _
-} dpdk_port_type_t;
-
typedef uint16_t dpdk_portid_t;
#define foreach_dpdk_device_flags \
@@ -133,12 +60,12 @@ typedef uint16_t dpdk_portid_t;
_ (13, INT_SUPPORTED, "int-supported") \
_ (14, INT_UNMASKABLE, "int-unmaskable")
-enum
+typedef enum
{
#define _(a, b, c) DPDK_DEVICE_FLAG_##b = (1 << a),
foreach_dpdk_device_flags
#undef _
-};
+} dpdk_device_flag_t;
typedef struct
{
@@ -169,6 +96,31 @@ typedef struct
clib_spinlock_t lock;
} dpdk_tx_queue_t;
+typedef struct
+{
+ const char *name;
+ const char *desc;
+} dpdk_driver_name_t;
+
+typedef struct
+{
+ dpdk_driver_name_t *drivers;
+ const char *interface_name_prefix;
+ u16 n_rx_desc;
+ u16 n_tx_desc;
+ u32 supported_flow_actions;
+ i32 enable_lsc_int : 1;
+ i32 enable_rxq_int : 1;
+ i32 disable_rx_scatter : 1;
+ i32 program_vlans : 1;
+ i32 mq_mode_none : 1;
+ i32 interface_number_from_port_id : 1;
+ i32 use_intel_phdr_cksum : 1;
+ i32 int_unmaskable : 1;
+} dpdk_driver_t;
+
+dpdk_driver_t *dpdk_driver_find (const char *name, const char **desc);
+
typedef union
{
struct
@@ -216,15 +168,15 @@ typedef struct
/* DPDK device port number */
dpdk_portid_t port_id;
- dpdk_pmd_t pmd:8;
i8 cpu_socket;
CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
u64 enabled_tx_off;
u64 enabled_rx_off;
+ dpdk_driver_t *driver;
u8 *name;
- u8 *interface_name_suffix;
+ const char *if_desc;
/* number of sub-interfaces */
u16 num_subifs;
@@ -244,7 +196,6 @@ typedef struct
struct rte_eth_stats last_stats;
struct rte_eth_xstat *xstats;
f64 time_last_stats_update;
- dpdk_port_type_t port_type;
/* mac address */
u8 *default_mac_address;
diff --git a/src/plugins/dpdk/device/dpdk_priv.h b/src/plugins/dpdk/device/dpdk_priv.h
index e170134052d..4e4438a007e 100644
--- a/src/plugins/dpdk/device/dpdk_priv.h
+++ b/src/plugins/dpdk/device/dpdk_priv.h
@@ -16,8 +16,6 @@
#define DPDK_NB_RX_DESC_DEFAULT 1024
#define DPDK_NB_TX_DESC_DEFAULT 1024
#define DPDK_MAX_LRO_SIZE_DEFAULT 65536
-#define DPDK_NB_RX_DESC_VIRTIO 256
-#define DPDK_NB_TX_DESC_VIRTIO 256
/* These args appear by themselves */
#define foreach_eal_double_hyphen_predicate_arg \
diff --git a/src/plugins/dpdk/device/driver.c b/src/plugins/dpdk/device/driver.c
new file mode 100644
index 00000000000..11d65f7de94
--- /dev/null
+++ b/src/plugins/dpdk/device/driver.c
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2021 Cisco Systems, Inc.
+ */
+
+#include <vlib/vlib.h>
+
+#include <dpdk/device/dpdk.h>
+
+static const u32 supported_flow_actions_intel =
+ (VNET_FLOW_ACTION_MARK | VNET_FLOW_ACTION_REDIRECT_TO_NODE |
+ VNET_FLOW_ACTION_REDIRECT_TO_QUEUE | VNET_FLOW_ACTION_BUFFER_ADVANCE |
+ VNET_FLOW_ACTION_COUNT | VNET_FLOW_ACTION_DROP | VNET_FLOW_ACTION_RSS);
+
+#define DPDK_DRIVERS(...) \
+ (dpdk_driver_name_t[]) \
+ { \
+ __VA_ARGS__, {} \
+ }
+
+static dpdk_driver_t dpdk_drivers[] = {
+ {
+ .drivers = DPDK_DRIVERS ({ "net_ice", "Intel E810 Family" },
+ { "net_igc", "Intel I225 2.5G Family" },
+ { "net_e1000_igb", "Intel e1000" },
+ { "net_e1000_em", "Intel 82540EM (e1000)" }),
+ .enable_rxq_int = 1,
+ .supported_flow_actions = supported_flow_actions_intel,
+ .use_intel_phdr_cksum = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_ixgbe", "Intel 82599" }),
+ .enable_rxq_int = 1,
+ .program_vlans = 1,
+ .supported_flow_actions = supported_flow_actions_intel,
+ .use_intel_phdr_cksum = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_i40e", "Intel X710/XL710 Family" }),
+ .enable_rxq_int = 1,
+ .supported_flow_actions = supported_flow_actions_intel,
+ .use_intel_phdr_cksum = 1,
+ .int_unmaskable = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_liovf", "Cavium Lio VF" },
+ { "net_thunderx", "Cavium ThunderX" }),
+ .interface_name_prefix = "VirtualFunctionEthernet",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_iavf", "Intel iAVF" },
+ { "net_i40e_vf", "Intel X710/XL710 Family VF" }),
+ .interface_name_prefix = "VirtualFunctionEthernet",
+ .supported_flow_actions = supported_flow_actions_intel,
+ .use_intel_phdr_cksum = 1,
+ .int_unmaskable = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_e1000_igb_vf", "Intel e1000 VF" },
+ { "net_ixgbe_vf", "Intel 82599 VF" }),
+ .interface_name_prefix = "VirtualFunctionEthernet",
+ .use_intel_phdr_cksum = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_dpaa2", "NXP DPAA2 Mac" }),
+ .interface_name_prefix = "TenGigabitEthernet",
+ },
+ {
+ .drivers =
+ DPDK_DRIVERS ({ "net_fm10k", "Intel FM10000 Family Ethernet Switch" }),
+ .interface_name_prefix = "EthernetSwitch",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_cxgbe", "Chelsio T4/T5" }),
+ .interface_number_from_port_id = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_mlx4", "Mellanox ConnectX-3 Family" },
+ { "net_qede", "Cavium QLogic FastLinQ QL4xxxx" },
+ { "net_bnxt", "Broadcom NetXtreme E/S-Series" }),
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_virtio_user", "Virtio User" }),
+ .interface_name_prefix = "VirtioUser",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_vhost", "VhostEthernet" }),
+ .interface_name_prefix = "VhostEthernet",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "mlx5_pci", "Mellanox ConnectX-4 Family" },
+ { "net_enic", "Cisco VIC" }),
+ .use_intel_phdr_cksum = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_failsafe", "FailsafeEthernet" }),
+ .interface_name_prefix = "FailsafeEthernet",
+ .enable_lsc_int = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "AF_PACKET PMD", "af_packet" }),
+ .interface_name_prefix = "af_packet",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_netvsc", "Microsoft Hyper-V Netvsc" }),
+ .interface_name_prefix = "NetVSC",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_ena", "AWS ENA VF" }),
+ .interface_name_prefix = "VirtualFunctionEthernet",
+ .enable_rxq_int = 1,
+ .disable_rx_scatter = 1,
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_vmxnet3", "VMware VMXNET3" }),
+ .interface_name_prefix = "GigabitEthernet",
+ },
+ {
+ .drivers = DPDK_DRIVERS ({ "net_virtio", "Red Hat Virtio" }),
+ .interface_name_prefix = "GigabitEthernet",
+ .n_rx_desc = 256,
+ .n_tx_desc = 256,
+ .mq_mode_none = 1,
+ }
+};
+
+dpdk_driver_t *
+dpdk_driver_find (const char *name, const char **desc)
+{
+ for (int i = 0; i < ARRAY_LEN (dpdk_drivers); i++)
+ {
+ dpdk_driver_t *dr = dpdk_drivers + i;
+ dpdk_driver_name_t *dn = dr->drivers;
+
+ while (dn->name)
+ {
+ if (name && !strcmp (name, dn->name))
+ {
+ *desc = dn->desc;
+ return dr;
+ }
+ dn++;
+ }
+ }
+ return 0;
+}
diff --git a/src/plugins/dpdk/device/format.c b/src/plugins/dpdk/device/format.c
index e8aca247be5..4a4b4110b9f 100644
--- a/src/plugins/dpdk/device/format.c
+++ b/src/plugins/dpdk/device/format.c
@@ -147,49 +147,14 @@
#define foreach_dpdk_pkt_dyn_rx_offload_flag \
_ (RX_TIMESTAMP, 0, "Timestamp field is valid")
-static char *device_name_by_port_type[] = {
-#define _(n, s) [VNET_DPDK_PORT_TYPE_##n] = (s),
- forach_dpdk_port_type
-#undef _
-};
-
u8 *
format_dpdk_device_name (u8 * s, va_list * args)
{
dpdk_main_t *dm = &dpdk_main;
- char *devname_format;
- char *device_name = 0;
u32 i = va_arg (*args, u32);
dpdk_device_t *xd = vec_elt_at_index (dm->devices, i);
- struct rte_eth_dev_info dev_info;
- struct rte_pci_device *pci_dev;
- u8 *ret;
-
- if (xd->name)
- return format (s, "%s", xd->name);
-
- if (dm->conf->interface_name_format_decimal)
- devname_format = "%s%d/%d/%d";
- else
- devname_format = "%s%x/%x/%x";
-
- if (xd->port_type < ARRAY_LEN (device_name_by_port_type))
- device_name = device_name_by_port_type[xd->port_type];
-
- device_name = device_name ? device_name : "UnknownEthernet";
-
- rte_eth_dev_info_get (xd->port_id, &dev_info);
- pci_dev = dpdk_get_pci_device (&dev_info);
-
- if (pci_dev && xd->port_type != VNET_DPDK_PORT_TYPE_FAILSAFE)
- ret = format (s, devname_format, device_name, pci_dev->addr.bus,
- pci_dev->addr.devid, pci_dev->addr.function);
- else
- ret = format (s, "%s%d", device_name, xd->port_id);
- if (xd->interface_name_suffix)
- return format (ret, "/%s", xd->interface_name_suffix);
- return ret;
+ return format (s, "%v", xd->name);
}
u8 *
@@ -211,126 +176,12 @@ static u8 *
format_dpdk_device_type (u8 * s, va_list * args)
{
dpdk_main_t *dm = &dpdk_main;
- char *dev_type;
u32 i = va_arg (*args, u32);
- switch (dm->devices[i].pmd)
- {
- case VNET_DPDK_PMD_E1000EM:
- dev_type = "Intel 82540EM (e1000)";
- break;
-
- case VNET_DPDK_PMD_IGB:
- dev_type = "Intel e1000";
- break;
-
- case VNET_DPDK_PMD_I40E:
- dev_type = "Intel X710/XL710 Family";
- break;
-
- case VNET_DPDK_PMD_I40EVF:
- dev_type = "Intel X710/XL710 Family VF";
- break;
-
- case VNET_DPDK_PMD_ICE:
- dev_type = "Intel E810 Family";
- break;
-
- case VNET_DPDK_PMD_IAVF:
- dev_type = "Intel iAVF";
- break;
-
- case VNET_DPDK_PMD_FM10K:
- dev_type = "Intel FM10000 Family Ethernet Switch";
- break;
-
- case VNET_DPDK_PMD_IGBVF:
- dev_type = "Intel e1000 VF";
- break;
-
- case VNET_DPDK_PMD_VIRTIO:
- dev_type = "Red Hat Virtio";
- break;
-
- case VNET_DPDK_PMD_IXGBEVF:
- dev_type = "Intel 82599 VF";
- break;
-
- case VNET_DPDK_PMD_IXGBE:
- dev_type = "Intel 82599";
- break;
-
- case VNET_DPDK_PMD_ENIC:
- dev_type = "Cisco VIC";
- break;
-
- case VNET_DPDK_PMD_CXGBE:
- dev_type = "Chelsio T4/T5";
- break;
-
- case VNET_DPDK_PMD_MLX4:
- dev_type = "Mellanox ConnectX-3 Family";
- break;
-
- case VNET_DPDK_PMD_MLX5:
- dev_type = "Mellanox ConnectX-4 Family";
- break;
-
- case VNET_DPDK_PMD_VMXNET3:
- dev_type = "VMware VMXNET3";
- break;
-
- case VNET_DPDK_PMD_AF_PACKET:
- dev_type = "af_packet";
- break;
-
- case VNET_DPDK_PMD_DPAA2:
- dev_type = "NXP DPAA2 Mac";
- break;
-
- case VNET_DPDK_PMD_VIRTIO_USER:
- dev_type = "Virtio User";
- break;
-
- case VNET_DPDK_PMD_THUNDERX:
- dev_type = "Cavium ThunderX";
- break;
-
- case VNET_DPDK_PMD_VHOST_ETHER:
- dev_type = "VhostEthernet";
- break;
-
- case VNET_DPDK_PMD_ENA:
- dev_type = "AWS ENA VF";
- break;
-
- case VNET_DPDK_PMD_FAILSAFE:
- dev_type = "FailsafeEthernet";
- break;
-
- case VNET_DPDK_PMD_LIOVF_ETHER:
- dev_type = "Cavium Lio VF";
- break;
-
- case VNET_DPDK_PMD_QEDE:
- dev_type = "Cavium QLogic FastLinQ QL4xxxx";
- break;
-
- case VNET_DPDK_PMD_NETVSC:
- dev_type = "Microsoft Hyper-V Netvsc";
- break;
-
- case VNET_DPDK_PMD_BNXT:
- dev_type = "Broadcom NetXtreme E/S-Series";
- break;
-
- default:
- case VNET_DPDK_PMD_UNKNOWN:
- dev_type = "### UNKNOWN ###";
- break;
- }
-
- return format (s, dev_type);
+ if (dm->devices[i].if_desc)
+ return format (s, dm->devices[i].if_desc);
+ else
+ return format (s, "### UNKNOWN ###");
}
static u8 *
diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c
index 1d3e061aaaf..5e06e48d37e 100644
--- a/src/plugins/dpdk/device/init.c
+++ b/src/plugins/dpdk/device/init.c
@@ -43,42 +43,30 @@
#include <dpdk/device/dpdk_priv.h>
-#define ETHER_MAX_LEN 1518 /**< Maximum frame len, including CRC. */
-
dpdk_main_t dpdk_main;
dpdk_config_main_t dpdk_config_main;
#define LINK_STATE_ELOGS 0
-/* Port configuration, mildly modified Intel app values */
-
-static dpdk_port_type_t
-port_type_from_speed_capa (struct rte_eth_dev_info *dev_info)
+/* dev_info.speed_capa -> interface name mapppings */
+const struct
{
-
- if (dev_info->speed_capa & ETH_LINK_SPEED_100G)
- return VNET_DPDK_PORT_TYPE_ETH_100G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_56G)
- return VNET_DPDK_PORT_TYPE_ETH_56G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_50G)
- return VNET_DPDK_PORT_TYPE_ETH_50G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_40G)
- return VNET_DPDK_PORT_TYPE_ETH_40G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_25G)
- return VNET_DPDK_PORT_TYPE_ETH_25G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_20G)
- return VNET_DPDK_PORT_TYPE_ETH_20G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_10G)
- return VNET_DPDK_PORT_TYPE_ETH_10G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_5G)
- return VNET_DPDK_PORT_TYPE_ETH_5G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_2_5G)
- return VNET_DPDK_PORT_TYPE_ETH_2_5G;
- else if (dev_info->speed_capa & ETH_LINK_SPEED_1G)
- return VNET_DPDK_PORT_TYPE_ETH_1G;
-
- return VNET_DPDK_PORT_TYPE_UNKNOWN;
-}
+ u32 link_speed;
+ const char *pfx;
+} if_name_prefixes[] = {
+ /* sorted, higher speed first */
+ { ETH_LINK_SPEED_200G, "TwoHundredGigabitEthernet" },
+ { ETH_LINK_SPEED_100G, "HundredGigabitEthernet" },
+ { ETH_LINK_SPEED_56G, "FiftySixGigabitEthernet" },
+ { ETH_LINK_SPEED_50G, "FiftyGigabitEthernet" },
+ { ETH_LINK_SPEED_40G, "FortyGigabitEthernet" },
+ { ETH_LINK_SPEED_25G, "TwentyFiveGigabitEthernet" },
+ { ETH_LINK_SPEED_20G, "TwentyGigabitEthernet" },
+ { ETH_LINK_SPEED_10G, "TenGigabitEthernet" },
+ { ETH_LINK_SPEED_5G, "FiveGigabitEthernet" },
+ { ETH_LINK_SPEED_2_5G, "TwoDotFiveGigabitEthernet" },
+ { ETH_LINK_SPEED_1G, "GigabitEthernet" },
+};
static u32
dpdk_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
@@ -161,31 +149,53 @@ check_l3cache ()
return 0;
}
+static dpdk_device_config_t *
+dpdk_find_startup_config (struct rte_eth_dev_info *di)
+{
+ dpdk_main_t *dm = &dpdk_main;
+ struct rte_pci_device *pci_dev;
+ struct rte_vmbus_device *vmbus_dev;
+ vlib_pci_addr_t pci_addr;
+ vlib_vmbus_addr_t vmbus_addr;
+ uword *p = 0;
+
+ if ((pci_dev = dpdk_get_pci_device (di)))
+ {
+ pci_addr.domain = pci_dev->addr.domain;
+ pci_addr.bus = pci_dev->addr.bus;
+ pci_addr.slot = pci_dev->addr.devid;
+ pci_addr.function = pci_dev->addr.function;
+ p =
+ hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32);
+ }
+
+ if ((vmbus_dev = dpdk_get_vmbus_device (di)))
+ {
+ unformat_input_t input_vmbus;
+ unformat_init_string (&input_vmbus, di->device->name,
+ strlen (di->device->name));
+ if (unformat (&input_vmbus, "%U", unformat_vlib_vmbus_addr, &vmbus_addr))
+ p = mhash_get (&dm->conf->device_config_index_by_vmbus_addr,
+ &vmbus_addr);
+ unformat_free (&input_vmbus);
+ }
+
+ if (p)
+ return pool_elt_at_index (dm->conf->dev_confs, p[0]);
+ return &dm->conf->default_devconf;
+}
+
static clib_error_t *
dpdk_lib_init (dpdk_main_t * dm)
{
vnet_main_t *vnm = vnet_get_main ();
- u32 nports;
u16 port_id;
- vlib_main_t *vm = vlib_get_main ();
vlib_thread_main_t *tm = vlib_get_thread_main ();
vnet_device_main_t *vdm = &vnet_device_main;
vnet_sw_interface_t *sw;
vnet_hw_interface_t *hi;
dpdk_device_t *xd;
- vlib_pci_addr_t last_pci_addr;
- u32 last_pci_addr_port = 0;
- last_pci_addr.as_u32 = ~0;
-
- nports = rte_eth_dev_count_avail ();
-
- if (nports < 1)
- {
- dpdk_log_notice ("DPDK drivers found no Ethernet devices...");
- }
-
- if (CLIB_DEBUG > 0)
- dpdk_log_notice ("DPDK drivers found %d ports...", nports);
+ char *if_num_fmt;
/* vlib_buffer_t template */
vec_validate_aligned (dm->per_thread_data, tm->n_vlib_mains - 1,
@@ -197,6 +207,9 @@ dpdk_lib_init (dpdk_main_t * dm)
vnet_buffer (&ptd->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
}
+ if_num_fmt =
+ dm->conf->interface_name_format_decimal ? "%d/%d/%d" : "%x/%x/%x";
+
/* device config defaults */
dm->default_port_conf.n_rx_desc = DPDK_NB_RX_DESC_DEFAULT;
dm->default_port_conf.n_tx_desc = DPDK_NB_TX_DESC_DEFAULT;
@@ -212,121 +225,109 @@ dpdk_lib_init (dpdk_main_t * dm)
RTE_ETH_FOREACH_DEV (port_id)
{
u8 addr[6];
+ int rv, q;
struct rte_eth_dev_info di;
- struct rte_pci_device *pci_dev;
- struct rte_vmbus_device *vmbus_dev;
- dpdk_portid_t next_port_id;
dpdk_device_config_t *devconf = 0;
vnet_eth_interface_registration_t eir = {};
- vlib_pci_addr_t pci_addr;
- vlib_vmbus_addr_t vmbus_addr;
- uword *p = 0;
+ dpdk_driver_t *dr;
if (!rte_eth_dev_is_valid_port (port_id))
continue;
- rte_eth_dev_info_get (port_id, &di);
-
- if (di.device == 0)
+ if ((rv = rte_eth_dev_info_get (port_id, &di)) != 0)
{
- dpdk_log_notice ("DPDK bug: missing device info. Skipping %s device",
- di.driver_name);
+ dpdk_log_warn ("[%u] failed to get device info. skipping device.",
+ port_id);
continue;
}
- pci_dev = dpdk_get_pci_device (&di);
-
- if (pci_dev)
+ if (di.device == 0)
{
- pci_addr.domain = pci_dev->addr.domain;
- pci_addr.bus = pci_dev->addr.bus;
- pci_addr.slot = pci_dev->addr.devid;
- pci_addr.function = pci_dev->addr.function;
- p = hash_get (dm->conf->device_config_index_by_pci_addr,
- pci_addr.as_u32);
+ dpdk_log_warn ("[%u] missing device info. Skipping '%s' device",
+ port_id, di.driver_name);
+ continue;
}
- vmbus_dev = dpdk_get_vmbus_device (&di);
+ devconf = dpdk_find_startup_config (&di);
- if (vmbus_dev)
+ /* If device is blacklisted, we should skip it */
+ if (devconf->is_blacklisted)
{
- unformat_input_t input_vmbus;
- unformat_init_string (&input_vmbus, di.device->name,
- strlen (di.device->name));
- if (unformat (&input_vmbus, "%U", unformat_vlib_vmbus_addr,
- &vmbus_addr))
- {
- p = mhash_get (&dm->conf->device_config_index_by_vmbus_addr,
- &vmbus_addr);
- }
- unformat_free (&input_vmbus);
- }
-
- if (p)
- {
- devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
- /* If device is blacklisted, we should skip it */
- if (devconf->is_blacklisted)
- {
- continue;
- }
+ dpdk_log_notice ("[%d] Device %s blacklisted. Skipping...", port_id,
+ di.driver_name);
+ continue;
}
- else
- devconf = &dm->conf->default_devconf;
- /* Create vnet interface */
vec_add2_aligned (dm->devices, xd, 1, CLIB_CACHE_LINE_BYTES);
- xd->cpu_socket = (i8) rte_eth_dev_socket_id (port_id);
+ xd->port_id = port_id;
+ xd->device_index = xd - dm->devices;
+ xd->per_interface_next_index = ~0;
+
clib_memcpy (&xd->conf, &dm->default_port_conf,
sizeof (dpdk_port_conf_t));
- if (p)
+ /* find driver datea for this PMD */
+ if ((dr = dpdk_driver_find (di.driver_name, &xd->if_desc)))
{
- xd->name = devconf->name;
+ xd->driver = dr;
+ xd->supported_flow_actions = dr->supported_flow_actions;
+ xd->conf.disable_rss = dr->mq_mode_none;
+ xd->conf.disable_rx_scatter = dr->disable_rx_scatter;
+ if (dr->use_intel_phdr_cksum)
+ dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM, 1);
+ if (dr->int_unmaskable)
+ dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INT_UNMASKABLE, 1);
}
+ else
+ dpdk_log_warn ("[%u] unknown driver '%s'", port_id, di.driver_name);
- /* Handle representor devices that share the same PCI ID */
- if (di.switch_info.domain_id != RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID)
+ if (devconf->name)
{
- if (di.switch_info.port_id != (uint16_t) -1)
- xd->interface_name_suffix =
- format (0, "%d", di.switch_info.port_id);
+ xd->name = devconf->name;
}
- /* Handle interface naming for devices with multiple ports sharing same
- * PCI ID */
- else if (pci_dev && ((next_port_id = rte_eth_find_next (port_id + 1)) !=
- RTE_MAX_ETHPORTS))
+ else
{
- struct rte_eth_dev_info next_di = { 0 };
- struct rte_pci_device *next_pci_dev;
- rte_eth_dev_info_get (next_port_id, &next_di);
- next_pci_dev = next_di.device ? RTE_DEV_TO_PCI (next_di.device) : 0;
- if (next_pci_dev && pci_addr.as_u32 != last_pci_addr.as_u32 &&
- memcmp (&pci_dev->addr, &next_pci_dev->addr,
- sizeof (struct rte_pci_addr)) == 0)
- {
- xd->interface_name_suffix = format (0, "0");
- last_pci_addr.as_u32 = pci_addr.as_u32;
- last_pci_addr_port = port_id;
- }
- else if (pci_addr.as_u32 == last_pci_addr.as_u32)
+ struct rte_pci_device *pci_dev;
+ if (dr && dr->interface_name_prefix)
{
- xd->interface_name_suffix =
- format (0, "%u", port_id - last_pci_addr_port);
+ /* prefix override by driver */
+ xd->name = format (xd->name, "%s", dr->interface_name_prefix);
}
else
{
- last_pci_addr.as_u32 = ~0;
+ /* interface name prefix from speed_capa */
+ u64 mask = ~((if_name_prefixes[0].link_speed << 1) - 1);
+
+ if (di.speed_capa & mask)
+ dpdk_log_warn ("[%u] unknown speed capability 0x%x reported",
+ xd->port_id, di.speed_capa & mask);
+
+ for (int i = 0; i < ARRAY_LEN (if_name_prefixes); i++)
+ if (if_name_prefixes[i].link_speed & di.speed_capa)
+ {
+ xd->name =
+ format (xd->name, "%s", if_name_prefixes[i].pfx);
+ break;
+ }
+ if (xd->name == 0)
+ xd->name = format (xd->name, "Ethernet");
}
- }
- else
- last_pci_addr.as_u32 = ~0;
- if (devconf->max_lro_pkt_size)
- xd->conf.max_lro_pkt_size = devconf->max_lro_pkt_size;
+ if (dr && dr->interface_number_from_port_id)
+ xd->name = format (xd->name, "%u", port_id);
+ else if ((pci_dev = dpdk_get_pci_device (&di)))
+ xd->name = format (xd->name, if_num_fmt, pci_dev->addr.bus,
+ pci_dev->addr.devid, pci_dev->addr.function);
+ else
+ xd->name = format (xd->name, "%u", port_id);
+ }
- xd->conf.n_tx_queues = clib_min (di.max_tx_queues, xd->conf.n_tx_queues);
+ /* Handle representor devices that share the same PCI ID */
+ if ((di.switch_info.domain_id != RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) &&
+ (di.switch_info.port_id != (uint16_t) -1))
+ xd->name = format (xd->name, "/%d", di.switch_info.port_id);
+ /* number of RX and TX queues */
if (devconf->num_tx_queues > 0 &&
devconf->num_tx_queues < xd->conf.n_tx_queues)
xd->conf.n_tx_queues = devconf->num_tx_queues;
@@ -348,184 +349,39 @@ dpdk_lib_init (dpdk_main_t * dm)
xd->conf.rss_hf &= di.flow_type_rss_offloads;
}
+ /* number of RX and TX tescriptors */
if (devconf->num_rx_desc)
xd->conf.n_rx_desc = devconf->num_rx_desc;
+ else if (dr && dr->n_rx_desc)
+ xd->conf.n_rx_desc = dr->n_rx_desc;
if (devconf->num_tx_desc)
xd->conf.n_tx_desc = devconf->num_tx_desc;
+ else if (dr && dr->n_tx_desc)
+ xd->conf.n_tx_desc = dr->n_tx_desc;
vec_validate_aligned (xd->rx_queues, xd->conf.n_rx_queues - 1,
CLIB_CACHE_LINE_BYTES);
- /* workaround for drivers not setting driver_name */
- if ((!di.driver_name) && (pci_dev))
- di.driver_name = pci_dev->driver->driver.name;
-
- ASSERT (di.driver_name);
-
- if (!xd->pmd)
- {
-
-#define _(s, f) \
- else if (di.driver_name && !strcmp (di.driver_name, s)) xd->pmd = \
- VNET_DPDK_PMD_##f;
- if (0)
- ;
- foreach_dpdk_pmd
-#undef _
- else xd->pmd = VNET_DPDK_PMD_UNKNOWN;
-
- xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
-
- switch (xd->pmd)
- {
- /* Drivers with valid speed_capa set */
- case VNET_DPDK_PMD_I40E:
- dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INT_UNMASKABLE, 1);
- /* fall through */
- case VNET_DPDK_PMD_E1000EM:
- case VNET_DPDK_PMD_IGB:
- case VNET_DPDK_PMD_IGC:
- case VNET_DPDK_PMD_IXGBE:
- case VNET_DPDK_PMD_ICE:
- xd->supported_flow_actions =
- VNET_FLOW_ACTION_MARK | VNET_FLOW_ACTION_REDIRECT_TO_NODE |
- VNET_FLOW_ACTION_REDIRECT_TO_QUEUE |
- VNET_FLOW_ACTION_BUFFER_ADVANCE | VNET_FLOW_ACTION_COUNT |
- VNET_FLOW_ACTION_DROP | VNET_FLOW_ACTION_RSS;
- dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM, 1);
- xd->conf.enable_rxq_int = 1;
- /* fall through */
- case VNET_DPDK_PMD_MLX5:
- case VNET_DPDK_PMD_CXGBE:
- case VNET_DPDK_PMD_MLX4:
- case VNET_DPDK_PMD_QEDE:
- case VNET_DPDK_PMD_BNXT:
- case VNET_DPDK_PMD_ENIC:
- xd->port_type = port_type_from_speed_capa (&di);
- break;
-
- /* SR-IOV VFs */
- case VNET_DPDK_PMD_I40EVF:
- dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INT_UNMASKABLE, 1);
- /* fall through */
- case VNET_DPDK_PMD_IGBVF:
- case VNET_DPDK_PMD_IXGBEVF:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
- dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM, 1);
- /* DPDK bug in multiqueue... */
- /* xd->port_conf.intr_conf.rxq = 1; */
- break;
-
- /* iAVF */
- case VNET_DPDK_PMD_IAVF:
- dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INT_UNMASKABLE, 1);
- dpdk_device_flag_set (xd, DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM, 1);
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
- xd->supported_flow_actions =
- VNET_FLOW_ACTION_MARK | VNET_FLOW_ACTION_REDIRECT_TO_NODE |
- VNET_FLOW_ACTION_REDIRECT_TO_QUEUE |
- VNET_FLOW_ACTION_BUFFER_ADVANCE | VNET_FLOW_ACTION_COUNT |
- VNET_FLOW_ACTION_DROP | VNET_FLOW_ACTION_RSS;
- /* DPDK bug in multiqueue... */
- /* xd->port_conf.intr_conf.rxq = 1; */
- break;
-
- case VNET_DPDK_PMD_THUNDERX:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
- break;
-
- case VNET_DPDK_PMD_ENA:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
- xd->conf.disable_rx_scatter = 1;
- xd->conf.enable_rxq_int = 1;
- break;
-
- case VNET_DPDK_PMD_DPAA2:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
- break;
-
- /* Intel Red Rock Canyon */
- case VNET_DPDK_PMD_FM10K:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_SWITCH;
- break;
-
- /* virtio */
- case VNET_DPDK_PMD_VIRTIO:
- xd->conf.disable_rss = 1;
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
- xd->conf.n_rx_desc = DPDK_NB_RX_DESC_VIRTIO;
- xd->conf.n_tx_desc = DPDK_NB_TX_DESC_VIRTIO;
- xd->conf.enable_rxq_int = 1;
- break;
-
- /* vmxnet3 */
- case VNET_DPDK_PMD_VMXNET3:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
- break;
-
- case VNET_DPDK_PMD_AF_PACKET:
- xd->port_type = VNET_DPDK_PORT_TYPE_AF_PACKET;
- break;
-
- case VNET_DPDK_PMD_VIRTIO_USER:
- xd->port_type = VNET_DPDK_PORT_TYPE_VIRTIO_USER;
- break;
-
- case VNET_DPDK_PMD_VHOST_ETHER:
- xd->port_type = VNET_DPDK_PORT_TYPE_VHOST_ETHER;
- break;
-
- case VNET_DPDK_PMD_LIOVF_ETHER:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
- break;
-
- case VNET_DPDK_PMD_FAILSAFE:
- xd->port_type = VNET_DPDK_PORT_TYPE_FAILSAFE;
- xd->conf.enable_lsc_int = 1;
- break;
-
- case VNET_DPDK_PMD_NETVSC:
- {
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
- }
- break;
-
- default:
- xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
- }
- }
-
- if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
- {
- f64 now = vlib_time_now (vm);
- u32 rnd;
- rnd = (u32) (now * 1e6);
- rnd = random_u32 (&rnd);
- clib_memcpy (addr + 2, &rnd, sizeof (rnd));
- addr[0] = 2;
- addr[1] = 0xfe;
- }
- else
- rte_eth_macaddr_get (port_id, (void *) addr);
-
- xd->port_id = port_id;
- xd->device_index = xd - dm->devices;
- xd->per_interface_next_index = ~0;
-
- /* assign interface to input thread */
- int q;
+ rte_eth_macaddr_get (port_id, (void *) addr);
+ /* create interface */
eir.dev_class_index = dpdk_device_class.index;
eir.dev_instance = xd->device_index;
eir.address = addr;
eir.cb.flag_change = dpdk_flag_change;
xd->hw_if_index = vnet_eth_register_interface (vnm, &eir);
-
+ hi = vnet_get_hw_interface (vnm, xd->hw_if_index);
+ hi->numa_node = xd->cpu_socket = (i8) rte_eth_dev_socket_id (port_id);
sw = vnet_get_hw_sw_interface (vnm, xd->hw_if_index);
xd->sw_if_index = sw->sw_if_index;
- vnet_hw_if_set_input_node (vnm, xd->hw_if_index, dpdk_input_node.index);
+ dpdk_log_debug ("[%u] interface %s created", port_id, hi->name);
+
+ ethernet_set_flags (vnm, xd->hw_if_index,
+ ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
+ /* assign worker threads */
+ vnet_hw_if_set_input_node (vnm, xd->hw_if_index, dpdk_input_node.index);
if (devconf->workers)
{
int j;
@@ -545,20 +401,6 @@ dpdk_lib_init (dpdk_main_t * dm)
vnm, xd->hw_if_index, q, VNET_HW_IF_RXQ_THREAD_ANY);
}
-
- /*Get vnet hardware interface */
- hi = vnet_get_hw_interface (vnm, xd->hw_if_index);
-
- if (hi)
- {
- hi->numa_node = xd->cpu_socket;
-
- /* Indicate ability to support L3 DMAC filtering and
- * initialize interface to L3 non-promisc mode */
- ethernet_set_flags (vnm, xd->hw_if_index,
- ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
- }
-
if (devconf->tso == DPDK_DEVICE_TSO_ON)
{
/*tcp_udp checksum must be enabled*/
@@ -571,21 +413,21 @@ dpdk_lib_init (dpdk_main_t * dm)
xd->conf.enable_tso = 1;
}
+ if (devconf->max_lro_pkt_size)
+ xd->conf.max_lro_pkt_size = devconf->max_lro_pkt_size;
+
dpdk_device_setup (xd);
/* rss queues should be configured after dpdk_device_setup() */
- if ((hi != NULL) && (devconf->rss_queues != NULL))
+ if (devconf->rss_queues)
{
if (vnet_hw_interface_set_rss_queues (vnet_get_main (), hi,
devconf->rss_queues))
- {
- clib_warning ("%s: Failed to set rss queues", hi->name);
- }
+ dpdk_log_warn ("[%u] Failed to set rss queues", port_id);
}
if (vec_len (xd->errors))
- dpdk_log_err ("setup failed for device %U. Errors:\n %U",
- format_dpdk_device_name, port_id,
+ dpdk_log_err ("[%u] setup failed Errors:\n %U", port_id,
format_dpdk_device_errors, xd);
}
@@ -944,7 +786,7 @@ dpdk_device_config (dpdk_config_main_t *conf, void *addr,
;
else if (unformat (input, "num-tx-desc %u", &devconf->num_tx_desc))
;
- else if (unformat (input, "name %s", &devconf->name))
+ else if (unformat (input, "name %v", &devconf->name))
;
else if (unformat (input, "workers %U", unformat_bitmap_list,
&devconf->workers))