From: Manish Chopra Date: Thu, 14 Apr 2016 05:38:31 +0000 (-0400) Subject: qed/qede: Add GENEVE tunnel slowpath configuration support X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=9a109dd073582f69eba591888e64aa617340da6f;p=linux-beck.git 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: Manish Chopra Signed-off-by: Yuval Mintz Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- 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 #endif +#ifdef CONFIG_QEDE_GENEVE +#include +#endif #include #include #include @@ -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; }