This patch adds driver hooks to implement ndo_ops to add/del udp port in the HW to identify GENEVE tunnels.
Also cleans up the features_check path now that we support multiple udp based tunnels. Signed-off-by: Anjali Singhai Jain <anjali.sing...@intel.com> Signed-off-by: Kiran Patil <kiran.pa...@intel.com> --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 35 +++++++++++++++++++++-------- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index c701bbb..69c2c88 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -336,6 +336,7 @@ struct i40e_pf { #define I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE BIT_ULL(38) #define I40E_FLAG_LINK_POLLING_ENABLED BIT_ULL(39) #define I40E_FLAG_VEB_MODE_ENABLED BIT_ULL(40) +#define I40E_FLAG_GENEVE_OFFLOAD_CAPABLE BIT_ULL(41) #define I40E_FLAG_NO_PCI_LINK_CHECK BIT_ULL(42) /* tracks features that get auto disabled by errors */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f6447c7..e0e40c3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -30,6 +30,9 @@ #if IS_ENABLED(CONFIG_VXLAN) #include <net/vxlan.h> #endif +#if IS_ENABLED(CONFIG_GENEVE) +#include <net/geneve.h> +#endif #include <net/udp_tunnel.h> #include <net/protocol.h> @@ -6990,7 +6993,7 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf) **/ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf) { -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_hw *hw = &pf->hw; i40e_status ret; __be16 port; @@ -8174,7 +8177,8 @@ static int i40e_sw_init(struct i40e_pf *pf) I40E_FLAG_HW_ATR_EVICT_CAPABLE | I40E_FLAG_OUTER_UDP_CSUM_CAPABLE | I40E_FLAG_WB_ON_ITR_CAPABLE | - I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE; + I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE | + I40E_FLAG_GENEVE_OFFLOAD_CAPABLE; } pf->eeprom_version = 0xDEAD; pf->lan_veb = I40E_NO_VEB; @@ -8273,7 +8277,7 @@ static int i40e_set_features(struct net_device *netdev, return 0; } -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) /** * i40e_get_udp_port_idx - Lookup a possibly offloaded for Rx UDP port * @pf: board private structure @@ -8308,14 +8312,18 @@ static void i40e_add_tunnel_port(struct net_device *netdev, sa_family_t sa_family, __be16 port, u32 type) { -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; u8 next_idx; u8 idx; - if (type != UDP_TUNNEL_VXLAN) + if (!(type == UDP_TUNNEL_VXLAN || type == UDP_TUNNEL_GENEVE)) + return; + + if ((type == UDP_TUNNEL_GENEVE) && + (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))) return; if (sa_family == AF_INET6) @@ -8343,6 +8351,8 @@ static void i40e_add_tunnel_port(struct net_device *netdev, pf->udp_ports[next_idx].index = port; if (type == UDP_TUNNEL_VXLAN) pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_VXLAN; + else if (type == UDP_TUNNEL_GENEVE) + pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_NGE; pf->pending_udp_bitmap |= BIT_ULL(next_idx); pf->flags |= I40E_FLAG_UDP_FILTER_SYNC; @@ -8363,13 +8373,13 @@ static void i40e_del_tunnel_port(struct net_device *netdev, sa_family_t sa_family, __be16 port, u32 type) { -#if IS_ENABLED(CONFIG_VXLAN) +#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE) struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; u8 idx; - if (type != UDP_TUNNEL_VXLAN) + if (!(type == UDP_TUNNEL_VXLAN || type == UDP_TUNNEL_GENEVE)) return; if (sa_family == AF_INET6) @@ -8569,7 +8579,10 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, nlflags, 0, 0, filter_mask, NULL); } -#define I40E_MAX_TUNNEL_HDR_LEN 80 +/* Hardware supports L4 tunnel length of 128B (=2^7) which includes + * inner mac plus all inner ethertypes. + */ +#define I40E_MAX_TUNNEL_HDR_LEN 128 /** * i40e_features_check - Validate encapsulated packet conforms to limits * @skb: skb buff @@ -8581,7 +8594,7 @@ static netdev_features_t i40e_features_check(struct sk_buff *skb, netdev_features_t features) { if (skb->encapsulation && - (skb_inner_mac_header(skb) - skb_transport_header(skb) > + ((skb_inner_network_header(skb) - skb_transport_header(skb)) > I40E_MAX_TUNNEL_HDR_LEN)) return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); @@ -8651,6 +8664,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) np->vsi = vsi; netdev->hw_enc_features |= NETIF_F_IP_CSUM | + NETIF_F_RXCSUM | NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE | NETIF_F_TSO; @@ -10165,6 +10179,9 @@ static void i40e_print_features(struct i40e_pf *pf) #if IS_ENABLED(CONFIG_VXLAN) buf += sprintf(buf, "VxLAN "); #endif +#if IS_ENABLED(CONFIG_GENVE) + i += snprintf(&buf[i], REMAIN(i), "Geneve "); +#endif if (pf->flags & I40E_FLAG_PTP) buf += sprintf(buf, "PTP "); #ifdef I40E_FCOE diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 46556b6..a66d590 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1374,7 +1374,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT)) return; - /* If VXLAN traffic has an outer UDPv4 checksum we need to check + /* If VXLAN/GENEVE traffic has an outer UDPv4 checksum we need to check * it in the driver, hardware does not do it for us. * Since L3L4P bit was set we assume a valid IHL value (>=5) * so the total length of IPv4 header is IHL*4 bytes -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html