From c5122cf584128f9d42655189e69fda7151c1f275 Mon Sep 17 00:00:00 2001 From: Edward Cree <ecree@solarflare.com> Date: Thu, 12 Nov 2020 15:20:05 +0000 Subject: [PATCH] sfc: support GRE TSO on EF100 We can treat SKB_GSO_GRE almost exactly the same as UDP tunnels, except that we don't want to edit the outer UDP len (as there isn't one). For SKB_GSO_GRE_CSUM, we have to use GSO_PARTIAL as the device doesn't support offload of non-UDP outer L4 checksums. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Acked-by: Martin Habets <mhabets@solarflare.com> Reviewed-by: Alexander Duyck <alexanderduyck@fb.com> --- drivers/net/ethernet/sfc/ef100_nic.c | 7 ++++++- drivers/net/ethernet/sfc/ef100_tx.c | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index 05d22220228a4..518268ce20644 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -185,11 +185,16 @@ static int efx_ef100_init_datapath_caps(struct efx_nic *efx) if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3)) { struct net_device *net_dev = efx->net_dev; netdev_features_t tso = NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_PARTIAL | - NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM; + NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM | + NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM; net_dev->features |= tso; net_dev->hw_features |= tso; net_dev->hw_enc_features |= tso; + /* EF100 HW can only offload outer checksums if they are UDP, + * so for GRE_CSUM we have to use GSO_PARTIAL. + */ + net_dev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; } efx->num_mac_stats = MCDI_WORD(outbuf, GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS); diff --git a/drivers/net/ethernet/sfc/ef100_tx.c b/drivers/net/ethernet/sfc/ef100_tx.c index a9e045c54a79e..26ef51d6b5423 100644 --- a/drivers/net/ethernet/sfc/ef100_tx.c +++ b/drivers/net/ethernet/sfc/ef100_tx.c @@ -194,6 +194,7 @@ static void ef100_make_tso_desc(struct efx_nic *efx, u16 vlan_tci = skb_vlan_tag_get(skb); u32 mss = skb_shinfo(skb)->gso_size; bool encap = skb->encapsulation; + bool udp_encap = false; u16 vlan_enable = 0; struct tcphdr *tcp; bool outer_csum; @@ -212,6 +213,9 @@ static void ef100_make_tso_desc(struct efx_nic *efx, outer_l4_offset = skb_transport_offset(skb); ip_offset = skb_inner_network_offset(skb); tcp_offset = skb_inner_transport_offset(skb); + if (skb_shinfo(skb)->gso_type & + (SKB_GSO_UDP_TUNNEL | SKB_GSO_UDP_TUNNEL_CSUM)) + udp_encap = true; } else { ip_offset = skb_network_offset(skb); tcp_offset = skb_transport_offset(skb); @@ -239,7 +243,7 @@ static void ef100_make_tso_desc(struct efx_nic *efx, ESF_GZ_TX_TSO_ED_INNER_IP_LEN, 1, ESF_GZ_TX_TSO_OUTER_L3_OFF_W, outer_ip_offset >> 1, ESF_GZ_TX_TSO_OUTER_L4_OFF_W, outer_l4_offset >> 1, - ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN, encap && !gso_partial, + ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN, udp_encap && !gso_partial, ESF_GZ_TX_TSO_ED_OUTER_IP_LEN, encap && !gso_partial, ESF_GZ_TX_TSO_ED_OUTER_IP4_ID, encap ? mangleid : ESE_GZ_TX_DESC_IP4_ID_NO_OP, -- 2.30.2