Skip to content

Commit

Permalink
i40e/i40evf: Add support for IPIP and SIT offloads
Browse files Browse the repository at this point in the history
Looking over the documentation it turns out enabling IPIP and SIT offloads
for i40e is pretty straightforward.  As such I decided to enable them with
this patch.  In my testing I am seeing an improvement of 8 to 10 Gb/s
for IPIP and SIT tunnels with this offload enabled.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Apr 26, 2016
1 parent b0fe330 commit 577389a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9120,6 +9120,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
NETIF_F_TSO_ECN |
NETIF_F_TSO6 |
NETIF_F_GSO_GRE |
NETIF_F_GSO_IPIP |
NETIF_F_GSO_SIT |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_SCTP_CRC |
Expand Down
24 changes: 16 additions & 8 deletions drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2299,7 +2299,10 @@ static int i40e_tso(struct sk_buff *skb, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
ip.v6->payload_len = 0;
}

if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | SKB_GSO_GRE |
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
SKB_GSO_IPIP |
SKB_GSO_SIT |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_UDP_TUNNEL_CSUM)) {
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) {
/* determine offset of outer transport header */
Expand Down Expand Up @@ -2442,13 +2445,6 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
&l4_proto, &frag_off);
}

/* compute outer L3 header size */
tunnel |= ((l4.hdr - ip.hdr) / 4) <<
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;

/* switch IP header pointer from outer to inner header */
ip.hdr = skb_inner_network_header(skb);

/* define outer transport */
switch (l4_proto) {
case IPPROTO_UDP:
Expand All @@ -2459,6 +2455,11 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
tunnel |= I40E_TXD_CTX_GRE_TUNNELING;
*tx_flags |= I40E_TX_FLAGS_UDP_TUNNEL;
break;
case IPPROTO_IPIP:
case IPPROTO_IPV6:
*tx_flags |= I40E_TX_FLAGS_UDP_TUNNEL;
l4.hdr = skb_inner_network_header(skb);
break;
default:
if (*tx_flags & I40E_TX_FLAGS_TSO)
return -1;
Expand All @@ -2467,6 +2468,13 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
return 0;
}

/* compute outer L3 header size */
tunnel |= ((l4.hdr - ip.hdr) / 4) <<
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;

/* switch IP header pointer from outer to inner header */
ip.hdr = skb_inner_network_header(skb);

/* compute tunnel header size */
tunnel |= ((ip.hdr - l4.hdr) / 2) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
Expand Down
24 changes: 16 additions & 8 deletions drivers/net/ethernet/intel/i40evf/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,10 @@ static int i40e_tso(struct sk_buff *skb, u8 *hdr_len, u64 *cd_type_cmd_tso_mss)
ip.v6->payload_len = 0;
}

if (skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | SKB_GSO_GRE |
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
SKB_GSO_IPIP |
SKB_GSO_SIT |
SKB_GSO_UDP_TUNNEL |
SKB_GSO_UDP_TUNNEL_CSUM)) {
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM) {
/* determine offset of outer transport header */
Expand Down Expand Up @@ -1665,13 +1668,6 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
&l4_proto, &frag_off);
}

/* compute outer L3 header size */
tunnel |= ((l4.hdr - ip.hdr) / 4) <<
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;

/* switch IP header pointer from outer to inner header */
ip.hdr = skb_inner_network_header(skb);

/* define outer transport */
switch (l4_proto) {
case IPPROTO_UDP:
Expand All @@ -1682,6 +1678,11 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
tunnel |= I40E_TXD_CTX_GRE_TUNNELING;
*tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL;
break;
case IPPROTO_IPIP:
case IPPROTO_IPV6:
*tx_flags |= I40E_TX_FLAGS_VXLAN_TUNNEL;
l4.hdr = skb_inner_network_header(skb);
break;
default:
if (*tx_flags & I40E_TX_FLAGS_TSO)
return -1;
Expand All @@ -1690,6 +1691,13 @@ static int i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
return 0;
}

/* compute outer L3 header size */
tunnel |= ((l4.hdr - ip.hdr) / 4) <<
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT;

/* switch IP header pointer from outer to inner header */
ip.hdr = skb_inner_network_header(skb);

/* compute tunnel header size */
tunnel |= ((ip.hdr - l4.hdr) / 2) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40evf/i40evf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,8 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
NETIF_F_TSO_ECN |
NETIF_F_TSO6 |
NETIF_F_GSO_GRE |
NETIF_F_GSO_IPIP |
NETIF_F_GSO_SIT |
NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_GSO_UDP_TUNNEL_CSUM |
NETIF_F_SCTP_CRC |
Expand Down

0 comments on commit 577389a

Please sign in to comment.