#include <vnet/ethernet/ethernet.h>
#include <dpdk/buffer.h>
#include <dpdk/device/dpdk.h>
+#include <dpdk/cryptodev/cryptodev.h>
#include <vlib/pci/pci.h>
#include <vlib/vmbus/vmbus.h>
#include <sys/mount.h>
#include <string.h>
#include <fcntl.h>
+#include <dirent.h>
#include <dpdk/device/dpdk_priv.h>
{
dpdk_main_t *dm = &dpdk_main;
dpdk_device_t *xd = vec_elt_at_index (dm->devices, hi->dev_instance);
- u32 old = 0;
+ u32 old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
- if (ETHERNET_INTERFACE_FLAG_CONFIG_PROMISC (flags))
- {
- old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
-
- if (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
- xd->flags |= DPDK_DEVICE_FLAG_PROMISC;
- else
- xd->flags &= ~DPDK_DEVICE_FLAG_PROMISC;
-
- if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- {
- if (xd->flags & DPDK_DEVICE_FLAG_PROMISC)
- rte_eth_promiscuous_enable (xd->port_id);
- else
- rte_eth_promiscuous_disable (xd->port_id);
- }
- }
- else if (ETHERNET_INTERFACE_FLAG_CONFIG_MTU (flags))
+ switch (flags)
{
+ case ETHERNET_INTERFACE_FLAG_DEFAULT_L3:
+ /* set to L3/non-promisc mode */
+ xd->flags &= ~DPDK_DEVICE_FLAG_PROMISC;
+ break;
+ case ETHERNET_INTERFACE_FLAG_ACCEPT_ALL:
+ xd->flags |= DPDK_DEVICE_FLAG_PROMISC;
+ break;
+ case ETHERNET_INTERFACE_FLAG_MTU:
xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
dpdk_device_setup (xd);
+ return 0;
+ default:
+ return ~0;
}
- return old;
-}
-static void
-dpdk_device_lock_init (dpdk_device_t * xd)
-{
- int q;
- vec_validate (xd->lockp, xd->tx_q_used - 1);
- for (q = 0; q < xd->tx_q_used; q++)
+ if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
{
- xd->lockp[q] = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
- CLIB_CACHE_LINE_BYTES);
- clib_memset ((void *) xd->lockp[q], 0, CLIB_CACHE_LINE_BYTES);
+ if (xd->flags & DPDK_DEVICE_FLAG_PROMISC)
+ rte_eth_promiscuous_enable (xd->port_id);
+ else
+ rte_eth_promiscuous_disable (xd->port_id);
}
+
+ return old;
}
static int
dpdk_port_crc_strip_enabled (dpdk_device_t * xd)
{
-#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
- return ! !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP);
-#else
return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC);
-#endif
+}
+
+/* The function check_l3cache helps check if Level 3 cache exists or not on current CPUs
+ return value 1: exist.
+ return value 0: not exist.
+*/
+static int
+check_l3cache ()
+{
+
+ struct dirent *dp;
+ clib_error_t *err;
+ const char *sys_cache_dir = "/sys/devices/system/cpu/cpu0/cache";
+ DIR *dir_cache = opendir (sys_cache_dir);
+
+ if (dir_cache == NULL)
+ return -1;
+
+ while ((dp = readdir (dir_cache)) != NULL)
+ {
+ if (dp->d_type == DT_DIR)
+ {
+ u8 *p = NULL;
+ int level_cache = -1;
+
+ p = format (p, "%s/%s/%s%c", sys_cache_dir, dp->d_name, "level", 0);
+ if ((err = clib_sysfs_read ((char *) p, "%d", &level_cache)))
+ clib_error_free (err);
+
+ if (level_cache == 3)
+ {
+ closedir (dir_cache);
+ return 1;
+ }
+ }
+ }
+
+ if (dir_cache != NULL)
+ closedir (dir_cache);
+
+ return 0;
+}
+
+static void
+dpdk_enable_l4_csum_offload (dpdk_device_t * xd)
+{
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
}
static clib_error_t *
dpdk_device_t *xd;
vlib_pci_addr_t last_pci_addr;
u32 last_pci_addr_port = 0;
- vlib_thread_registration_t *tr_hqos;
- uword *p_hqos;
-
- u32 next_hqos_cpu = 0;
u8 af_packet_instance_num = 0;
- u8 bond_ether_instance_num = 0;
last_pci_addr.as_u32 = ~0;
- dm->hqos_cpu_first_index = 0;
- dm->hqos_cpu_count = 0;
-
- /* find out which cpus will be used for I/O TX */
- p_hqos = hash_get_mem (tm->thread_registrations_by_name, "hqos-threads");
- tr_hqos = p_hqos ? (vlib_thread_registration_t *) p_hqos[0] : 0;
-
- if (tr_hqos && tr_hqos->count > 0)
- {
- dm->hqos_cpu_first_index = tr_hqos->first_index;
- dm->hqos_cpu_count = tr_hqos->count;
- }
-
- vec_validate_aligned (dm->devices_by_hqos_cpu, tm->n_vlib_mains - 1,
- CLIB_CACHE_LINE_BYTES);
-
nports = rte_eth_dev_count_avail ();
if (nports < 1)
{
- dpdk_log_notice ("DPDK drivers found no ports...");
+ dpdk_log_notice ("DPDK drivers found no Ethernet devices...");
}
if (CLIB_DEBUG > 0)
RTE_ETH_FOREACH_DEV(i)
{
u8 addr[6];
- u8 vlan_strip = 0;
+ int vlan_off;
struct rte_eth_dev_info dev_info;
struct rte_pci_device *pci_dev;
- struct rte_eth_link l;
+ dpdk_portid_t next_port_id;
dpdk_device_config_t *devconf = 0;
vlib_pci_addr_t pci_addr;
uword *p = 0;
if (!rte_eth_dev_is_valid_port(i))
continue;
- rte_eth_link_get_nowait (i, &l);
rte_eth_dev_info_get (i, &dev_info);
if (dev_info.device == 0)
{
- clib_warning ("DPDK bug: missing device info. Skipping %s device",
+ dpdk_log_notice ("DPDK bug: missing device info. Skipping %s device",
dev_info.driver_name);
continue;
}
pci_dev = dpdk_get_pci_device (&dev_info);
- if (pci_dev) /* bonded interface has no pci info */
+ if (pci_dev)
{
pci_addr.domain = pci_dev->addr.domain;
pci_addr.bus = pci_dev->addr.bus;
else
devconf = &dm->conf->default_devconf;
+ /* Handle representor devices that share the same PCI ID */
+ if (dev_info.switch_info.domain_id != RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID)
+ {
+ if (dev_info.switch_info.port_id != (uint16_t)-1)
+ xd->interface_name_suffix = format (0, "%d", dev_info.switch_info.port_id);
+ }
/* Handle interface naming for devices with multiple ports sharing same PCI ID */
- if (pci_dev)
+ else if (pci_dev &&
+ ((next_port_id = rte_eth_find_next (i + 1)) != RTE_MAX_ETHPORTS))
{
struct rte_eth_dev_info di = { 0 };
struct rte_pci_device *next_pci_dev;
- rte_eth_dev_info_get (i + 1, &di);
+ rte_eth_dev_info_get (next_port_id, &di);
next_pci_dev = di.device ? RTE_DEV_TO_PCI (di.device) : 0;
- if (pci_dev && next_pci_dev &&
+ 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->flags |= DPDK_DEVICE_FLAG_RX_IP4_CKSUM;
}
+ if (dm->conf->enable_tcp_udp_checksum)
+ {
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM)
+ xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_UDP_CKSUM;
+ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
+ xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_CKSUM;
+ }
+
if (dm->conf->no_multi_seg)
{
xd->port_conf.txmode.offloads &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
case VNET_DPDK_PMD_IGB:
case VNET_DPDK_PMD_IXGBE:
case VNET_DPDK_PMD_I40E:
+ case VNET_DPDK_PMD_ICE:
xd->port_type = port_type_from_speed_capa (&dev_info);
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_COUNT | VNET_FLOW_ACTION_DROP |
+ VNET_FLOW_ACTION_RSS;
if (dm->conf->no_tx_checksum_offload == 0)
{
case VNET_DPDK_PMD_MLX4:
case VNET_DPDK_PMD_MLX5:
case VNET_DPDK_PMD_QEDE:
+ case VNET_DPDK_PMD_BNXT:
xd->port_type = port_type_from_speed_capa (&dev_info);
break;
case VNET_DPDK_PMD_IXGBEVF:
case VNET_DPDK_PMD_I40EVF:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
- xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-#endif
+ if (dm->conf->no_tx_checksum_offload == 0)
+ {
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ xd->flags |=
+ DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+ }
break;
+ /* iAVF */
+ case VNET_DPDK_PMD_IAVF:
+ 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;
+
+ if (dm->conf->no_tx_checksum_offload == 0)
+ {
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+ xd->flags |=
+ DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+ }
+ break;
+
case VNET_DPDK_PMD_THUNDERX:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
- xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-#endif
if (dm->conf->no_tx_checksum_offload == 0)
{
/* Cisco VIC */
case VNET_DPDK_PMD_ENIC:
- if (l.link_speed == 40000)
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
- else
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
+ {
+ struct rte_eth_link l;
+ rte_eth_link_get_nowait (i, &l);
+ xd->port_type = port_type_from_link_speed (l.link_speed);
+ if (dm->conf->enable_tcp_udp_checksum)
+ dpdk_enable_l4_csum_offload (xd);
+ }
break;
/* Intel Red Rock Canyon */
case VNET_DPDK_PMD_FM10K:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_SWITCH;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
- xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
-#endif
break;
/* virtio */
case VNET_DPDK_PMD_VIRTIO:
+ xd->port_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
xd->nb_rx_desc = DPDK_NB_RX_DESC_VIRTIO;
xd->nb_tx_desc = DPDK_NB_TX_DESC_VIRTIO;
xd->af_packet_instance_num = af_packet_instance_num++;
break;
- case VNET_DPDK_PMD_BOND:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_BOND;
- xd->bond_instance_num = bond_ether_instance_num++;
- break;
-
case VNET_DPDK_PMD_VIRTIO_USER:
xd->port_type = VNET_DPDK_PORT_TYPE_VIRTIO_USER;
break;
break;
case VNET_DPDK_PMD_NETVSC:
- xd->port_type = port_type_from_link_speed (l.link_speed);
+ {
+ struct rte_eth_link l;
+ rte_eth_link_get_nowait (i, &l);
+ xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
+ }
break;
default:
if (devconf->num_rx_desc)
xd->nb_rx_desc = devconf->num_rx_desc;
+ else {
+
+ /* If num_rx_desc is not specified by VPP user, the current CPU is working
+ with 2M page and has no L3 cache, default num_rx_desc is changed to 512
+ from original 1024 to help reduce TLB misses.
+ */
+ if ((clib_mem_get_default_hugepage_size () == 2 << 20)
+ && check_l3cache() == 0)
+ xd->nb_rx_desc = 512;
+ }
if (devconf->num_tx_desc)
xd->nb_tx_desc = devconf->num_tx_desc;
- }
+ else {
+
+ /* If num_tx_desc is not specified by VPP user, the current CPU is working
+ with 2M page and has no L3 cache, default num_tx_desc is changed to 512
+ from original 1024 to help reduce TLB misses.
+ */
+ if ((clib_mem_get_default_hugepage_size () == 2 << 20)
+ && check_l3cache() == 0)
+ xd->nb_tx_desc = 512;
+ }
+ }
if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
{
addr[1] = 0xfe;
}
else
- rte_eth_macaddr_get (i, (struct ether_addr *) addr);
-
- if (xd->tx_q_used < tm->n_vlib_mains)
- dpdk_device_lock_init (xd);
+ rte_eth_macaddr_get (i, (void *) addr);
xd->port_id = i;
xd->device_index = xd - dm->devices;
/* assign interface to input thread */
int q;
- if (devconf->hqos_enabled)
- {
- xd->flags |= DPDK_DEVICE_FLAG_HQOS;
-
- int cpu;
- if (devconf->hqos.hqos_thread_valid)
- {
- if (devconf->hqos.hqos_thread >= dm->hqos_cpu_count)
- return clib_error_return (0, "invalid HQoS thread index");
-
- cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
- }
- else
- {
- if (dm->hqos_cpu_count == 0)
- return clib_error_return (0, "no HQoS threads available");
-
- cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
-
- next_hqos_cpu++;
- if (next_hqos_cpu == dm->hqos_cpu_count)
- next_hqos_cpu = 0;
-
- devconf->hqos.hqos_thread_valid = 1;
- devconf->hqos.hqos_thread = cpu;
- }
-
- dpdk_device_and_queue_t *dq;
- vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
- dq->device = xd->device_index;
- dq->queue_id = 0;
- }
-
error = ethernet_register_interface
(dm->vnet_main, dpdk_device_class.index, xd->device_index,
/* ethernet address */ addr,
{
hi->max_packet_bytes = mtu;
hi->max_supported_packet_bytes = max_rx_frame;
+ hi->numa_node = xd->cpu_socket;
+
+ /* Indicate ability to support L3 DMAC filtering and
+ * initialize interface to L3 non-promisc mode */
+ hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_MAC_FILTER;
+ ethernet_set_flags (dm->vnet_main, xd->hw_if_index,
+ ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
}
if (dm->conf->no_tx_checksum_offload == 0)
if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD && hi != NULL)
hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD;
+ if (devconf->tso == DPDK_DEVICE_TSO_ON && hi != NULL)
+ {
+ /*tcp_udp checksum must be enabled*/
+ if ((dm->conf->enable_tcp_udp_checksum) &&
+ (hi->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD))
+ {
+ hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO |
+ DEV_TX_OFFLOAD_UDP_TSO;
+ }
+ else
+ clib_warning ("%s: TCP/UDP checksum offload must be enabled",
+ hi->name);
+ }
+
dpdk_device_setup (xd);
+ /* rss queues should be configured after dpdk_device_setup() */
+ if ((hi != NULL) && (devconf->rss_queues != NULL))
+ {
+ if (vnet_hw_interface_set_rss_queues
+ (vnet_get_main (), hi, devconf->rss_queues))
+ {
+ clib_warning ("%s: Failed to set rss queues", hi->name);
+ }
+ }
+
if (vec_len (xd->errors))
- dpdk_log_err ("setup failed for device %U. Errors:\n %U",
- format_dpdk_device_name, i,
- format_dpdk_device_errors, xd);
+ dpdk_log_err ("setup failed for device %U. Errors:\n %U",
+ format_dpdk_device_name, i,
+ format_dpdk_device_errors, xd);
- if (devconf->hqos_enabled)
- {
- clib_error_t *rv;
- rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
- if (rv)
- return rv;
- }
+ /*
+ * A note on Cisco VIC (PMD_ENIC) and VLAN:
+ *
+ * With Cisco VIC vNIC, every ingress packet is tagged. On a
+ * trunk vNIC (C series "standalone" server), packets on no VLAN
+ * are tagged with vlan 0. On an access vNIC (standalone or B
+ * series "blade" server), packets on the default/native VLAN
+ * are tagged with that vNIC's VLAN. VPP expects these packets
+ * to be untagged, and previously enabled VLAN strip on VIC by
+ * default. But it also broke vlan sub-interfaces.
+ *
+ * The VIC adapter has "untag default vlan" ingress VLAN rewrite
+ * mode, which removes tags from these packets. VPP now includes
+ * a local patch for the enic driver to use this untag mode, so
+ * enabling vlan stripping is no longer needed. In future, the
+ * driver + dpdk will have an API to set the mode after
+ * rte_eal_init. Then, this note and local patch will be
+ * removed.
+ */
/*
- * For cisco VIC vNIC, set default to VLAN strip enabled, unless
- * specified otherwise in the startup config.
- * For other NICs default to VLAN strip disabled, unless specified
+ * VLAN stripping: default to VLAN strip disabled, unless specified
* otherwise in the startup config.
*/
- if (xd->pmd == VNET_DPDK_PMD_ENIC)
- {
- if (devconf->vlan_strip_offload != DPDK_DEVICE_VLAN_STRIP_OFF)
- vlan_strip = 1; /* remove vlan tag from VIC port by default */
- else
- dpdk_log_warn ("VLAN strip disabled for interface\n");
- }
- else if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
- vlan_strip = 1;
- if (vlan_strip)
- {
- int vlan_off;
- vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
- vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
- if (vlan_off)
- xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
- else
- xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
- if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) == 0)
- dpdk_log_info ("VLAN strip enabled for interface\n");
- else
- dpdk_log_warn ("VLAN strip cannot be supported by interface\n");
- }
+ vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
+ if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
+ {
+ vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
+ if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) >= 0)
+ dpdk_log_info ("VLAN strip enabled for interface\n");
+ else
+ dpdk_log_warn ("VLAN strip cannot be supported by interface\n");
+ xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
+ }
+ else
+ {
+ if (vlan_off & ETH_VLAN_STRIP_OFFLOAD)
+ {
+ vlan_off &= ~ETH_VLAN_STRIP_OFFLOAD;
+ if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) >= 0)
+ dpdk_log_warn ("set VLAN offload failed\n");
+ }
+ xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
+ }
- if (hi)
- hi->max_packet_bytes = xd->port_conf.rxmode.max_rx_pkt_len
- - sizeof (ethernet_header_t);
- else
- clib_warning ("hi NULL");
+ if (hi)
+ hi->max_packet_bytes = xd->port_conf.rxmode.max_rx_pkt_len
+ - sizeof (ethernet_header_t);
+ else
+ dpdk_log_warn ("hi NULL");
- if (dm->conf->no_multi_seg)
- mtu = mtu > ETHER_MAX_LEN ? ETHER_MAX_LEN : mtu;
+ if (dm->conf->no_multi_seg)
+ mtu = mtu > ETHER_MAX_LEN ? ETHER_MAX_LEN : mtu;
+
+ rte_eth_dev_set_mtu (xd->port_id, mtu);
+}
- rte_eth_dev_set_mtu (xd->port_id, mtu);
- }
/* *INDENT-ON* */
return 0;
;
/* all Intel QAT devices VFs */
else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_PROCESSOR_CO &&
- (d->device_id == 0x0443 || d->device_id == 0x37c9 || d->device_id == 0x19e3))
+ (d->device_id == 0x0443 || d->device_id == 0x18a1 || d->device_id == 0x19e3 ||
+ d->device_id == 0x37c9 || d->device_id == 0x6f55))
;
/* Cisco VIC */
- else if (d->vendor_id == 0x1137 && d->device_id == 0x0043)
+ else if (d->vendor_id == 0x1137 &&
+ (d->device_id == 0x0043 || d->device_id == 0x0071))
;
/* Chelsio T4/T5 */
else if (d->vendor_id == 0x1425 && (d->device_id & 0xe000) == 0x4000)
;
- /* Amazen Elastic Network Adapter */
+ /* Amazon Elastic Network Adapter */
else if (d->vendor_id == 0x1d0f && d->device_id >= 0xec20 && d->device_id <= 0xec21)
;
/* Cavium Network Adapter */
/* Cavium FastlinQ QL41000 Series */
else if (d->vendor_id == 0x1077 && d->device_id >= 0x8070 && d->device_id <= 0x8090)
;
- /* Mellanox mlx4 */
+ /* Mellanox CX3, CX3VF */
else if (d->vendor_id == 0x15b3 && d->device_id >= 0x1003 && d->device_id <= 0x1004)
{
continue;
}
- /* Mellanox mlx5 */
+ /* Mellanox CX4, CX4VF, CX4LX, CX4LXVF, CX5, CX5VF, CX5EX, CX5EXVF */
else if (d->vendor_id == 0x15b3 && d->device_id >= 0x1013 && d->device_id <= 0x101a)
{
continue;
}
+ /* Mellanox CX6, CX6VF, CX6DX, CX6DXVF */
+ else if (d->vendor_id == 0x15b3 && d->device_id >= 0x101b && d->device_id <= 0x101e)
+ {
+ continue;
+ }
+ /* Broadcom NetXtreme S, and E series only */
+ else if (d->vendor_id == 0x14e4 &&
+ ((d->device_id >= 0x16c0 &&
+ d->device_id != 0x16c6 && d->device_id != 0x16c7 &&
+ d->device_id != 0x16dd && d->device_id != 0x16f7 &&
+ d->device_id != 0x16fd && d->device_id != 0x16fe &&
+ d->device_id != 0x170d && d->device_id != 0x170c &&
+ d->device_id != 0x170e && d->device_id != 0x1712 &&
+ d->device_id != 0x1713) ||
+ (d->device_id == 0x1604 || d->device_id == 0x1605 ||
+ d->device_id == 0x1614 || d->device_id == 0x1606 ||
+ d->device_id == 0x1609 || d->device_id == 0x1614)))
+ ;
else
{
dpdk_log_warn ("Unsupported PCI device 0x%04x:0x%04x found "
}
devconf->pci_addr.as_u32 = pci_addr.as_u32;
- devconf->hqos_enabled = 0;
- dpdk_device_config_hqos_default (&devconf->hqos);
+ devconf->tso = DPDK_DEVICE_TSO_DEFAULT;
if (!input)
return 0;
devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_OFF;
else if (unformat (input, "vlan-strip-offload on"))
devconf->vlan_strip_offload = DPDK_DEVICE_VLAN_STRIP_ON;
- else
- if (unformat
- (input, "hqos %U", unformat_vlib_cli_sub_input, &sub_input))
+ else if (unformat (input, "tso on"))
{
- devconf->hqos_enabled = 1;
- error = unformat_hqos (&sub_input, &devconf->hqos);
- if (error)
- break;
+ devconf->tso = DPDK_DEVICE_TSO_ON;
}
- else if (unformat (input, "hqos"))
+ else if (unformat (input, "tso off"))
{
- devconf->hqos_enabled = 1;
+ devconf->tso = DPDK_DEVICE_TSO_OFF;
}
+ else if (unformat (input, "devargs %s", &devconf->devargs))
+ ;
+ else if (unformat (input, "rss-queues %U",
+ unformat_bitmap_list, &devconf->rss_queues))
+ ;
else
{
error = clib_error_return (0, "unknown input `%U'",
unformat_input_t sub_input;
uword default_hugepage_sz, x;
u8 *s, *tmp = 0;
- u32 log_level;
int ret, i;
int num_whitelisted = 0;
u8 no_pci = 0;
u8 file_prefix = 0;
u8 *socket_mem = 0;
u8 *huge_dir_path = 0;
- u32 vendor, device;
+ u32 vendor, device, domain, bus, func;
huge_dir_path =
format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
conf->device_config_index_by_pci_addr = hash_create (0, sizeof (uword));
- log_level = RTE_LOG_NOTICE;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
else if (unformat (input, "decimal-interface-names"))
conf->interface_name_format_decimal = 1;
- else if (unformat (input, "log-level %U", unformat_dpdk_log_level, &x))
- log_level = x;
-
else if (unformat (input, "no-multi-seg"))
conf->no_multi_seg = 1;
tmp = format (0, "--no-pci%c", 0);
vec_add1 (conf->eal_init_args, tmp);
}
+ else
+ if (unformat
+ (input, "blacklist %x:%x:%x.%x", &domain, &bus, &device, &func))
+ {
+ tmp =
+ format (0, "-b %04x:%02x:%02x.%x%c", domain, bus, device, func,
+ 0);
+ vec_add1 (conf->eal_init_args, tmp);
+ }
else if (unformat (input, "blacklist %x:%x", &vendor, &device))
{
u32 blacklist_entry;
vec_insert (conf->eal_init_args, 2, 3);
conf->eal_init_args[3] = (u8 *) "-n";
tmp = format (0, "%d", conf->nchannels);
+ vec_terminate_c_string (tmp);
conf->eal_init_args[4] = tmp;
}
/* default per-device config items */
foreach_dpdk_device_config_item
+ /* copy vlan_strip config from default device */
+ if (devconf->vlan_strip_offload == 0 &&
+ conf->default_devconf.vlan_strip_offload > 0)
+ devconf->vlan_strip_offload =
+ conf->default_devconf.vlan_strip_offload;
+
+ /* copy tso config from default device */
+ _(tso)
+
+ /* copy tso config from default device */
+ _(devargs)
+
+ /* copy rss_queues config from default device */
+ _(rss_queues)
+
/* add DPDK EAL whitelist/blacklist entry */
if (num_whitelisted > 0 && devconf->is_blacklisted == 0)
- {
- tmp = format (0, "-w%c", 0);
- vec_add1 (conf->eal_init_args, tmp);
- tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
- vec_add1 (conf->eal_init_args, tmp);
- }
+ {
+ tmp = format (0, "-w%c", 0);
+ vec_add1 (conf->eal_init_args, tmp);
+ if (devconf->devargs)
+ {
+ tmp = format (0, "%U,%s", format_vlib_pci_addr, &devconf->pci_addr, devconf->devargs, 0);
+ }
+ else
+ {
+ tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
+ }
+ vec_add1 (conf->eal_init_args, tmp);
+ }
else if (num_whitelisted == 0 && devconf->is_blacklisted != 0)
- {
- tmp = format (0, "-b%c", 0);
- vec_add1 (conf->eal_init_args, tmp);
- tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
- vec_add1 (conf->eal_init_args, tmp);
- }
+ {
+ tmp = format (0, "-b%c", 0);
+ vec_add1 (conf->eal_init_args, tmp);
+ tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
+ vec_add1 (conf->eal_init_args, tmp);
+ }
}));
/* *INDENT-ON* */
/* Set up DPDK eal and packet mbuf pool early. */
- rte_log_set_global_level (log_level);
int log_fds[2] = { 0 };
if (pipe (log_fds) == 0)
{
conf->eal_init_args_str = format (conf->eal_init_args_str, "%s ",
conf->eal_init_args[i]);
+ vec_terminate_c_string (conf->eal_init_args_str);
+
dpdk_log_warn ("EAL init args: %s", conf->eal_init_args_str);
ret = rte_eal_init (vec_len (conf->eal_init_args),
(char **) conf->eal_init_args);
ed->new_link_state = (u8) xd->link.link_status;
}
- if ((xd->flags & (DPDK_DEVICE_FLAG_ADMIN_UP | DPDK_DEVICE_FLAG_BOND_SLAVE))
- && ((xd->link.link_status != 0) ^
- vnet_hw_interface_is_link_up (vnm, xd->hw_if_index)))
- {
- hw_flags_chg = 1;
- hw_flags |= (xd->link.link_status ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
- }
-
- if (hw_flags_chg || (xd->link.link_duplex != prev_link.link_duplex))
+ if ((xd->link.link_duplex != prev_link.link_duplex))
{
hw_flags_chg = 1;
switch (xd->link.link_duplex)
vnet_hw_interface_set_link_speed (vnm, xd->hw_if_index,
xd->link.link_speed * 1000);
+ if (xd->link.link_status != prev_link.link_status)
+ {
+ hw_flags_chg = 1;
+
+ if (xd->link.link_status)
+ hw_flags |= VNET_HW_INTERFACE_FLAG_LINK_UP;
+ }
+
if (hw_flags_chg)
{
if (LINK_STATE_ELOGS)
dpdk_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
{
clib_error_t *error;
- vnet_main_t *vnm = vnet_get_main ();
dpdk_main_t *dm = &dpdk_main;
- ethernet_main_t *em = ðernet_main;
dpdk_device_t *xd;
vlib_thread_main_t *tm = vlib_get_thread_main ();
- int i;
- int j;
error = dpdk_lib_init (dm);
+ if (error)
+ clib_error_report (error);
+
+ error = dpdk_cryptodev_init (vm);
if (error)
clib_error_report (error);
dpdk_update_link_state (xd, now);
}
- {
- /*
- * Extra set up for bond interfaces:
- * 1. Setup MACs for bond interfaces and their slave links which was set
- * in dpdk_device_setup() but needs to be done again here to take
- * effect.
- * 2. Set up info and register slave link state change callback handling.
- * 3. Set up info for bond interface related CLI support.
- */
- int nports = rte_eth_dev_count_avail ();
- if (nports > 0)
- {
- /* *INDENT-OFF* */
- RTE_ETH_FOREACH_DEV(i)
- {
- xd = NULL;
- for (j = 0; j < nports; j++)
- {
- if (dm->devices[j].port_id == i)
- {
- xd = &dm->devices[j];
- }
- }
- if (xd != NULL && xd->pmd == VNET_DPDK_PMD_BOND)
- {
- u8 addr[6];
- dpdk_portid_t slink[16];
- int nlink = rte_eth_bond_slaves_get (i, slink, 16);
- if (nlink > 0)
- {
- vnet_hw_interface_t *bhi;
- ethernet_interface_t *bei;
- int rv;
-
- /* Get MAC of 1st slave link */
- rte_eth_macaddr_get
- (slink[0], (struct ether_addr *) addr);
-
- /* Set MAC of bounded interface to that of 1st slave link */
- dpdk_log_info ("Set MAC for bond port %d BondEthernet%d",
- i, xd->bond_instance_num);
- rv = rte_eth_bond_mac_address_set
- (i, (struct ether_addr *) addr);
- if (rv)
- dpdk_log_warn ("Set MAC addr failure rv=%d", rv);
-
- /* Populate MAC of bonded interface in VPP hw tables */
- bhi = vnet_get_hw_interface
- (vnm, dm->devices[i].hw_if_index);
- bei = pool_elt_at_index
- (em->interfaces, bhi->hw_instance);
- clib_memcpy (bhi->hw_address, addr, 6);
- clib_memcpy (bei->address, addr, 6);
-
- /* Init l3 packet size allowed on bonded interface */
- bhi->max_packet_bytes = ETHERNET_MAX_PACKET_BYTES;
- while (nlink >= 1)
- { /* for all slave links */
- int slave = slink[--nlink];
- dpdk_device_t *sdev = &dm->devices[slave];
- vnet_hw_interface_t *shi;
- vnet_sw_interface_t *ssi;
- ethernet_interface_t *sei;
- /* Add MAC to all slave links except the first one */
- if (nlink)
- {
- dpdk_log_info ("Add MAC for slave port %d",
- slave);
- rv = rte_eth_dev_mac_addr_add
- (slave, (struct ether_addr *) addr, 0);
- if (rv)
- dpdk_log_warn ("Add MAC addr failure rv=%d",
- rv);
- }
- /* Setup slave link state change callback handling */
- rte_eth_dev_callback_register
- (slave, RTE_ETH_EVENT_INTR_LSC,
- dpdk_port_state_callback, NULL);
- dpdk_device_t *sxd = &dm->devices[slave];
- sxd->flags |= DPDK_DEVICE_FLAG_BOND_SLAVE;
- sxd->bond_port = i;
- /* Set slaves bitmap for bonded interface */
- bhi->bond_info = clib_bitmap_set
- (bhi->bond_info, sdev->hw_if_index, 1);
- /* Set MACs and slave link flags on slave interface */
- shi = vnet_get_hw_interface (vnm, sdev->hw_if_index);
- ssi = vnet_get_sw_interface (vnm, sdev->sw_if_index);
- sei = pool_elt_at_index
- (em->interfaces, shi->hw_instance);
- shi->bond_info = VNET_HW_INTERFACE_BOND_INFO_SLAVE;
- ssi->flags |= VNET_SW_INTERFACE_FLAG_BOND_SLAVE;
- clib_memcpy (shi->hw_address, addr, 6);
- clib_memcpy (sei->address, addr, 6);
- /* Set l3 packet size allowed as the lowest of slave */
- if (bhi->max_packet_bytes > shi->max_packet_bytes)
- bhi->max_packet_bytes = shi->max_packet_bytes;
- }
- }
- }
- }
- /* *INDENT-ON* */
- }
- }
-
while (1)
{
/*
STATIC_ASSERT (RTE_CACHE_LINE_SIZE == 1 << CLIB_LOG2_CACHE_LINE_BYTES,
"DPDK RTE CACHE LINE SIZE does not match with 1<<CLIB_LOG2_CACHE_LINE_BYTES");
+ dpdk_cli_reference ();
+
dm->vlib_main = vm;
dm->vnet_main = vnet_get_main ();
dm->conf = &dpdk_config_main;
dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;
- /* init CLI */
- if ((error = vlib_call_init_function (vm, dpdk_cli_init)))
- return error;
-
dm->log_default = vlib_log_register_class ("dpdk", 0);
return error;
VLIB_INIT_FUNCTION (dpdk_init);
-
/*
* fd.io coding-style-patch-verification: ON
*