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;
+ u32 tso = b->flags & VNET_BUFFER_F_GSO;
u64 ol_flags;
/* Is there any work for us? */
- if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum) == 0))
+ if (PREDICT_TRUE ((ip_cksum | tcp_cksum | udp_cksum | tso) == 0))
return;
mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data;
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;
+ ol_flags |= tso ? (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG) : 0;
+
+ if (tso)
+ {
+ mb->l4_len = vnet_buffer2 (b)->gso_l4_hdr_sz;
+ mb->tso_segsz = vnet_buffer2 (b)->gso_size;
+ }
+
mb->ol_flags |= ol_flags;
/* we are trying to help compiler here by using local ol_flags with known
int i;
clib_error_t *error;
vlib_main_t *vm = vlib_get_main ();
+ vnet_main_t *vnm = vnet_get_main ();
vlib_thread_main_t *tm = vlib_get_thread_main ();
vnet_device_main_t *vdm = &vnet_device_main;
vnet_sw_interface_t *sw;
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)
+ {
+ if (xd->flags & DPDK_DEVICE_FLAG_TX_OFFLOAD && hi != NULL)
+ {
+ /*tcp_udp checksum must be enabled*/
+ if (hi->flags & VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD)
+ {
+ hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+ vnm->interface_main.gso_interface_count++;
+ xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO |
+ DEV_TX_OFFLOAD_UDP_TSO;
+ }
+ else
+ return clib_error_return (0, "TSO: TCP/UDP checksum offload must be enabled");
+ }
+ }
+
dpdk_device_setup (xd);
if (vec_len (xd->errors))
devconf->pci_addr.as_u32 = pci_addr.as_u32;
devconf->hqos_enabled = 0;
+ devconf->tso = DPDK_DEVICE_TSO_DEFAULT;
#if 0
dpdk_device_config_hqos_default (&devconf->hqos);
#endif
{
devconf->hqos_enabled = 1;
}
+ else if (unformat (input, "tso on"))
+ {
+ devconf->tso = DPDK_DEVICE_TSO_ON;
+ }
+ else if (unformat (input, "tso off"))
+ {
+ devconf->tso = DPDK_DEVICE_TSO_OFF;
+ }
else
{
error = clib_error_return (0, "unknown input `%U'",
devconf->vlan_strip_offload =
conf->default_devconf.vlan_strip_offload;
+ /* copy tso config from default device */
+ _(tso)
+
/* add DPDK EAL whitelist/blacklist entry */
if (num_whitelisted > 0 && devconf->is_blacklisted == 0)
{