&tx_vector[tx_tail], tx_head - tx_tail);
rv = rte_ring_sp_enqueue_burst (hqos->swq,
(void **) &tx_vector[tx_tail],
+#if RTE_VERSION >= RTE_VERSION_NUM(17, 5, 0, 0)
+ (uint16_t) (tx_head - tx_tail), 0);
+#else
(uint16_t) (tx_head - tx_tail));
+#endif
}
else if (PREDICT_TRUE (xd->flags & DPDK_DEVICE_FLAG_PMD))
{
struct rte_mbuf *mb;
b = vlib_get_buffer (vm, bi);
mb = rte_mbuf_from_vlib_buffer (b);
- CLIB_PREFETCH (mb, CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (mb, 2 * CLIB_CACHE_LINE_BYTES, STORE);
CLIB_PREFETCH (b, CLIB_CACHE_LINE_BYTES, LOAD);
}
vec_add1 (dm->recycle[my_cpu], bi);
}
+static_always_inline void
+dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
+ struct rte_mbuf *mb)
+{
+ u32 ip_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
+ u32 tcp_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
+ u32 udp_cksum = b->flags & VNET_BUFFER_F_OFFLOAD_UDP_CKSUM;
+ int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4;
+ u64 ol_flags;
+
+ /* Is there any work for us? */
+ if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum) == 0))
+ return;
+
+ mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data;
+ mb->l3_len = vnet_buffer (b)->l4_hdr_offset -
+ vnet_buffer (b)->l3_hdr_offset;
+ mb->outer_l3_len = 0;
+ mb->outer_l2_len = 0;
+ ol_flags = is_ip4 ? PKT_TX_IPV4 : PKT_TX_IPV6;
+ ol_flags |= ip_cksum ? PKT_TX_IP_CKSUM : 0;
+ ol_flags |= tcp_cksum ? PKT_TX_TCP_CKSUM : 0;
+ ol_flags |= udp_cksum ? PKT_TX_UDP_CKSUM : 0;
+ mb->ol_flags |= ol_flags;
+
+ /* we are trying to help compiler here by using local ol_flags with known
+ state of all flags */
+ if (xd->flags & DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM)
+ rte_net_intel_cksum_flags_prepare (mb, ol_flags);
+}
+
/*
* Transmits the packets on the frame to the interface associated with the
* node. It first copies packets on the frame to a tx_vector containing the
mb2 = rte_mbuf_from_vlib_buffer (b2);
mb3 = rte_mbuf_from_vlib_buffer (b3);
+ if (PREDICT_FALSE ((xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD) &&
+ (or_flags & VNET_BUFFER_F_OFFLOAD_TCP_CKSUM)))
+ {
+ dpdk_buffer_tx_offload (xd, b0, mb0);
+ dpdk_buffer_tx_offload (xd, b1, mb1);
+ dpdk_buffer_tx_offload (xd, b2, mb2);
+ dpdk_buffer_tx_offload (xd, b3, mb3);
+ }
+
if (PREDICT_FALSE (or_flags & VLIB_BUFFER_RECYCLE))
{
dpdk_buffer_recycle (vm, node, b0, bi0, &mb0);
dpdk_validate_rte_mbuf (vm, b0, 1);
mb0 = rte_mbuf_from_vlib_buffer (b0);
+ dpdk_buffer_tx_offload (xd, b0, mb0);
dpdk_buffer_recycle (vm, node, b0, bi0, &mb0);
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
dpdk_main_t *dm = &dpdk_main;
dpdk_device_t *xd = vec_elt_at_index (dm->devices, hif->dev_instance);
- int rv = 0;
+
+ if (xd->flags & DPDK_DEVICE_FLAG_PMD_INIT_FAIL)
+ return clib_error_return (0, "Interface not initialized");
if (is_up)
{
- f64 now = vlib_time_now (dm->vlib_main);
-
+ vnet_hw_interface_set_flags (vnm, xd->hw_if_index,
+ VNET_HW_INTERFACE_FLAG_LINK_UP);
if ((xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) == 0)
- {
- 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 (xd->flags & DPDK_DEVICE_FLAG_PROMISC)
- rte_eth_promiscuous_enable (xd->device_index);
- else
- rte_eth_promiscuous_disable (xd->device_index);
-
- rte_eth_allmulticast_enable (xd->device_index);
-
- if (xd->pmd == VNET_DPDK_PMD_BOND)
- {
- u8 slink[16];
- int nlink = rte_eth_bond_slaves_get (xd->device_index, slink, 16);
- while (nlink >= 1)
- {
- u8 dpdk_port = slink[--nlink];
- rte_eth_allmulticast_enable (dpdk_port);
- }
- }
-
+ dpdk_device_start (xd);
xd->flags |= DPDK_DEVICE_FLAG_ADMIN_UP;
+ f64 now = vlib_time_now (dm->vlib_main);
dpdk_update_counters (xd, now);
dpdk_update_link_state (xd, now);
}
else
{
- xd->flags &= ~DPDK_DEVICE_FLAG_ADMIN_UP;
-
- rte_eth_allmulticast_disable (xd->device_index);
vnet_hw_interface_set_flags (vnm, xd->hw_if_index, 0);
- rte_eth_dev_stop (xd->device_index);
-
- /* For bonded interface, stop slave links */
- if (xd->pmd == VNET_DPDK_PMD_BOND)
- {
- u8 slink[16];
- int nlink = rte_eth_bond_slaves_get (xd->device_index, slink, 16);
- while (nlink >= 1)
- {
- u8 dpdk_port = slink[--nlink];
- rte_eth_dev_stop (dpdk_port);
- }
- }
+ if ((xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) != 0)
+ dpdk_device_stop (xd);
+ xd->flags &= ~DPDK_DEVICE_FLAG_ADMIN_UP;
}
- if (rv < 0)
- clib_warning ("rte_eth_dev_%s error: %d", is_up ? "start" : "stop", rv);
-
return /* no error */ 0;
}