Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1179094 authored by Govindarajulu Varadarajan's avatar Govindarajulu Varadarajan Committed by David S. Miller
Browse files

enic: Add vxlan offload support for IPv6 pkts



New adaptors supports vxlan offload for inner IPv6 and outer IPv6 vxlan
pkts.

Fw sets BIT(0) & BIT(1) in a1 if hw supports ipv6 inner & outer pkt
offload.

Signed-off-by: default avatarGovindarajulu Varadarajan <gvaradar@cisco.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4a464a2b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ struct enic_rfs_flw_tbl {
struct vxlan_offload {
	u16 vxlan_udp_port_number;
	u8 patch_level;
	u8 flags;
};

/* Per-instance private data structure */
+35 −9
Original line number Diff line number Diff line
@@ -191,10 +191,18 @@ static void enic_udp_tunnel_add(struct net_device *netdev,
		goto error;
	}

	if (ti->sa_family != AF_INET) {
	switch (ti->sa_family) {
	case AF_INET6:
		if (!(enic->vxlan.flags & ENIC_VXLAN_OUTER_IPV6)) {
			netdev_info(netdev, "vxlan: only IPv4 offload supported");
			goto error;
		}
		/* Fall through */
	case AF_INET:
		break;
	default:
		goto error;
	}

	if (enic->vxlan.vxlan_udp_port_number) {
		if (ntohs(port) == enic->vxlan.vxlan_udp_port_number)
@@ -271,22 +279,37 @@ static netdev_features_t enic_features_check(struct sk_buff *skb,
	struct enic *enic = netdev_priv(dev);
	struct udphdr *udph;
	u16 port = 0;
	u16 proto;
	u8 proto;

	if (!skb->encapsulation)
		return features;

	features = vxlan_features_check(skb, features);

	/* hardware only supports IPv4 vxlan tunnel */
	if (vlan_get_protocol(skb) != htons(ETH_P_IP))
	switch (vlan_get_protocol(skb)) {
	case htons(ETH_P_IPV6):
		if (!(enic->vxlan.flags & ENIC_VXLAN_OUTER_IPV6))
			goto out;
		proto = ipv6_hdr(skb)->nexthdr;
		break;
	case htons(ETH_P_IP):
		proto = ip_hdr(skb)->protocol;
		break;
	default:
		goto out;
	}

	/* hardware does not support offload of ipv6 inner pkt */
	if (eth->h_proto != ntohs(ETH_P_IP))
	switch (eth->h_proto) {
	case ntohs(ETH_P_IPV6):
		if (!(enic->vxlan.flags & ENIC_VXLAN_INNER_IPV6))
			goto out;
		/* Fall through */
	case ntohs(ETH_P_IP):
		break;
	default:
		goto out;
	}

	proto = ip_hdr(skb)->protocol;

	if (proto == IPPROTO_UDP) {
		udph = udp_hdr(skb);
@@ -2914,9 +2937,11 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
		netdev->hw_features |= NETIF_F_RXCSUM;
	if (ENIC_SETTING(enic, VXLAN)) {
		u64 patch_level;
		u64 a1 = 0;

		netdev->hw_enc_features |= NETIF_F_RXCSUM		|
					   NETIF_F_TSO			|
					   NETIF_F_TSO6			|
					   NETIF_F_TSO_ECN		|
					   NETIF_F_GSO_UDP_TUNNEL	|
					   NETIF_F_HW_CSUM		|
@@ -2935,9 +2960,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
		 */
		err = vnic_dev_get_supported_feature_ver(enic->vdev,
							 VIC_FEATURE_VXLAN,
							 &patch_level);
							 &patch_level, &a1);
		if (err)
			patch_level = 0;
		enic->vxlan.flags = (u8)a1;
		/* mask bits that are supported by driver
		 */
		patch_level &= BIT_ULL(0) | BIT_ULL(2);
+2 −3
Original line number Diff line number Diff line
@@ -1269,14 +1269,13 @@ int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay,
}

int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
				       u64 *supported_versions)
				       u64 *supported_versions, u64 *a1)
{
	u64 a0 = feature;
	int wait = 1000;
	u64 a1 = 0;
	int ret;

	ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait);
	ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, a1, wait);
	if (!ret)
		*supported_versions = a0;

+1 −1
Original line number Diff line number Diff line
@@ -183,6 +183,6 @@ int vnic_dev_overlay_offload_ctrl(struct vnic_dev *vdev, u8 overlay, u8 config);
int vnic_dev_overlay_offload_cfg(struct vnic_dev *vdev, u8 overlay,
				 u16 vxlan_udp_port_number);
int vnic_dev_get_supported_feature_ver(struct vnic_dev *vdev, u8 feature,
				       u64 *supported_versions);
				       u64 *supported_versions, u64 *a1);

#endif /* _VNIC_DEV_H_ */
+3 −0
Original line number Diff line number Diff line
@@ -697,6 +697,9 @@ enum overlay_ofld_cmd {

#define OVERLAY_CFG_VXLAN_PORT_UPDATE	0

#define ENIC_VXLAN_INNER_IPV6		BIT(0)
#define ENIC_VXLAN_OUTER_IPV6		BIT(1)

/* Use this enum to get the supported versions for each of these features
 * If you need to use the devcmd_get_supported_feature_version(), add
 * the new feature into this enum and install function handler in devcmd.c