#include <vnet/vnet.h>
#include <vppinfra/vec.h>
#include <vppinfra/format.h>
-#include <vlib/unix/cj.h>
#include <assert.h>
#include <vnet/ethernet/ethernet.h>
#undef _
};
+static clib_error_t *
+dpdk_add_del_mac_address (vnet_hw_interface_t * hi,
+ const u8 * address, u8 is_add)
+{
+ int error;
+ dpdk_main_t *dm = &dpdk_main;
+ dpdk_device_t *xd = vec_elt_at_index (dm->devices, hi->dev_instance);
+
+ if (is_add)
+ error = rte_eth_dev_mac_addr_add (xd->port_id,
+ (struct rte_ether_addr *) address, 0);
+ else
+ error = rte_eth_dev_mac_addr_remove (xd->port_id,
+ (struct rte_ether_addr *) address);
+
+ if (error)
+ {
+ return clib_error_return (0, "mac address add/del failed: %d", error);
+ }
+
+ return NULL;
+}
+
static clib_error_t *
dpdk_set_mac_address (vnet_hw_interface_t * hi,
const u8 * old_address, const u8 * address)
else
{
vec_reset_length (xd->default_mac_address);
- vec_add (xd->default_mac_address, address, sizeof (address));
+ vec_add (xd->default_mac_address, address, sizeof (mac_address_t));
return NULL;
}
}
struct rte_mbuf **mb, u32 n_left)
{
dpdk_main_t *dm = &dpdk_main;
+ dpdk_tx_queue_t *txq;
u32 n_retry;
int n_sent = 0;
int queue_id;
n_retry = 16;
- queue_id = vm->thread_index;
+ queue_id = vm->thread_index % xd->tx_q_used;
+ txq = vec_elt_at_index (xd->tx_queues, queue_id);
do
{
- /*
- * This device only supports one TX queue,
- * and we're running multi-threaded...
- */
- if (PREDICT_FALSE (xd->lockp != 0))
- {
- queue_id = queue_id % xd->tx_q_used;
- while (clib_atomic_test_and_set (xd->lockp[queue_id]))
- /* zzzz */
- queue_id = (queue_id + 1) % xd->tx_q_used;
- }
-
-#if 0
- if (PREDICT_FALSE (xd->flags & DPDK_DEVICE_FLAG_HQOS)) /* HQoS ON */
- {
- /* no wrap, transmit in one burst */
- dpdk_device_hqos_per_worker_thread_t *hqos =
- &xd->hqos_wt[vm->thread_index];
-
- ASSERT (hqos->swq != NULL);
+ clib_spinlock_lock_if_init (&txq->lock);
- dpdk_hqos_metadata_set (hqos, mb, n_left);
- n_sent = rte_ring_sp_enqueue_burst (hqos->swq, (void **) mb,
- n_left, 0);
- }
- else
-#endif
if (PREDICT_TRUE (xd->flags & DPDK_DEVICE_FLAG_PMD))
{
/* no wrap, transmit in one burst */
n_sent = rte_eth_tx_burst (xd->port_id, queue_id, mb, n_left);
+ n_retry--;
}
else
{
n_sent = 0;
}
- if (PREDICT_FALSE (xd->lockp != 0))
- clib_atomic_release (xd->lockp[queue_id]);
+ clib_spinlock_unlock_if_init (&txq->lock);
if (PREDICT_FALSE (n_sent < 0))
{
xd->hw_if_index)->tx_node_index;
vlib_error_count (vm, node_index, DPDK_TX_FUNC_ERROR_BAD_RETVAL, 1);
- clib_warning ("rte_eth_tx_burst[%d]: error %d",
- xd->port_id, n_sent);
return n_left; // untransmitted packets
}
n_left -= n_sent;
return n_left;
}
-static_always_inline void
+static_always_inline __clib_unused void
dpdk_prefetch_buffer (vlib_main_t * vm, struct rte_mbuf *mb)
{
vlib_buffer_t *b = vlib_buffer_from_rte_mbuf (mb);
.subif_add_del_function = dpdk_subif_add_del_function,
.rx_redirect_to_node = dpdk_set_interface_next_node,
.mac_addr_change_function = dpdk_set_mac_address,
+ .mac_addr_add_del_function = dpdk_add_del_mac_address,
.format_flow = format_dpdk_flow,
.flow_ops_function = dpdk_flow_ops_fn,
};