#define LINK_STATE_ELOGS 0
-#define DEFAULT_HUGE_DIR "/run/vpp/hugepages"
-#define VPP_RUN_DIR "/run/vpp"
+#define DEFAULT_HUGE_DIR (VPP_RUN_DIR "/hugepages")
/* Port configuration, mildly modified Intel app values */
},
};
-clib_error_t *
-dpdk_port_setup (dpdk_main_t * dm, dpdk_device_t * xd)
+static dpdk_port_type_t
+port_type_from_speed_capa (struct rte_eth_dev_info *dev_info)
{
- int rv;
- int j;
- ASSERT (vlib_get_thread_index () == 0);
-
- if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- {
- vnet_hw_interface_set_flags (dm->vnet_main, xd->hw_if_index, 0);
- rte_eth_dev_stop (xd->device_index);
- }
-
- rv = rte_eth_dev_configure (xd->device_index, xd->rx_q_used,
- xd->tx_q_used, &xd->port_conf);
-
- if (rv < 0)
- return clib_error_return (0, "rte_eth_dev_configure[%d]: err %d",
- xd->device_index, rv);
-
- /* Set up one TX-queue per worker thread */
- for (j = 0; j < xd->tx_q_used; j++)
- {
- rv = rte_eth_tx_queue_setup (xd->device_index, j, xd->nb_tx_desc,
- xd->cpu_socket, &xd->tx_conf);
-
- /* retry with any other CPU socket */
- if (rv < 0)
- rv = rte_eth_tx_queue_setup (xd->device_index, j, xd->nb_tx_desc,
- SOCKET_ID_ANY, &xd->tx_conf);
- if (rv < 0)
- break;
- }
-
- if (rv < 0)
- return clib_error_return (0, "rte_eth_tx_queue_setup[%d]: err %d",
- xd->device_index, rv);
-
- for (j = 0; j < xd->rx_q_used; j++)
- {
- uword tidx = vnet_get_device_input_thread_index (dm->vnet_main,
- xd->hw_if_index, j);
- unsigned lcore = vlib_worker_threads[tidx].lcore_id;
- u16 socket_id = rte_lcore_to_socket_id (lcore);
-
- rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
- xd->cpu_socket, 0,
- dm->pktmbuf_pools[socket_id]);
-
- /* retry with any other CPU socket */
- if (rv < 0)
- rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
- SOCKET_ID_ANY, 0,
- dm->pktmbuf_pools[socket_id]);
- if (rv < 0)
- return clib_error_return (0, "rte_eth_rx_queue_setup[%d]: err %d",
- xd->device_index, rv);
- }
-
- if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- {
- int rv;
- rv = rte_eth_dev_start (xd->device_index);
- if (!rv && xd->default_mac_address)
- rv = rte_eth_dev_default_mac_addr_set (xd->device_index,
- (struct ether_addr *)
- xd->default_mac_address);
- if (rv < 0)
- clib_warning ("rte_eth_dev_start %d returned %d",
- xd->device_index, rv);
- }
- return 0;
+ 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_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_10G)
+ return VNET_DPDK_PORT_TYPE_ETH_10G;
+ else if (dev_info->speed_capa & ETH_LINK_SPEED_1G)
+ return VNET_DPDK_PORT_TYPE_ETH_1G;
+
+ return VNET_DPDK_PORT_TYPE_UNKNOWN;
}
+
static u32
dpdk_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
{
xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- rte_eth_dev_stop (xd->device_index);
+ dpdk_device_stop (xd);
rv = rte_eth_dev_configure
(xd->device_index, xd->rx_q_used, xd->tx_q_used, &xd->port_conf);
rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- {
- int rv = rte_eth_dev_start (xd->device_index);
- if (!rv && xd->default_mac_address)
- rv = rte_eth_dev_default_mac_addr_set (xd->device_index,
- (struct ether_addr *)
- xd->default_mac_address);
- if (rv < 0)
- clib_warning ("rte_eth_dev_start %d returned %d",
- xd->device_index, rv);
- }
+ dpdk_device_start (xd);
}
return old;
u8 vlan_strip = 0;
int j;
struct rte_eth_dev_info dev_info;
- clib_error_t *rv;
struct rte_eth_link l;
dpdk_device_config_t *devconf = 0;
vlib_pci_addr_t pci_addr;
switch (xd->pmd)
{
- /* 1G adapters */
+ /* Drivers with valid speed_capa set */
case VNET_DPDK_PMD_E1000EM:
case VNET_DPDK_PMD_IGB:
- case VNET_DPDK_PMD_IGBVF:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
+ case VNET_DPDK_PMD_IXGBE:
+ case VNET_DPDK_PMD_I40E:
+ case VNET_DPDK_PMD_CXGBE:
+ case VNET_DPDK_PMD_MLX4:
+ case VNET_DPDK_PMD_MLX5:
+ xd->port_type = port_type_from_speed_capa (&dev_info);
break;
- /* 10G adapters */
- case VNET_DPDK_PMD_IXGBE:
+ /* SR-IOV VFs */
+ case VNET_DPDK_PMD_IGBVF:
case VNET_DPDK_PMD_IXGBEVF:
+ case VNET_DPDK_PMD_I40EVF:
+ xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
+ xd->port_conf.rxmode.hw_strip_crc = 1;
+ break;
+
case VNET_DPDK_PMD_THUNDERX:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
+ xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
break;
+
case VNET_DPDK_PMD_DPAA2:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
break;
/* Cisco VIC */
case VNET_DPDK_PMD_ENIC:
rte_eth_link_get_nowait (i, &l);
- xd->flags |= DPDK_DEVICE_FLAG_PMD_SUPPORTS_PTYPE;
if (l.link_speed == 40000)
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
else
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
break;
- /* Intel Fortville */
- case VNET_DPDK_PMD_I40E:
- case VNET_DPDK_PMD_I40EVF:
- xd->flags |= DPDK_DEVICE_FLAG_PMD_SUPPORTS_PTYPE;
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
-
- switch (dev_info.pci_dev->id.device_id)
- {
- case I40E_DEV_ID_10G_BASE_T:
- case I40E_DEV_ID_SFP_XL710:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
- break;
- case I40E_DEV_ID_QSFP_A:
- case I40E_DEV_ID_QSFP_B:
- case I40E_DEV_ID_QSFP_C:
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
- break;
- case I40E_DEV_ID_VF:
- rte_eth_link_get_nowait (i, &l);
- xd->port_type = l.link_speed == 10000 ?
- VNET_DPDK_PORT_TYPE_ETH_10G : VNET_DPDK_PORT_TYPE_ETH_40G;
- break;
- default:
- xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
- }
- break;
-
- case VNET_DPDK_PMD_CXGBE:
- switch (dev_info.pci_dev->id.device_id)
- {
- case 0x540d: /* T580-CR */
- case 0x5410: /* T580-LP-cr */
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
- break;
- case 0x5403: /* T540-CR */
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
- break;
- default:
- xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
- }
- break;
-
- case VNET_DPDK_PMD_MLX5:
- {
- char *pn_100g[] = { "MCX415A-CCAT", "MCX416A-CCAT",
- "MCX556A-ECAT", "MCX556A-EDAT", "MCX555A-ECAT",
- "MCX515A-CCAT", "MCX516A-CCAT", "MCX516A-CDAT", 0
- };
- char *pn_40g[] = { "MCX413A-BCAT", "MCX414A-BCAT",
- "MCX415A-BCAT", "MCX416A-BCAT", "MCX4131A-BCAT", 0
- };
- char *pn_10g[] = { "MCX4111A-XCAT", "MCX4121A-XCAT", 0 };
-
- vlib_pci_device_t *pd = vlib_get_pci_device (&pci_addr);
- u8 *pn = 0;
- char **c;
- int found = 0;
- pn = format (0, "%U%c",
- format_vlib_pci_vpd, pd->vpd_r, "PN", 0);
-
- if (!pn)
- break;
-
- c = pn_100g;
- while (!found && c[0])
- {
- if (strncmp ((char *) pn, c[0], strlen (c[0])) == 0)
- {
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_100G;
- break;
- }
- c++;
- }
-
- c = pn_40g;
- while (!found && c[0])
- {
- if (strncmp ((char *) pn, c[0], strlen (c[0])) == 0)
- {
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_40G;
- break;
- }
- c++;
- }
-
- c = pn_10g;
- while (!found && c[0])
- {
- if (strncmp ((char *) pn, c[0], strlen (c[0])) == 0)
- {
- xd->port_type = VNET_DPDK_PORT_TYPE_ETH_10G;
- break;
- }
- c++;
- }
-
- vec_free (pn);
- }
-
- break;
/* Intel Red Rock Canyon */
case VNET_DPDK_PMD_FM10K:
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_SWITCH;
+ xd->port_conf.rxmode.hw_strip_crc = 1;
break;
/* virtio */
break;
case VNET_DPDK_PMD_BOND:
- xd->flags |= DPDK_DEVICE_FLAG_PMD_SUPPORTS_PTYPE;
xd->port_type = VNET_DPDK_PORT_TYPE_ETH_BOND;
xd->port_id = bond_ether_port_id++;
break;
+ case VNET_DPDK_PMD_VIRTIO_USER:
+ xd->port_type = VNET_DPDK_PORT_TYPE_VIRTIO_USER;
+ break;
+
default:
xd->port_type = VNET_DPDK_PORT_TYPE_UNKNOWN;
}
sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->hw_if_index);
xd->vlib_sw_if_index = sw->sw_if_index;
- vnet_set_device_input_node (dm->vnet_main, xd->hw_if_index,
- dpdk_input_node.index);
+ vnet_hw_interface_set_input_node (dm->vnet_main, xd->hw_if_index,
+ dpdk_input_node.index);
if (devconf->workers)
{
q = 0;
/* *INDENT-OFF* */
clib_bitmap_foreach (i, devconf->workers, ({
- vnet_device_input_assign_thread (dm->vnet_main, xd->hw_if_index, q++,
+ vnet_hw_interface_assign_rx_thread (dm->vnet_main, xd->hw_if_index, q++,
vdm->first_worker_thread_index + i);
}));
/* *INDENT-ON* */
else
for (q = 0; q < xd->rx_q_used; q++)
{
- vnet_device_input_assign_thread (dm->vnet_main, xd->hw_if_index, q, /* any */
- ~1);
+ vnet_hw_interface_assign_rx_thread (dm->vnet_main, xd->hw_if_index, q, /* any */
+ ~1);
}
hi = vnet_get_hw_interface (dm->vnet_main, xd->hw_if_index);
- rv = dpdk_port_setup (dm, xd);
+ dpdk_device_setup (xd);
- if (rv)
- return rv;
+ if (vec_len (xd->errors))
+ clib_warning ("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;
dpdk_device_config_t *devconf;
vlib_pci_addr_t pci_addr;
unformat_input_t sub_input;
+ uword x;
u8 *s, *tmp = 0;
u8 *rte_cmd = 0, *ethname = 0;
u32 log_level;
u8 *socket_mem = 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;
vec_free (mem_by_socket);
- rv = mkdir (VPP_RUN_DIR, 0755);
- if (rv && errno != EEXIST)
- {
- error = clib_error_return (0, "mkdir '%s' failed errno %d",
- VPP_RUN_DIR, errno);
- goto done;
- }
+ /* Make sure VPP_RUN_DIR exists */
+ error = unix_make_vpp_run_dir ();
+ if (error)
+ goto done;
rv = mkdir (DEFAULT_HUGE_DIR, 0755);
if (rv && errno != EEXIST)
/* Set up DPDK eal and packet mbuf pool early. */
- log_level = (CLIB_DEBUG > 0) ? RTE_LOG_DEBUG : RTE_LOG_NOTICE;
-
+#if RTE_VERSION >= RTE_VERSION_NUM(17, 5, 0, 0)
+ rte_log_set_global_level (log_level);
+#else
rte_set_log_level (log_level);
+#endif
vm = vlib_get_main ();
/*
* Extra set up for bond interfaces:
* 1. Setup MACs for bond interfaces and their slave links which was set
- * in dpdk_port_setup() but needs to be done again here to take effect.
- * 2. Set up info for bond interface related CLI support.
+ * 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 ();
if (nports > 0)
(slink[0], (struct ether_addr *) addr);
/* Set MAC of bounded interface to that of 1st slave link */
- clib_warning ("Set MAC for bond dev# %d", i);
+ clib_warning ("Set MAC for bond port %d BondEthernet%d",
+ i, xd->port_id);
rv = rte_eth_bond_mac_address_set
(i, (struct ether_addr *) addr);
if (rv)
/* Add MAC to all slave links except the first one */
if (nlink)
{
- clib_warning ("Add MAC for slave dev# %d", slave);
+ clib_warning ("Add MAC for slave port %d", slave);
rv = rte_eth_dev_mac_addr_add
(slave, (struct ether_addr *) addr, 0);
if (rv)
clib_warning ("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 slave link flags on slave interface */
+ /* 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->vlib_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_l3_packet_bytes[VLIB_RX] >
shi->max_l3_packet_bytes[VLIB_RX])
bhi->max_l3_packet_bytes[VLIB_RX] =
bhi->max_l3_packet_bytes[VLIB_TX] =
shi->max_l3_packet_bytes[VLIB_RX];
-
/* Set max 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;