dpdk_main_t dpdk_main;
-#include <vlibapi/api.h>
-#include <vlibmemory/api.h>
-
-/* define message IDs */
-#include <dpdk/api/dpdk_msg_enum.h>
-
-#define vl_typedefs /* define message structures */
-#include <dpdk/api/dpdk_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <dpdk/api/dpdk_all_api_h.h>
-#undef vl_endianfun
-
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-
-/* Get the API version number. */
-#define vl_api_version(n,v) static u32 api_version=(v);
-#include <dpdk/api/dpdk_all_api_h.h>
-#undef vl_api_version
-
-/* Macro to finish up custom dump fns */
-#define FINISH \
- vec_add1 (s, 0); \
- vl_print (handle, (char *)s); \
- vec_free (s); \
- return handle;
-
-#include <vlibapi/api_helper_macros.h>
-
-static void
- vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler
- (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp)
-{
- vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
- int rv = 0;
-
- dpdk_main_t *dm = &dpdk_main;
- dpdk_device_t *xd;
-
- u32 sw_if_index = ntohl (mp->sw_if_index);
- u32 subport = ntohl (mp->subport);
- u32 pipe = ntohl (mp->pipe);
- u32 profile = ntohl (mp->profile);
- vnet_hw_interface_t *hw;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- /* hw_if & dpdk device */
- hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
-
- xd = vec_elt_at_index (dm->devices, hw->dev_instance);
-
- rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
-}
-
-static void *vl_api_sw_interface_set_dpdk_hqos_pipe_t_print
- (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp, void *handle)
-{
- u8 *s;
-
- s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_pipe ");
-
- s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
-
- s = format (s, "subport %u pipe %u profile %u ",
- ntohl (mp->subport), ntohl (mp->pipe), ntohl (mp->profile));
-
- FINISH;
-}
-
-static void
- vl_api_sw_interface_set_dpdk_hqos_subport_t_handler
- (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp)
-{
- vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
- int rv = 0;
-
- dpdk_main_t *dm = &dpdk_main;
- dpdk_device_t *xd;
- struct rte_sched_subport_params p;
-
- u32 sw_if_index = ntohl (mp->sw_if_index);
- u32 subport = ntohl (mp->subport);
- p.tb_rate = ntohl (mp->tb_rate);
- p.tb_size = ntohl (mp->tb_size);
- p.tc_rate[0] = ntohl (mp->tc_rate[0]);
- p.tc_rate[1] = ntohl (mp->tc_rate[1]);
- p.tc_rate[2] = ntohl (mp->tc_rate[2]);
- p.tc_rate[3] = ntohl (mp->tc_rate[3]);
- p.tc_period = ntohl (mp->tc_period);
-
- vnet_hw_interface_t *hw;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- /* hw_if & dpdk device */
- hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
-
- xd = vec_elt_at_index (dm->devices, hw->dev_instance);
-
- rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
-}
-
-static void *vl_api_sw_interface_set_dpdk_hqos_subport_t_print
- (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp, void *handle)
-{
- u8 *s;
-
- s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_subport ");
-
- s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
-
- s =
- format (s,
- "subport %u rate %u bkt_size %u tc0 %u tc1 %u tc2 %u tc3 %u period %u",
- ntohl (mp->subport), ntohl (mp->tb_rate), ntohl (mp->tb_size),
- ntohl (mp->tc_rate[0]), ntohl (mp->tc_rate[1]),
- ntohl (mp->tc_rate[2]), ntohl (mp->tc_rate[3]),
- ntohl (mp->tc_period));
-
- FINISH;
-}
-
-static void
- vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler
- (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp)
-{
- vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
- int rv = 0;
-
- dpdk_main_t *dm = &dpdk_main;
- vlib_thread_main_t *tm = vlib_get_thread_main ();
- dpdk_device_t *xd;
-
- u32 sw_if_index = ntohl (mp->sw_if_index);
- u32 entry = ntohl (mp->entry);
- u32 tc = ntohl (mp->tc);
- u32 queue = ntohl (mp->queue);
- u32 val, i;
-
- vnet_hw_interface_t *hw;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- /* hw_if & dpdk device */
- hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
-
- xd = vec_elt_at_index (dm->devices, hw->dev_instance);
-
- if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
- {
- clib_warning ("invalid traffic class !!");
- rv = VNET_API_ERROR_INVALID_VALUE;
- goto done;
- }
- if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
- {
- clib_warning ("invalid queue !!");
- rv = VNET_API_ERROR_INVALID_VALUE;
- goto done;
- }
-
- /* Detect the set of worker threads */
- uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
-
- if (p == 0)
- {
- clib_warning ("worker thread registration AWOL !!");
- rv = VNET_API_ERROR_INVALID_VALUE_2;
- goto done;
- }
-
- vlib_thread_registration_t *tr = (vlib_thread_registration_t *) p[0];
- int worker_thread_first = tr->first_index;
- int worker_thread_count = tr->count;
-
- val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
- for (i = 0; i < worker_thread_count; i++)
- xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
-
- BAD_SW_IF_INDEX_LABEL;
-done:
-
- REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
-}
-
-static void *vl_api_sw_interface_set_dpdk_hqos_tctbl_t_print
- (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp, void *handle)
-{
- u8 *s;
-
- s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_tctbl ");
-
- s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
-
- s = format (s, "entry %u tc %u queue %u",
- ntohl (mp->entry), ntohl (mp->tc), ntohl (mp->queue));
-
- FINISH;
-}
-
-#define foreach_dpdk_plugin_api_msg \
-_(SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe) \
-_(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport) \
-_(SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl)
-
-/* Set up the API message handling tables */
-static clib_error_t *
-dpdk_plugin_api_hookup (vlib_main_t * vm)
-{
- dpdk_main_t *dm __attribute__ ((unused)) = &dpdk_main;
-#define _(N,n) \
- vl_msg_api_set_handlers((VL_API_##N + dm->msg_id_base), \
- #n, \
- vl_api_##n##_t_handler, \
- vl_noop_handler, \
- vl_api_##n##_t_endian, \
- vl_api_##n##_t_print, \
- sizeof(vl_api_##n##_t), 1);
- foreach_dpdk_plugin_api_msg;
-#undef _
- return 0;
-}
-
-#define vl_msg_name_crc_list
-#include <dpdk/api/dpdk_all_api_h.h>
-#undef vl_msg_name_crc_list
-
-static void
-setup_message_id_table (dpdk_main_t * dm, api_main_t * am)
-{
-#define _(id,n,crc) \
- vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + dm->msg_id_base);
- foreach_vl_msg_name_crc_dpdk;
-#undef _
-}
-
-// TODO
-/*
-static void plugin_custom_dump_configure (dpdk_main_t * dm)
-{
-#define _(n,f) dm->api_main->msg_print_handlers \
- [VL_API_##n + dm->msg_id_base] \
- = (void *) vl_api_##f##_t_print;
- foreach_dpdk_plugin_api_msg;
-#undef _
-}
-*/
-/* force linker to link functions used by vlib and declared weak */
-void *vlib_weakly_linked_functions[] = {
- &rte_pktmbuf_init,
- &rte_pktmbuf_pool_init,
-};
-
#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 (os_get_cpu_number () == 0);
-
- if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- {
- vnet_hw_interface_set_flags (dm->vnet_main, xd->vlib_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++)
- {
-
- rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
- xd->cpu_socket, 0,
- dm->
- pktmbuf_pools[xd->cpu_socket_id_by_queue
- [j]]);
-
- /* 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[xd->cpu_socket_id_by_queue
- [j]]);
- 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)
{
}
else if (ETHERNET_INTERFACE_FLAG_CONFIG_MTU (flags))
{
- /*
- * DAW-FIXME: The Cisco VIC firmware does not provide an api for a
- * driver to dynamically change the mtu. If/when the
- * VIC firmware gets fixed, then this should be removed.
- */
- if (xd->pmd == VNET_DPDK_PMD_ENIC)
- {
- struct rte_eth_dev_info dev_info;
-
- /*
- * Restore mtu to what has been set by CIMC in the firmware cfg.
- */
- rte_eth_dev_info_get (xd->device_index, &dev_info);
- hi->max_packet_bytes = dev_info.max_rx_pktlen;
+ int rv;
- vlib_cli_output (vlib_get_main (),
- "Cisco VIC mtu can only be changed "
- "using CIMC then rebooting the server!");
- }
- else
- {
- int rv;
+ xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
- xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
+ if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
+ dpdk_device_stop (xd);
- if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
- 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);
- rv = rte_eth_dev_configure
- (xd->device_index, xd->rx_q_used, xd->tx_q_used, &xd->port_conf);
+ if (rv < 0)
+ vlib_cli_output (vlib_get_main (),
+ "rte_eth_dev_configure[%d]: err %d",
+ xd->device_index, rv);
- if (rv < 0)
- vlib_cli_output (vlib_get_main (),
- "rte_eth_dev_configure[%d]: err %d",
- xd->device_index, rv);
+ rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
- rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
+ if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
+ dpdk_device_start (xd);
- 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);
- }
- }
}
return old;
}
-void
+static void
dpdk_device_lock_init (dpdk_device_t * xd)
{
int q;
}
}
-void
-dpdk_device_lock_free (dpdk_device_t * xd)
-{
- int q;
-
- for (q = 0; q < vec_len (xd->lockp); q++)
- clib_mem_free ((void *) xd->lockp[q]);
- vec_free (xd->lockp);
- xd->lockp = 0;
-}
-
static clib_error_t *
dpdk_lib_init (dpdk_main_t * dm)
{
clib_error_t *error;
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;
- vlib_thread_registration_t *tr, *tr_hqos;
- uword *p, *p_hqos;
+ vlib_thread_registration_t *tr_hqos;
+ uword *p_hqos;
- u32 next_cpu = 0, next_hqos_cpu = 0;
+ u32 next_hqos_cpu = 0;
u8 af_packet_port_id = 0;
+ u8 bond_ether_port_id = 0;
last_pci_addr.as_u32 = ~0;
- dm->input_cpu_first_index = 0;
- dm->input_cpu_count = 1;
-
- /* find out which cpus will be used for input */
- p = hash_get_mem (tm->thread_registrations_by_name, "workers");
- tr = p ? (vlib_thread_registration_t *) p[0] : 0;
-
- if (tr && tr->count > 0)
- {
- dm->input_cpu_first_index = tr->first_index;
- dm->input_cpu_count = tr->count;
- }
-
- vec_validate_aligned (dm->devices_by_cpu, tm->n_vlib_mains - 1,
- CLIB_CACHE_LINE_BYTES);
-
dm->hqos_cpu_first_index = 0;
dm->hqos_cpu_count = 0;
"dpdk rx");
if (dm->conf->enable_tcp_udp_checksum)
- dm->buffer_flags_template &= ~(IP_BUFFER_L4_CHECKSUM_CORRECT
- | IP_BUFFER_L4_CHECKSUM_COMPUTED);
+ dm->buffer_flags_template &= ~(VNET_BUFFER_F_L4_CHECKSUM_CORRECT
+ | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED);
/* vlib_buffer_t template */
vec_validate_aligned (dm->buffer_templates, tm->n_vlib_mains - 1,
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;
{
xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
port_conf_template.rxmode.jumbo_frame = 0;
+ port_conf_template.rxmode.enable_scatter = 0;
}
else
{
xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
port_conf_template.rxmode.jumbo_frame = 1;
+ port_conf_template.rxmode.enable_scatter = 1;
xd->flags |= DPDK_DEVICE_FLAG_MAYBE_MULTISEG;
}
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:
+ xd->port_type = port_type_from_speed_capa (&dev_info);
+ xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
+ DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+
+ break;
+ 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", 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 */
case VNET_DPDK_PMD_AF_PACKET:
xd->port_type = VNET_DPDK_PORT_TYPE_AF_PACKET;
- xd->af_packet_port_id = af_packet_port_id++;
+ xd->port_id = af_packet_port_id++;
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:
dpdk_device_and_queue_t *dq;
int q;
- if (devconf->workers)
- {
- int i;
- q = 0;
- /* *INDENT-OFF* */
- clib_bitmap_foreach (i, devconf->workers, ({
- int cpu = dm->input_cpu_first_index + i;
- unsigned lcore = vlib_worker_threads[cpu].lcore_id;
- vec_validate(xd->cpu_socket_id_by_queue, q);
- xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id(lcore);
- vec_add2(dm->devices_by_cpu[cpu], dq, 1);
- dq->device = xd->device_index;
- dq->queue_id = q++;
- }));
- /* *INDENT-ON* */
- }
- else
- for (q = 0; q < xd->rx_q_used; q++)
- {
- int cpu = dm->input_cpu_first_index + next_cpu;
- unsigned lcore = vlib_worker_threads[cpu].lcore_id;
-
- /*
- * numa node for worker thread handling this queue
- * needed for taking buffers from the right mempool
- */
- vec_validate (xd->cpu_socket_id_by_queue, q);
- xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id (lcore);
-
- /*
- * construct vector of (device,queue) pairs for each worker thread
- */
- vec_add2 (dm->devices_by_cpu[cpu], dq, 1);
- dq->device = xd->device_index;
- dq->queue_id = q;
-
- next_cpu++;
- if (next_cpu == dm->input_cpu_count)
- next_cpu = 0;
- }
-
-
if (devconf->hqos_enabled)
{
xd->flags |= DPDK_DEVICE_FLAG_HQOS;
vec_validate_aligned (xd->d_trace_buffers, tm->n_vlib_mains,
CLIB_CACHE_LINE_BYTES);
- rv = dpdk_port_setup (dm, xd);
-
- if (rv)
- return rv;
-
- if (devconf->hqos_enabled)
- {
- rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
- if (rv)
- return rv;
- }
/* count the number of descriptors used for this device */
nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
error = ethernet_register_interface
(dm->vnet_main, dpdk_device_class.index, xd->device_index,
/* ethernet address */ addr,
- &xd->vlib_hw_if_index, dpdk_flag_change);
+ &xd->hw_if_index, dpdk_flag_change);
if (error)
return error;
- sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->vlib_hw_if_index);
+ sw = vnet_get_hw_sw_interface (dm->vnet_main, xd->hw_if_index);
xd->vlib_sw_if_index = sw->sw_if_index;
- hi = vnet_get_hw_interface (dm->vnet_main, xd->vlib_hw_if_index);
+ vnet_hw_interface_set_input_node (dm->vnet_main, xd->hw_if_index,
+ dpdk_input_node.index);
+
+ if (devconf->workers)
+ {
+ int i;
+ q = 0;
+ /* *INDENT-OFF* */
+ clib_bitmap_foreach (i, devconf->workers, ({
+ 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_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);
+
+ if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD)
+ hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD;
+
+ dpdk_device_setup (xd);
+
+ 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;
+ }
/*
- * DAW-FIXME: The Cisco VIC firmware does not provide an api for a
- * driver to dynamically change the mtu. If/when the
- * VIC firmware gets fixed, then this should 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
+ * otherwis in the startup config.
*/
if (xd->pmd == VNET_DPDK_PMD_ENIC)
{
- /*
- * Initialize mtu to what has been set by CIMC in the firmware cfg.
- */
- hi->max_packet_bytes = dev_info.max_rx_pktlen;
if (devconf->vlan_strip_offload != DPDK_DEVICE_VLAN_STRIP_OFF)
vlan_strip = 1; /* remove vlan tag from VIC port by default */
else
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;
- else if (unformat (input, "enable-cryptodev"))
- conf->cryptodev = 1;
-
else if (unformat (input, "dev default %U", unformat_vlib_cli_sub_input,
&sub_input))
{
}
else if (unformat (input, "num-mbufs %d", &conf->num_mbufs))
;
- else if (unformat (input, "kni %d", &conf->num_kni))
- ;
else if (unformat (input, "uio-driver %s", &conf->uio_driver_name))
;
else if (unformat (input, "socket-mem %s", &socket_mem))
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 ();
rte_dump_physmem_layout (stdout);
/* main thread 1st */
- error = vlib_buffer_pool_create (vm, conf->num_mbufs, rte_socket_id ());
+ error = dpdk_buffer_pool_create (vm, conf->num_mbufs, rte_socket_id ());
if (error)
return error;
for (i = 0; i < RTE_MAX_LCORE; i++)
{
- error = vlib_buffer_pool_create (vm, conf->num_mbufs,
+ error = dpdk_buffer_pool_create (vm, conf->num_mbufs,
rte_lcore_to_socket_id (i));
if (error)
return error;
ed->sw_if_index = xd->vlib_sw_if_index;
ed->admin_up = (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) != 0;
ed->old_link_state = (u8)
- vnet_hw_interface_is_link_up (vnm, xd->vlib_hw_if_index);
+ vnet_hw_interface_is_link_up (vnm, xd->hw_if_index);
ed->new_link_state = (u8) xd->link.link_status;
}
- if ((xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) &&
- ((xd->link.link_status != 0) ^
- vnet_hw_interface_is_link_up (vnm, xd->vlib_hw_if_index)))
+ 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);
ed->sw_if_index = xd->vlib_sw_if_index;
ed->flags = hw_flags;
}
- vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index, hw_flags);
+ vnet_hw_interface_set_flags (vnm, xd->hw_if_index, hw_flags);
}
}
error = dpdk_lib_init (dm);
- /*
- * Turn on the input node if we found some devices to drive
- * and we're not running worker threads or i/o threads
- */
-
- if (error == 0 && vec_len (dm->devices) > 0)
- {
- if (tm->n_vlib_mains == 1)
- vlib_node_set_state (vm, dpdk_input_node.index,
- VLIB_NODE_STATE_POLLING);
- else
- for (i = 0; i < tm->n_vlib_mains; i++)
- if (vec_len (dm->devices_by_cpu[i]) > 0)
- vlib_node_set_state (vlib_mains[i], dpdk_input_node.index,
- VLIB_NODE_STATE_POLLING);
- }
-
if (error)
clib_error_report (error);
/*
* 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)
{
for (i = 0; i < nports; i++)
{
- struct rte_eth_dev_info dev_info;
- rte_eth_dev_info_get (i, &dev_info);
- if (!dev_info.driver_name)
- dev_info.driver_name = dev_info.pci_dev->driver->driver.name;
-
- ASSERT (dev_info.driver_name);
- if (strncmp (dev_info.driver_name, "rte_bond_pmd", 12) == 0)
+ xd = &dm->devices[i];
+ ASSERT (i == xd->device_index);
+ if (xd->pmd == VNET_DPDK_PMD_BOND)
{
u8 addr[6];
u8 slink[16];
int rv;
/* Get MAC of 1st slave link */
- rte_eth_macaddr_get (slink[0],
- (struct ether_addr *) addr);
+ rte_eth_macaddr_get
+ (slink[0], (struct ether_addr *) addr);
+
/* Set MAC of bounded interface to that of 1st slave link */
- rv =
- rte_eth_bond_mac_address_set (i,
- (struct ether_addr *)
- addr);
- if (rv < 0)
- clib_warning ("Failed to set MAC address");
+ 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)
+ clib_warning ("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].vlib_hw_if_index);
- bei =
- pool_elt_at_index (em->interfaces, bhi->hw_instance);
+ 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;
bhi->max_l3_packet_bytes[VLIB_RX] =
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)
- rte_eth_dev_mac_addr_add (slave,
- (struct ether_addr *)
- addr, 0);
+ {
+ 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->vlib_hw_if_index, 1);
- /* Set slave link flags on slave interface */
- shi =
- vnet_get_hw_interface (vnm, sdev->vlib_hw_if_index);
- ssi =
- vnet_get_sw_interface (vnm, sdev->vlib_sw_if_index);
+ 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->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;
};
/* *INDENT-ON* */
-int
-dpdk_set_stat_poll_interval (f64 interval)
-{
- if (interval < DPDK_MIN_STATS_POLL_INTERVAL)
- return (VNET_API_ERROR_INVALID_VALUE);
-
- dpdk_main.stat_poll_interval = interval;
-
- return 0;
-}
-
-int
-dpdk_set_link_state_poll_interval (f64 interval)
-{
- if (interval < DPDK_MIN_LINK_POLL_INTERVAL)
- return (VNET_API_ERROR_INVALID_VALUE);
-
- dpdk_main.link_state_poll_interval = interval;
-
- return 0;
-}
-
-clib_error_t *
+static clib_error_t *
dpdk_init (vlib_main_t * vm)
{
dpdk_main_t *dm = &dpdk_main;
STATIC_ASSERT (offsetof (frame_queue_trace_t, cacheline0) == 0,
"Cache line marker must be 1st element in frame_queue_trace_t");
- u8 *name;
- name = format (0, "dpdk_%08x%c", api_version, 0);
-
- /* Ask for a correctly-sized block of API message decode slots */
- dm->msg_id_base = vl_msg_api_get_msg_ids
- ((char *) name, VL_MSG_FIRST_AVAILABLE);
- vec_free (name);
-
dm->vlib_main = vm;
dm->vnet_main = vnet_get_main ();
dm->conf = &dpdk_config_main;
- error = dpdk_plugin_api_hookup (vm);
-
- /* Add our API messages to the global name_crc hash table */
- setup_message_id_table (dm, &api_main);
-
-// TODO
-// plugin_custom_dump_configure (dm);
-
ei = vlib_get_node_by_name (vm, (u8 *) "ethernet-input");
if (ei == 0)
return clib_error_return (0, "ethernet-input node AWOL");
dm->conf->num_mbufs = dm->conf->num_mbufs ? dm->conf->num_mbufs : NB_MBUF;
vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
- dm->dpdk_device_by_kni_port_id = hash_create (0, sizeof (uword));
- dm->vu_sw_if_index_by_listener_fd = hash_create (0, sizeof (uword));
- dm->vu_sw_if_index_by_sock_fd = hash_create (0, sizeof (uword));
-
- /* $$$ use n_thread_stacks since it's known-good at this point */
vec_validate (dm->recycle, tm->n_thread_stacks - 1);
/* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */
dm->buffer_flags_template =
(VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_EXT_HDR_VALID
- | IP_BUFFER_L4_CHECKSUM_COMPUTED | IP_BUFFER_L4_CHECKSUM_CORRECT);
+ | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED |
+ VNET_BUFFER_F_L4_CHECKSUM_CORRECT);
dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;