summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/qlogic/Kconfig10
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_main.c5
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede.h2
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_main.c53
4 files changed, 69 insertions, 1 deletions
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index 7a65522005ee..c0a11b5158e7 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -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
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 0bb2c574df79..c1533a64f41c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -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,
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 16a43444af21..8521feeda4de 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -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;
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 895016d9f7e3..6c40316f1e70 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -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);
}
@@ -3216,6 +3266,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;
}