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

Commit 9a109dd0 authored by Manish Chopra's avatar Manish Chopra Committed by David S. Miller
Browse files

qed/qede: Add GENEVE tunnel slowpath configuration support



This patch enables GENEVE tunnel on the adapter and
add support for driver hooks to configure UDP ports
for GENEVE tunnel offload to be performed by the adapter.

Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: default avatarAriel Elior <Ariel.Elior@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b18e170c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -114,4 +114,14 @@ config QEDE_VXLAN
	  support for Virtual eXtensible Local Area Network (VXLAN)
	  in the driver.

config QEDE_GENEVE
	bool "Generic Network Virtualization Encapsulation (GENEVE) support"
	depends on QEDE && GENEVE && !(QEDE=y && GENEVE=m)
	---help---
	  This allows one to create GENEVE virtual interfaces that provide
	  Layer 2 Networks over Layer 3 Networks. GENEVE is often used
	  to tunnel virtual network infrastructure in virtualized environments.
	  Say Y here if you want to enable hardware offload support for
	  Generic Network Virtualization Encapsulation (GENEVE) in the driver.

endif # NET_VENDOR_QLOGIC
+4 −1
Original line number Diff line number Diff line
@@ -778,7 +778,10 @@ static int qed_slowpath_start(struct qed_dev *cdev,
	data = cdev->firmware->data;

	memset(&tunn_info, 0, sizeof(tunn_info));
	tunn_info.tunn_mode |=  1 << QED_MODE_VXLAN_TUNN;
	tunn_info.tunn_mode |=  1 << QED_MODE_VXLAN_TUNN |
				1 << QED_MODE_L2GENEVE_TUNN |
				1 << QED_MODE_IPGENEVE_TUNN;

	tunn_info.tunn_clss_vxlan = QED_TUNN_CLSS_MAC_VLAN;

	rc = qed_hw_init(cdev, &tunn_info, true,
+2 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ struct qede_dev {
	struct delayed_work		sp_task;
	unsigned long			sp_flags;
	u16				vxlan_dst_port;
	u16				geneve_dst_port;
};

enum QEDE_STATE {
@@ -292,6 +293,7 @@ struct qede_fastpath {

#define QEDE_SP_RX_MODE			1
#define QEDE_SP_VXLAN_PORT_CONFIG	2
#define QEDE_SP_GENEVE_PORT_CONFIG	3

union qede_reload_args {
	u16 mtu;
+53 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@
#ifdef CONFIG_QEDE_VXLAN
#include <net/vxlan.h>
#endif
#ifdef CONFIG_QEDE_GENEVE
#include <net/geneve.h>
#endif
#include <linux/ip.h>
#include <net/ipv6.h>
#include <net/tcp.h>
@@ -1859,6 +1862,40 @@ static void qede_del_vxlan_port(struct net_device *dev,
}
#endif

#ifdef CONFIG_QEDE_GENEVE
static void qede_add_geneve_port(struct net_device *dev,
				 sa_family_t sa_family, __be16 port)
{
	struct qede_dev *edev = netdev_priv(dev);
	u16 t_port = ntohs(port);

	if (edev->geneve_dst_port)
		return;

	edev->geneve_dst_port = t_port;

	DP_VERBOSE(edev, QED_MSG_DEBUG, "Added geneve port=%d", t_port);
	set_bit(QEDE_SP_GENEVE_PORT_CONFIG, &edev->sp_flags);
	schedule_delayed_work(&edev->sp_task, 0);
}

static void qede_del_geneve_port(struct net_device *dev,
				 sa_family_t sa_family, __be16 port)
{
	struct qede_dev *edev = netdev_priv(dev);
	u16 t_port = ntohs(port);

	if (t_port != edev->geneve_dst_port)
		return;

	edev->geneve_dst_port = 0;

	DP_VERBOSE(edev, QED_MSG_DEBUG, "Deleted geneve port=%d", t_port);
	set_bit(QEDE_SP_GENEVE_PORT_CONFIG, &edev->sp_flags);
	schedule_delayed_work(&edev->sp_task, 0);
}
#endif

static const struct net_device_ops qede_netdev_ops = {
	.ndo_open = qede_open,
	.ndo_stop = qede_close,
@@ -1874,6 +1911,10 @@ static const struct net_device_ops qede_netdev_ops = {
	.ndo_add_vxlan_port = qede_add_vxlan_port,
	.ndo_del_vxlan_port = qede_del_vxlan_port,
#endif
#ifdef CONFIG_QEDE_GENEVE
	.ndo_add_geneve_port = qede_add_geneve_port,
	.ndo_del_geneve_port = qede_del_geneve_port,
#endif
};

/* -------------------------------------------------------------------------
@@ -2064,6 +2105,15 @@ static void qede_sp_task(struct work_struct *work)
		qed_ops->tunn_config(cdev, &tunn_params);
	}

	if (test_and_clear_bit(QEDE_SP_GENEVE_PORT_CONFIG, &edev->sp_flags)) {
		struct qed_tunn_params tunn_params;

		memset(&tunn_params, 0, sizeof(tunn_params));
		tunn_params.update_geneve_port = 1;
		tunn_params.geneve_port = edev->geneve_dst_port;
		qed_ops->tunn_config(cdev, &tunn_params);
	}

	mutex_unlock(&edev->qede_lock);
}

@@ -3215,6 +3265,9 @@ static int qede_open(struct net_device *ndev)

#ifdef CONFIG_QEDE_VXLAN
	vxlan_get_rx_port(ndev);
#endif
#ifdef CONFIG_QEDE_GENEVE
	geneve_get_rx_port(ndev);
#endif
	return 0;
}