1
0
Fork 0

qed/qede: Add VXLAN tunnel slowpath configuration support

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

Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
hifive-unleashed-5.1
Manish Chopra 2016-04-14 01:38:30 -04:00 committed by David S. Miller
parent 464f664501
commit b18e170cac
5 changed files with 86 additions and 4 deletions

View File

@ -103,4 +103,15 @@ config QEDE
depends on QED
---help---
This enables the support for ...
config QEDE_VXLAN
bool "Virtual eXtensible Local Area Network support"
default n
depends on QEDE && VXLAN && !(QEDE=y && VXLAN=m)
---help---
This enables hardware offload support for VXLAN protocol over
qede module. Say Y here if you want to enable hardware offload
support for Virtual eXtensible Local Area Network (VXLAN)
in the driver.
endif # NET_VENDOR_QLOGIC

View File

@ -744,6 +744,7 @@ static void qed_update_pf_params(struct qed_dev *cdev,
static int qed_slowpath_start(struct qed_dev *cdev,
struct qed_slowpath_params *params)
{
struct qed_tunn_start_params tunn_info;
struct qed_mcp_drv_version drv_version;
const u8 *data = NULL;
struct qed_hwfn *hwfn;
@ -776,7 +777,12 @@ static int qed_slowpath_start(struct qed_dev *cdev,
/* Start the slowpath */
data = cdev->firmware->data;
rc = qed_hw_init(cdev, NULL, true, cdev->int_params.out.int_mode,
memset(&tunn_info, 0, sizeof(tunn_info));
tunn_info.tunn_mode |= 1 << QED_MODE_VXLAN_TUNN;
tunn_info.tunn_clss_vxlan = QED_TUNN_CLSS_MAC_VLAN;
rc = qed_hw_init(cdev, &tunn_info, true,
cdev->int_params.out.int_mode,
true, data);
if (rc)
goto err2;

View File

@ -353,7 +353,8 @@ int qed_sp_pf_start(struct qed_hwfn *p_hwfn,
DMA_REGPAIR_LE(p_ramrod->consolid_q_pbl_addr,
p_hwfn->p_consq->chain.pbl.p_phys_table);
qed_tunn_set_pf_start_params(p_hwfn, NULL, NULL);
qed_tunn_set_pf_start_params(p_hwfn, p_tunn,
&p_ramrod->tunnel_config);
p_hwfn->hw_info.personality = PERSONALITY_ETH;
DP_VERBOSE(p_hwfn, QED_MSG_SPQ,

View File

@ -169,6 +169,7 @@ struct qede_dev {
bool accept_any_vlan;
struct delayed_work sp_task;
unsigned long sp_flags;
u16 vxlan_dst_port;
};
enum QEDE_STATE {
@ -289,7 +290,8 @@ struct qede_fastpath {
#define QEDE_CSUM_ERROR BIT(0)
#define QEDE_CSUM_UNNECESSARY BIT(1)
#define QEDE_SP_RX_MODE 1
#define QEDE_SP_RX_MODE 1
#define QEDE_SP_VXLAN_PORT_CONFIG 2
union qede_reload_args {
u16 mtu;

View File

@ -24,7 +24,9 @@
#include <linux/netdev_features.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#ifdef CONFIG_QEDE_VXLAN
#include <net/vxlan.h>
#endif
#include <linux/ip.h>
#include <net/ipv6.h>
#include <net/tcp.h>
@ -1821,6 +1823,42 @@ static void qede_vlan_mark_nonconfigured(struct qede_dev *edev)
edev->accept_any_vlan = false;
}
#ifdef CONFIG_QEDE_VXLAN
static void qede_add_vxlan_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->vxlan_dst_port)
return;
edev->vxlan_dst_port = t_port;
DP_VERBOSE(edev, QED_MSG_DEBUG, "Added vxlan port=%d", t_port);
set_bit(QEDE_SP_VXLAN_PORT_CONFIG, &edev->sp_flags);
schedule_delayed_work(&edev->sp_task, 0);
}
static void qede_del_vxlan_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->vxlan_dst_port)
return;
edev->vxlan_dst_port = 0;
DP_VERBOSE(edev, QED_MSG_DEBUG, "Deleted vxlan port=%d", t_port);
set_bit(QEDE_SP_VXLAN_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,
@ -1832,6 +1870,10 @@ static const struct net_device_ops qede_netdev_ops = {
.ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
.ndo_get_stats64 = qede_get_stats64,
#ifdef CONFIG_QEDE_VXLAN
.ndo_add_vxlan_port = qede_add_vxlan_port,
.ndo_del_vxlan_port = qede_del_vxlan_port,
#endif
};
/* -------------------------------------------------------------------------
@ -2004,6 +2046,8 @@ static void qede_sp_task(struct work_struct *work)
{
struct qede_dev *edev = container_of(work, struct qede_dev,
sp_task.work);
struct qed_dev *cdev = edev->cdev;
mutex_lock(&edev->qede_lock);
if (edev->state == QEDE_STATE_OPEN) {
@ -2011,6 +2055,15 @@ static void qede_sp_task(struct work_struct *work)
qede_config_rx_mode(edev->ndev);
}
if (test_and_clear_bit(QEDE_SP_VXLAN_PORT_CONFIG, &edev->sp_flags)) {
struct qed_tunn_params tunn_params;
memset(&tunn_params, 0, sizeof(tunn_params));
tunn_params.update_vxlan_port = 1;
tunn_params.vxlan_port = edev->vxlan_dst_port;
qed_ops->tunn_config(cdev, &tunn_params);
}
mutex_unlock(&edev->qede_lock);
}
@ -3149,12 +3202,21 @@ void qede_reload(struct qede_dev *edev,
static int qede_open(struct net_device *ndev)
{
struct qede_dev *edev = netdev_priv(ndev);
int rc;
netif_carrier_off(ndev);
edev->ops->common->set_power_state(edev->cdev, PCI_D0);
return qede_load(edev, QEDE_LOAD_NORMAL);
rc = qede_load(edev, QEDE_LOAD_NORMAL);
if (rc)
return rc;
#ifdef CONFIG_QEDE_VXLAN
vxlan_get_rx_port(ndev);
#endif
return 0;
}
static int qede_close(struct net_device *ndev)