DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels
@ 2017-12-24 10:46 Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 01/14] net/sfc: fix label name to be consistent Andrew Rybchenko
                   ` (14 more replies)
  0 siblings, 15 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

MC reboot handling is required for tunnels support since tunnel UDP
ports reconfiguration triggers MC reboot.

Support tunnel packet types classification and inner/outer Rx checksum
offload in EF10 native Rx datapath.

Support for inner checksum offload on transmit is datapath-independent
since it just requires to enable the offload.

checkpatches.sh generates errors/warnings for base driver patches
because of coding standard difference.

Warning about positive errno is expected since positive error codes are
used inside the driver (since base driver uses positive error code) and
conversion to negative is done in net/sfc ethdev interface implementation.

Andrew Rybchenko (13):
  net/sfc: fix label name to be consistent
  net/sfc: do not hold management event queue lock while MCDI
  net/sfc: handle MC reboot event
  net/sfc: retry port start to handle MC reboot in the middle
  net/sfc/base: control RxQ scatter using flag instead of type
  net/sfc/base: add function to create packed stream RxQ
  net/sfc/base: allow to request inner classes for Rx packets
  net/sfc: support UDP tunnel ports configuration
  net/sfc: fix incorrect bitwise ORing of L3/L4 packet types
  net/sfc: support VXLAN and NVGRE packet types classification
  net/sfc: correct Rx checksum offloads for tunnel packets
  net/sfc: support inner checksum offload on transmit
  doc: add net/sfc tunnels support to release features

Ivan Malov (1):
  net/sfc/base: add API to control UDP tunnel ports

 doc/guides/nics/features/sfc_efx.ini   |   2 +
 doc/guides/nics/sfc_efx.rst            |  24 ++
 doc/guides/rel_notes/release_18_02.rst |   8 +
 drivers/net/sfc/Makefile               |   1 +
 drivers/net/sfc/base/ef10_ev.c         |   3 +-
 drivers/net/sfc/base/ef10_impl.h       |   2 +
 drivers/net/sfc/base/ef10_nic.c        |  10 +-
 drivers/net/sfc/base/ef10_rx.c         |  71 +++--
 drivers/net/sfc/base/efx.h             |  96 ++++++-
 drivers/net/sfc/base/efx_check.h       |   7 +
 drivers/net/sfc/base/efx_impl.h        |  30 +-
 drivers/net/sfc/base/efx_mcdi.h        |   4 +
 drivers/net/sfc/base/efx_rx.c          |  74 ++++-
 drivers/net/sfc/base/efx_tunnel.c      | 487 +++++++++++++++++++++++++++++++++
 drivers/net/sfc/efsys.h                |   2 +
 drivers/net/sfc/sfc.c                  | 145 ++++++++--
 drivers/net/sfc/sfc.h                  |  26 ++
 drivers/net/sfc/sfc_dp_rx.h            |   4 +-
 drivers/net/sfc/sfc_ef10_rx.c          | 126 +++++++--
 drivers/net/sfc/sfc_ethdev.c           | 133 ++++++++-
 drivers/net/sfc/sfc_ev.c               |  27 +-
 drivers/net/sfc/sfc_intr.c             |   5 +-
 drivers/net/sfc/sfc_mcdi.c             |   2 +-
 drivers/net/sfc/sfc_rx.c               |  15 +-
 drivers/net/sfc/sfc_rx.h               |   1 +
 drivers/net/sfc/sfc_tx.c               |   8 +
 26 files changed, 1208 insertions(+), 105 deletions(-)
 create mode 100644 drivers/net/sfc/base/efx_tunnel.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 01/14] net/sfc: fix label name to be consistent
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 02/14] net/sfc: do not hold management event queue lock while MCDI Andrew Rybchenko
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev; +Cc: stable

Management event queue is the right name of event queue 0.

Fixes: 3b809c27b1fe ("net/sfc: support link status change interrupt")
Cc: stable@dpdk.org

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc_ev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index a16dc27..b29eb2f 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -743,7 +743,7 @@ sfc_ev_start(struct sfc_adapter *sa)
 	if (sa->intr.lsc_intr) {
 		rc = sfc_ev_qprime(sa->mgmt_evq);
 		if (rc != 0)
-			goto fail_evq0_prime;
+			goto fail_mgmt_evq_prime;
 	}
 
 	rte_spinlock_unlock(&sa->mgmt_evq_lock);
@@ -763,7 +763,7 @@ sfc_ev_start(struct sfc_adapter *sa)
 
 	return 0;
 
-fail_evq0_prime:
+fail_mgmt_evq_prime:
 	sfc_ev_qstop(sa->mgmt_evq);
 
 fail_mgmt_evq_start:
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 02/14] net/sfc: do not hold management event queue lock while MCDI
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 01/14] net/sfc: fix label name to be consistent Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 03/14] net/sfc: handle MC reboot event Andrew Rybchenko
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev; +Cc: stable

MCDI execution may require MCDI proxy handling which involves
management event queue polling. So, it is a bad idea to hold
managment event queue lock when MCDI is executed.

Event queue creation and destruction are MCDI operations.

Fixes: 4650ed44c120 ("net/sfc: support MCDI proxy")
Cc: stable@dpdk.org

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc.h      | 22 ++++++++++++++++++++++
 drivers/net/sfc/sfc_ev.c   | 23 ++++++++++++++---------
 drivers/net/sfc/sfc_intr.c |  5 +++--
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index b72eba0..ef980a4 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -212,7 +212,29 @@ struct sfc_adapter {
 	unsigned int			evq_count;
 
 	unsigned int			mgmt_evq_index;
+	/*
+	 * The lock is used to serialise management event queue polling
+	 * which can be done from different context. Also the lock
+	 * guarantees that mgmt_evq_running is preserved while the lock
+	 * is held. It is used to serialise polling and start/stop
+	 * operations.
+	 *
+	 * Locks which may be held when the lock is acquired:
+	 *  - adapter lock, when:
+	 *    - device start/stop to change mgmt_evq_running
+	 *    - any control operations in client side MCDI proxy handling to
+	 *	poll management event queue waiting for proxy response
+	 *  - MCDI lock, when:
+	 *    - any control operations in client side MCDI proxy handling to
+	 *	poll management event queue waiting for proxy response
+	 *
+	 * Locks which are acquired with the lock held:
+	 *  - nic_lock, when:
+	 *    - MC event processing on management event queue polling
+	 *	(e.g. MC REBOOT or BADASSERT events)
+	 */
 	rte_spinlock_t			mgmt_evq_lock;
+	bool				mgmt_evq_running;
 	struct sfc_evq			*mgmt_evq;
 
 	unsigned int			rxq_count;
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index b29eb2f..5fbebbf 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -565,10 +565,8 @@ void
 sfc_ev_mgmt_qpoll(struct sfc_adapter *sa)
 {
 	if (rte_spinlock_trylock(&sa->mgmt_evq_lock)) {
-		struct sfc_evq *mgmt_evq = sa->mgmt_evq;
-
-		if (mgmt_evq->init_state == SFC_EVQ_STARTED)
-			sfc_ev_qpoll(mgmt_evq);
+		if (sa->mgmt_evq_running)
+			sfc_ev_qpoll(sa->mgmt_evq);
 
 		rte_spinlock_unlock(&sa->mgmt_evq_lock);
 	}
@@ -734,20 +732,26 @@ sfc_ev_start(struct sfc_adapter *sa)
 		goto fail_ev_init;
 
 	/* Start management EVQ used for global events */
-	rte_spinlock_lock(&sa->mgmt_evq_lock);
 
+	/*
+	 * Management event queue start polls the queue, but it cannot
+	 * interfere with other polling contexts since mgmt_evq_running
+	 * is false yet.
+	 */
 	rc = sfc_ev_qstart(sa->mgmt_evq, sa->mgmt_evq_index);
 	if (rc != 0)
 		goto fail_mgmt_evq_start;
 
+	rte_spinlock_lock(&sa->mgmt_evq_lock);
+	sa->mgmt_evq_running = true;
+	rte_spinlock_unlock(&sa->mgmt_evq_lock);
+
 	if (sa->intr.lsc_intr) {
 		rc = sfc_ev_qprime(sa->mgmt_evq);
 		if (rc != 0)
 			goto fail_mgmt_evq_prime;
 	}
 
-	rte_spinlock_unlock(&sa->mgmt_evq_lock);
-
 	/*
 	 * Start management EVQ polling. If interrupts are disabled
 	 * (not used), it is required to process link status change
@@ -767,7 +771,6 @@ sfc_ev_start(struct sfc_adapter *sa)
 	sfc_ev_qstop(sa->mgmt_evq);
 
 fail_mgmt_evq_start:
-	rte_spinlock_unlock(&sa->mgmt_evq_lock);
 	efx_ev_fini(sa->nic);
 
 fail_ev_init:
@@ -783,9 +786,11 @@ sfc_ev_stop(struct sfc_adapter *sa)
 	sfc_ev_mgmt_periodic_qpoll_stop(sa);
 
 	rte_spinlock_lock(&sa->mgmt_evq_lock);
-	sfc_ev_qstop(sa->mgmt_evq);
+	sa->mgmt_evq_running = false;
 	rte_spinlock_unlock(&sa->mgmt_evq_lock);
 
+	sfc_ev_qstop(sa->mgmt_evq);
+
 	efx_ev_fini(sa->nic);
 }
 
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index ee59cb1..de65f8c 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -57,8 +57,9 @@ sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa)
 
 	evq = sa->mgmt_evq;
 
-	if (evq->init_state != SFC_EVQ_STARTED) {
-		sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index);
+	if (!sa->mgmt_evq_running) {
+		sfc_log_init(sa, "interrupt on not running management EVQ %u",
+			     evq->evq_index);
 	} else {
 		sfc_ev_qpoll(evq);
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 03/14] net/sfc: handle MC reboot event
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 01/14] net/sfc: fix label name to be consistent Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 02/14] net/sfc: do not hold management event queue lock while MCDI Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 04/14] net/sfc: retry port start to handle MC reboot in the middle Andrew Rybchenko
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

Implement handling of the MC reboot event received on management
event queue or detected by MCDI processing.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 drivers/net/sfc/sfc.c      | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/sfc.h      |  4 +++
 drivers/net/sfc/sfc_mcdi.c |  2 +-
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 49d7e93..0dcfdd8 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 
 #include <rte_errno.h>
+#include <rte_alarm.h>
 
 #include "efx.h"
 
@@ -389,6 +390,58 @@ sfc_stop(struct sfc_adapter *sa)
 	sfc_log_init(sa, "done");
 }
 
+static int
+sfc_restart(struct sfc_adapter *sa)
+{
+	int rc;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	if (sa->state != SFC_ADAPTER_STARTED)
+		return EINVAL;
+
+	sfc_stop(sa);
+
+	rc = sfc_start(sa);
+	if (rc != 0)
+		sfc_err(sa, "restart failed");
+
+	return rc;
+}
+
+static void
+sfc_restart_if_required(void *arg)
+{
+	struct sfc_adapter *sa = arg;
+
+	/* If restart is scheduled, clear the flag and do it */
+	if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required,
+				1, 0)) {
+		sfc_adapter_lock(sa);
+		if (sa->state == SFC_ADAPTER_STARTED)
+			(void)sfc_restart(sa);
+		sfc_adapter_unlock(sa);
+	}
+}
+
+void
+sfc_schedule_restart(struct sfc_adapter *sa)
+{
+	int rc;
+
+	/* Schedule restart alarm if it is not scheduled yet */
+	if (!rte_atomic32_test_and_set(&sa->restart_required))
+		return;
+
+	rc = rte_eal_alarm_set(1, sfc_restart_if_required, sa);
+	if (rc == -ENOTSUP)
+		sfc_warn(sa, "alarms are not supported, restart is pending");
+	else if (rc != 0)
+		sfc_err(sa, "cannot arm restart alarm (rc=%d)", rc);
+	else
+		sfc_info(sa, "restart scheduled");
+}
+
 int
 sfc_configure(struct sfc_adapter *sa)
 {
@@ -679,6 +732,7 @@ sfc_probe(struct sfc_adapter *sa)
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
 	sa->socket_id = rte_socket_id();
+	rte_atomic32_init(&sa->restart_required);
 
 	sfc_log_init(sa, "init mem bar");
 	rc = sfc_mem_bar_init(sa);
@@ -743,6 +797,14 @@ sfc_unprobe(struct sfc_adapter *sa)
 
 	sfc_mcdi_fini(sa);
 
+	/*
+	 * Make sure there is no pending alarm to restart since we are
+	 * going to free device private which is passed as the callback
+	 * opaque data. A new alarm cannot be scheduled since MCDI is
+	 * shut down.
+	 */
+	rte_eal_alarm_cancel(sfc_restart_if_required, sa);
+
 	sfc_log_init(sa, "destroy nic");
 	sa->nic = NULL;
 	efx_nic_destroy(enp);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index ef980a4..77882eb 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -39,6 +39,7 @@
 #include <rte_ethdev.h>
 #include <rte_kvargs.h>
 #include <rte_spinlock.h>
+#include <rte_atomic.h>
 
 #include "efx.h"
 
@@ -197,6 +198,7 @@ struct sfc_adapter {
 	efx_family_t			family;
 	efx_nic_t			*nic;
 	rte_spinlock_t			nic_lock;
+	rte_atomic32_t			restart_required;
 
 	struct sfc_mcdi			mcdi;
 	struct sfc_intr			intr;
@@ -329,6 +331,8 @@ void sfc_detach(struct sfc_adapter *sa);
 int sfc_start(struct sfc_adapter *sa);
 void sfc_stop(struct sfc_adapter *sa);
 
+void sfc_schedule_restart(struct sfc_adapter *sa);
+
 int sfc_mcdi_init(struct sfc_adapter *sa);
 void sfc_mcdi_fini(struct sfc_adapter *sa);
 
diff --git a/drivers/net/sfc/sfc_mcdi.c b/drivers/net/sfc/sfc_mcdi.c
index 0faad3e..f4763ab 100644
--- a/drivers/net/sfc/sfc_mcdi.c
+++ b/drivers/net/sfc/sfc_mcdi.c
@@ -176,7 +176,7 @@ sfc_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
 	    (eme == EFX_MCDI_EXCEPTION_MC_REBOOT) ? "REBOOT" :
 	    (eme == EFX_MCDI_EXCEPTION_MC_BADASSERT) ? "BADASSERT" : "UNKNOWN");
 
-	sfc_panic(sa, "MCDI exceptions handling is not implemented\n");
+	sfc_schedule_restart(sa);
 }
 
 #define SFC_MCDI_LOG_BUF_SIZE	128
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 04/14] net/sfc: retry port start to handle MC reboot in the middle
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (2 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 03/14] net/sfc: handle MC reboot event Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 05/14] net/sfc/base: control RxQ scatter using flag instead of type Andrew Rybchenko
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

MC reboot may be provoked by the other function which is either
starting in parallel or, for example, reconfiguring UDP tunnel
ports.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 drivers/net/sfc/sfc.c | 59 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 43 insertions(+), 16 deletions(-)

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 0dcfdd8..1ca123a 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -271,27 +271,15 @@ sfc_set_drv_limits(struct sfc_adapter *sa)
 	return efx_nic_set_drv_limits(sa->nic, &lim);
 }
 
-int
-sfc_start(struct sfc_adapter *sa)
+static int
+sfc_try_start(struct sfc_adapter *sa)
 {
 	int rc;
 
 	sfc_log_init(sa, "entry");
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
-
-	switch (sa->state) {
-	case SFC_ADAPTER_CONFIGURED:
-		break;
-	case SFC_ADAPTER_STARTED:
-		sfc_info(sa, "already started");
-		return 0;
-	default:
-		rc = EINVAL;
-		goto fail_bad_state;
-	}
-
-	sa->state = SFC_ADAPTER_STARTING;
+	SFC_ASSERT(sa->state == SFC_ADAPTER_STARTING);
 
 	sfc_log_init(sa, "set resource limits");
 	rc = sfc_set_drv_limits(sa);
@@ -327,7 +315,6 @@ sfc_start(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_flows_insert;
 
-	sa->state = SFC_ADAPTER_STARTED;
 	sfc_log_init(sa, "done");
 	return 0;
 
@@ -351,6 +338,46 @@ sfc_start(struct sfc_adapter *sa)
 
 fail_nic_init:
 fail_set_drv_limits:
+	sfc_log_init(sa, "failed %d", rc);
+	return rc;
+}
+
+int
+sfc_start(struct sfc_adapter *sa)
+{
+	unsigned int start_tries = 3;
+	int rc;
+
+	sfc_log_init(sa, "entry");
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	switch (sa->state) {
+	case SFC_ADAPTER_CONFIGURED:
+		break;
+	case SFC_ADAPTER_STARTED:
+		sfc_info(sa, "already started");
+		return 0;
+	default:
+		rc = EINVAL;
+		goto fail_bad_state;
+	}
+
+	sa->state = SFC_ADAPTER_STARTING;
+
+	do {
+		rc = sfc_try_start(sa);
+	} while ((--start_tries > 0) &&
+		 (rc == EIO || rc == EAGAIN || rc == ENOENT || rc == EINVAL));
+
+	if (rc != 0)
+		goto fail_try_start;
+
+	sa->state = SFC_ADAPTER_STARTED;
+	sfc_log_init(sa, "done");
+	return 0;
+
+fail_try_start:
 	sa->state = SFC_ADAPTER_CONFIGURED;
 fail_bad_state:
 	sfc_log_init(sa, "failed %d", rc);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 05/14] net/sfc/base: control RxQ scatter using flag instead of type
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (3 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 04/14] net/sfc: retry port start to handle MC reboot in the middle Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 06/14] net/sfc/base: add function to create packed stream RxQ Andrew Rybchenko
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

Rx scatter may be applicable to different Rx queue types.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Mark Spender <mspender@solarflare.com>
---
 drivers/net/sfc/base/ef10_impl.h |  1 +
 drivers/net/sfc/base/ef10_rx.c   |  4 ++--
 drivers/net/sfc/base/efx.h       |  9 ++++++++-
 drivers/net/sfc/base/efx_impl.h  |  1 +
 drivers/net/sfc/base/efx_rx.c    | 27 ++++++++++++++++++---------
 drivers/net/sfc/sfc_ethdev.c     |  3 ++-
 drivers/net/sfc/sfc_rx.c         |  9 +++++----
 drivers/net/sfc/sfc_rx.h         |  1 +
 8 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index a9b2862..0eeb68f 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -980,6 +980,7 @@ ef10_rx_qcreate(
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
+	__in		unsigned int flags,
 	__in		efx_evq_t *eep,
 	__in		efx_rxq_t *erp);
 
diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 9b0e1ee..9aa8981 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -951,6 +951,7 @@ ef10_rx_qcreate(
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
+	__in		unsigned int flags,
 	__in		efx_evq_t *eep,
 	__in		efx_rxq_t *erp)
 {
@@ -980,7 +981,6 @@ ef10_rx_qcreate(
 
 	switch (type) {
 	case EFX_RXQ_TYPE_DEFAULT:
-	case EFX_RXQ_TYPE_SCATTER:
 		ps_buf_size = 0;
 		break;
 #if EFSYS_OPT_RX_PACKED_STREAM
@@ -1024,7 +1024,7 @@ ef10_rx_qcreate(
 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
 
 	/* Scatter can only be disabled if the firmware supports doing so */
-	if (type == EFX_RXQ_TYPE_SCATTER)
+	if (flags & EFX_RXQ_FLAG_SCATTER)
 		disable_scatter = B_FALSE;
 	else
 		disable_scatter = encp->enc_rx_disable_scatter_supported;
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 93accd7..e0dc76c 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2002,7 +2002,6 @@ efx_pseudo_hdr_pkt_length_get(
 
 typedef enum efx_rxq_type_e {
 	EFX_RXQ_TYPE_DEFAULT,
-	EFX_RXQ_TYPE_SCATTER,
 	EFX_RXQ_TYPE_PACKED_STREAM_1M,
 	EFX_RXQ_TYPE_PACKED_STREAM_512K,
 	EFX_RXQ_TYPE_PACKED_STREAM_256K,
@@ -2011,6 +2010,13 @@ typedef enum efx_rxq_type_e {
 	EFX_RXQ_NTYPES
 } efx_rxq_type_t;
 
+/*
+ * Dummy flag to be used instead of 0 to make it clear that the argument
+ * is receive queue flags.
+ */
+#define	EFX_RXQ_FLAG_NONE		0x0
+#define	EFX_RXQ_FLAG_SCATTER		0x1
+
 extern	__checkReturn	efx_rc_t
 efx_rx_qcreate(
 	__in		efx_nic_t *enp,
@@ -2020,6 +2026,7 @@ efx_rx_qcreate(
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
+	__in		unsigned int flags,
 	__in		efx_evq_t *eep,
 	__deref_out	efx_rxq_t **erpp);
 
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index c29ba0e..8bd667c 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -183,6 +183,7 @@ typedef struct efx_rx_ops_s {
 	efx_rc_t	(*erxo_qcreate)(efx_nic_t *enp, unsigned int,
 					unsigned int, efx_rxq_type_t,
 					efsys_mem_t *, size_t, uint32_t,
+					unsigned int,
 					efx_evq_t *, efx_rxq_t *);
 	void		(*erxo_qdestroy)(efx_rxq_t *);
 } efx_rx_ops_t;
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index f922b59..870d42f 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -134,6 +134,7 @@ siena_rx_qcreate(
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
+	__in		unsigned int flags,
 	__in		efx_evq_t *eep,
 	__in		efx_rxq_t *erp);
 
@@ -619,6 +620,7 @@ efx_rx_qcreate(
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
+	__in		unsigned int flags,
 	__in		efx_evq_t *eep,
 	__deref_out	efx_rxq_t **erpp)
 {
@@ -644,7 +646,7 @@ efx_rx_qcreate(
 	erp->er_esmp = esmp;
 
 	if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, ndescs, id,
-	    eep, erp)) != 0)
+	    flags, eep, erp)) != 0)
 		goto fail2;
 
 	enp->en_rx_qcount++;
@@ -1306,13 +1308,14 @@ siena_rx_qcreate(
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
+	__in		unsigned int flags,
 	__in		efx_evq_t *eep,
 	__in		efx_rxq_t *erp)
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_oword_t oword;
 	uint32_t size;
-	boolean_t jumbo;
+	boolean_t jumbo = B_FALSE;
 	efx_rc_t rc;
 
 	_NOTE(ARGUNUSED(esmp))
@@ -1345,20 +1348,22 @@ siena_rx_qcreate(
 
 	switch (type) {
 	case EFX_RXQ_TYPE_DEFAULT:
-		jumbo = B_FALSE;
 		break;
 
-#if EFSYS_OPT_RX_SCATTER
-	case EFX_RXQ_TYPE_SCATTER:
-		jumbo = B_TRUE;
-		break;
-#endif	/* EFSYS_OPT_RX_SCATTER */
-
 	default:
 		rc = EINVAL;
 		goto fail4;
 	}
 
+	if (flags & EFX_RXQ_FLAG_SCATTER) {
+#if EFSYS_OPT_RX_SCATTER
+		jumbo = B_TRUE;
+#else
+		rc = EINVAL;
+		goto fail5;
+#endif	/* EFSYS_OPT_RX_SCATTER */
+	}
+
 	/* Set up the new descriptor queue */
 	EFX_POPULATE_OWORD_7(oword,
 	    FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
@@ -1374,6 +1379,10 @@ siena_rx_qcreate(
 
 	return (0);
 
+#if !EFSYS_OPT_RX_SCATTER
+fail5:
+	EFSYS_PROBE(fail5);
+#endif
 fail4:
 	EFSYS_PROBE(fail4);
 fail3:
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index fabcc32..0ac9362 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1058,7 +1058,8 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
 	qinfo->conf.rx_free_thresh = rxq->refill_threshold;
 	qinfo->conf.rx_drop_en = 1;
 	qinfo->conf.rx_deferred_start = rxq_info->deferred_start;
-	qinfo->scattered_rx = (rxq_info->type == EFX_RXQ_TYPE_SCATTER);
+	qinfo->scattered_rx =
+		((rxq_info->type_flags & EFX_RXQ_FLAG_SCATTER) != 0);
 	qinfo->nb_desc = rxq_info->entries;
 
 	sfc_adapter_unlock(sa);
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 7816393..22bf372 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -697,8 +697,8 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 
 	rc = efx_rx_qcreate(sa->nic, rxq->hw_index, 0, rxq_info->type,
 			    &rxq->mem, rxq_info->entries,
-			    0 /* not used on EF10 */, evq->common,
-			    &rxq->common);
+			    0 /* not used on EF10 */, rxq_info->type_flags,
+			    evq->common, &rxq->common);
 	if (rc != 0)
 		goto fail_rx_qcreate;
 
@@ -942,9 +942,10 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 
 	SFC_ASSERT(nb_rx_desc <= rxq_info->max_entries);
 	rxq_info->entries = nb_rx_desc;
-	rxq_info->type =
+	rxq_info->type = EFX_RXQ_TYPE_DEFAULT;
+	rxq_info->type_flags =
 		sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
-		EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT;
+		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
 			  rxq_info->entries, socket_id, &evq);
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 9e6282e..ff72718 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -144,6 +144,7 @@ struct sfc_rxq_info {
 	unsigned int		max_entries;
 	unsigned int		entries;
 	efx_rxq_type_t		type;
+	unsigned int		type_flags;
 	struct sfc_rxq		*rxq;
 	boolean_t		deferred_start;
 	boolean_t		deferred_started;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 06/14] net/sfc/base: add function to create packed stream RxQ
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (4 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 05/14] net/sfc/base: control RxQ scatter using flag instead of type Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 07/14] net/sfc/base: allow to request inner classes for Rx packets Andrew Rybchenko
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

Encoding packed stream buffer size in RxQ type is not a future-proof
idea taking into account a new RxQ types with extra parameters.
To be consistent make packet stream buffer size a separate parameter.
In order to avoid blowing of the default RxQ create function prototype
add a dedicated function to create packed stream RxQ without not
applicable paramters.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Mark Spender <mspender@solarflare.com>
---
 drivers/net/sfc/base/ef10_ev.c   |  3 +--
 drivers/net/sfc/base/ef10_impl.h |  1 +
 drivers/net/sfc/base/ef10_rx.c   | 54 ++++++++++++++++++++++++----------------
 drivers/net/sfc/base/efx.h       | 27 ++++++++++++++++----
 drivers/net/sfc/base/efx_impl.h  |  2 +-
 drivers/net/sfc/base/efx_rx.c    | 49 +++++++++++++++++++++++++++++++++---
 6 files changed, 103 insertions(+), 33 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_ev.c b/drivers/net/sfc/base/ef10_ev.c
index ee576a0..80257da 100644
--- a/drivers/net/sfc/base/ef10_ev.c
+++ b/drivers/net/sfc/base/ef10_ev.c
@@ -1347,8 +1347,7 @@ ef10_ev_rxlabel_init(
 {
 	efx_evq_rxq_state_t *eersp;
 #if EFSYS_OPT_RX_PACKED_STREAM
-	boolean_t packed_stream = (type >= EFX_RXQ_TYPE_PACKED_STREAM_1M) &&
-	    (type <= EFX_RXQ_TYPE_PACKED_STREAM_64K);
+	boolean_t packed_stream = (type == EFX_RXQ_TYPE_PACKED_STREAM);
 #endif
 
 	_NOTE(ARGUNUSED(type))
diff --git a/drivers/net/sfc/base/ef10_impl.h b/drivers/net/sfc/base/ef10_impl.h
index 0eeb68f..a17b471 100644
--- a/drivers/net/sfc/base/ef10_impl.h
+++ b/drivers/net/sfc/base/ef10_impl.h
@@ -977,6 +977,7 @@ ef10_rx_qcreate(
 	__in		unsigned int index,
 	__in		unsigned int label,
 	__in		efx_rxq_type_t type,
+	__in		uint32_t type_data,
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 9aa8981..17b1652 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -948,6 +948,7 @@ ef10_rx_qcreate(
 	__in		unsigned int index,
 	__in		unsigned int label,
 	__in		efx_rxq_type_t type,
+	__in		uint32_t type_data,
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
@@ -984,25 +985,32 @@ ef10_rx_qcreate(
 		ps_buf_size = 0;
 		break;
 #if EFSYS_OPT_RX_PACKED_STREAM
-	case EFX_RXQ_TYPE_PACKED_STREAM_1M:
-		ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M;
-		break;
-	case EFX_RXQ_TYPE_PACKED_STREAM_512K:
-		ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K;
-		break;
-	case EFX_RXQ_TYPE_PACKED_STREAM_256K:
-		ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K;
-		break;
-	case EFX_RXQ_TYPE_PACKED_STREAM_128K:
-		ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K;
-		break;
-	case EFX_RXQ_TYPE_PACKED_STREAM_64K:
-		ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K;
+	case EFX_RXQ_TYPE_PACKED_STREAM:
+		switch (type_data) {
+		case EFX_RXQ_PACKED_STREAM_BUF_SIZE_1M:
+			ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M;
+			break;
+		case EFX_RXQ_PACKED_STREAM_BUF_SIZE_512K:
+			ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K;
+			break;
+		case EFX_RXQ_PACKED_STREAM_BUF_SIZE_256K:
+			ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K;
+			break;
+		case EFX_RXQ_PACKED_STREAM_BUF_SIZE_128K:
+			ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K;
+			break;
+		case EFX_RXQ_PACKED_STREAM_BUF_SIZE_64K:
+			ps_buf_size = MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K;
+			break;
+		default:
+			rc = ENOTSUP;
+			goto fail3;
+		}
 		break;
 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
 	default:
 		rc = ENOTSUP;
-		goto fail3;
+		goto fail4;
 	}
 
 #if EFSYS_OPT_RX_PACKED_STREAM
@@ -1010,13 +1018,13 @@ ef10_rx_qcreate(
 		/* Check if datapath firmware supports packed stream mode */
 		if (encp->enc_rx_packed_stream_supported == B_FALSE) {
 			rc = ENOTSUP;
-			goto fail4;
+			goto fail5;
 		}
 		/* Check if packed stream allows configurable buffer sizes */
-		if ((type != EFX_RXQ_TYPE_PACKED_STREAM_1M) &&
+		if ((ps_buf_size != MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M) &&
 		    (encp->enc_rx_var_packed_stream_supported == B_FALSE)) {
 			rc = ENOTSUP;
-			goto fail5;
+			goto fail6;
 		}
 	}
 #else /* EFSYS_OPT_RX_PACKED_STREAM */
@@ -1031,7 +1039,7 @@ ef10_rx_qcreate(
 
 	if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep->ee_index, label, index,
 		    esmp, disable_scatter, ps_buf_size)) != 0)
-		goto fail6;
+		goto fail7;
 
 	erp->er_eep = eep;
 	erp->er_label = label;
@@ -1042,16 +1050,20 @@ ef10_rx_qcreate(
 
 	return (0);
 
+fail7:
+	EFSYS_PROBE(fail7);
+#if EFSYS_OPT_RX_PACKED_STREAM
 fail6:
 	EFSYS_PROBE(fail6);
-#if EFSYS_OPT_RX_PACKED_STREAM
 fail5:
 	EFSYS_PROBE(fail5);
+#endif /* EFSYS_OPT_RX_PACKED_STREAM */
 fail4:
 	EFSYS_PROBE(fail4);
-#endif /* EFSYS_OPT_RX_PACKED_STREAM */
+#if EFSYS_OPT_RX_PACKED_STREAM
 fail3:
 	EFSYS_PROBE(fail3);
+#endif /* EFSYS_OPT_RX_PACKED_STREAM */
 fail2:
 	EFSYS_PROBE(fail2);
 fail1:
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index e0dc76c..d4e0bc5 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2002,11 +2002,7 @@ efx_pseudo_hdr_pkt_length_get(
 
 typedef enum efx_rxq_type_e {
 	EFX_RXQ_TYPE_DEFAULT,
-	EFX_RXQ_TYPE_PACKED_STREAM_1M,
-	EFX_RXQ_TYPE_PACKED_STREAM_512K,
-	EFX_RXQ_TYPE_PACKED_STREAM_256K,
-	EFX_RXQ_TYPE_PACKED_STREAM_128K,
-	EFX_RXQ_TYPE_PACKED_STREAM_64K,
+	EFX_RXQ_TYPE_PACKED_STREAM,
 	EFX_RXQ_NTYPES
 } efx_rxq_type_t;
 
@@ -2030,6 +2026,27 @@ efx_rx_qcreate(
 	__in		efx_evq_t *eep,
 	__deref_out	efx_rxq_t **erpp);
 
+#if EFSYS_OPT_RX_PACKED_STREAM
+
+#define	EFX_RXQ_PACKED_STREAM_BUF_SIZE_1M	(1U * 1024 * 1024)
+#define	EFX_RXQ_PACKED_STREAM_BUF_SIZE_512K	(512U * 1024)
+#define	EFX_RXQ_PACKED_STREAM_BUF_SIZE_256K	(256U * 1024)
+#define	EFX_RXQ_PACKED_STREAM_BUF_SIZE_128K	(128U * 1024)
+#define	EFX_RXQ_PACKED_STREAM_BUF_SIZE_64K	(64U * 1024)
+
+extern	__checkReturn	efx_rc_t
+efx_rx_qcreate_packed_stream(
+	__in		efx_nic_t *enp,
+	__in		unsigned int index,
+	__in		unsigned int label,
+	__in		uint32_t ps_buf_size,
+	__in		efsys_mem_t *esmp,
+	__in		size_t ndescs,
+	__in		efx_evq_t *eep,
+	__deref_out	efx_rxq_t **erpp);
+
+#endif
+
 typedef struct efx_buffer_s {
 	efsys_dma_addr_t	eb_addr;
 	size_t			eb_size;
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 8bd667c..16e5c20 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -181,7 +181,7 @@ typedef struct efx_rx_ops_s {
 	efx_rc_t	(*erxo_qflush)(efx_rxq_t *);
 	void		(*erxo_qenable)(efx_rxq_t *);
 	efx_rc_t	(*erxo_qcreate)(efx_nic_t *enp, unsigned int,
-					unsigned int, efx_rxq_type_t,
+					unsigned int, efx_rxq_type_t, uint32_t,
 					efsys_mem_t *, size_t, uint32_t,
 					unsigned int,
 					efx_evq_t *, efx_rxq_t *);
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index 870d42f..d0dd605 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -131,6 +131,7 @@ siena_rx_qcreate(
 	__in		unsigned int index,
 	__in		unsigned int label,
 	__in		efx_rxq_type_t type,
+	__in		uint32_t type_data,
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
@@ -611,12 +612,13 @@ efx_rx_qenable(
 	erxop->erxo_qenable(erp);
 }
 
-	__checkReturn	efx_rc_t
-efx_rx_qcreate(
+static	__checkReturn	efx_rc_t
+efx_rx_qcreate_internal(
 	__in		efx_nic_t *enp,
 	__in		unsigned int index,
 	__in		unsigned int label,
 	__in		efx_rxq_type_t type,
+	__in		uint32_t type_data,
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
@@ -645,8 +647,8 @@ efx_rx_qcreate(
 	erp->er_mask = ndescs - 1;
 	erp->er_esmp = esmp;
 
-	if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, ndescs, id,
-	    flags, eep, erp)) != 0)
+	if ((rc = erxop->erxo_qcreate(enp, index, label, type, type_data, esmp,
+	    ndescs, id, flags, eep, erp)) != 0)
 		goto fail2;
 
 	enp->en_rx_qcount++;
@@ -664,6 +666,43 @@ efx_rx_qcreate(
 	return (rc);
 }
 
+	__checkReturn	efx_rc_t
+efx_rx_qcreate(
+	__in		efx_nic_t *enp,
+	__in		unsigned int index,
+	__in		unsigned int label,
+	__in		efx_rxq_type_t type,
+	__in		efsys_mem_t *esmp,
+	__in		size_t ndescs,
+	__in		uint32_t id,
+	__in		unsigned int flags,
+	__in		efx_evq_t *eep,
+	__deref_out	efx_rxq_t **erpp)
+{
+	return efx_rx_qcreate_internal(enp, index, label, type, 0, esmp, ndescs,
+	    id, flags, eep, erpp);
+}
+
+#if EFSYS_OPT_RX_PACKED_STREAM
+
+	__checkReturn	efx_rc_t
+efx_rx_qcreate_packed_stream(
+	__in		efx_nic_t *enp,
+	__in		unsigned int index,
+	__in		unsigned int label,
+	__in		uint32_t ps_buf_size,
+	__in		efsys_mem_t *esmp,
+	__in		size_t ndescs,
+	__in		efx_evq_t *eep,
+	__deref_out	efx_rxq_t **erpp)
+{
+	return efx_rx_qcreate_internal(enp, index, label,
+	    EFX_RXQ_TYPE_PACKED_STREAM, ps_buf_size, esmp, ndescs,
+	    0 /* id unused on EF10 */, EFX_RXQ_FLAG_NONE, eep, erpp);
+}
+
+#endif
+
 			void
 efx_rx_qdestroy(
 	__in		efx_rxq_t *erp)
@@ -1305,6 +1344,7 @@ siena_rx_qcreate(
 	__in		unsigned int index,
 	__in		unsigned int label,
 	__in		efx_rxq_type_t type,
+	__in		uint32_t type_data,
 	__in		efsys_mem_t *esmp,
 	__in		size_t ndescs,
 	__in		uint32_t id,
@@ -1319,6 +1359,7 @@ siena_rx_qcreate(
 	efx_rc_t rc;
 
 	_NOTE(ARGUNUSED(esmp))
+	_NOTE(ARGUNUSED(type_data))
 
 	EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
 	    (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 07/14] net/sfc/base: allow to request inner classes for Rx packets
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (5 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 06/14] net/sfc/base: add function to create packed stream RxQ Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 08/14] net/sfc/base: add API to control UDP tunnel ports Andrew Rybchenko
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

If HW/FW supports tunnel encapsulations, Rx event may contain
either inner or outer packet classes. By default outer classes
are requested. Make it possible to request inner classes to
have more information about packet type and allow to interpret
inner frame checksum validation results correctly.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Mark Spender <mspender@solarflare.com>
---
 drivers/net/sfc/base/ef10_rx.c | 13 +++++++++++--
 drivers/net/sfc/base/efx.h     |  9 +++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 17b1652..80f779e 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -44,6 +44,7 @@ efx_mcdi_init_rxq(
 	__in		uint32_t instance,
 	__in		efsys_mem_t *esmp,
 	__in		boolean_t disable_scatter,
+	__in		boolean_t want_inner_classes,
 	__in		uint32_t ps_bufsize)
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
@@ -65,7 +66,8 @@ efx_mcdi_init_rxq(
 	else
 		dma_mode = MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET;
 
-	if (encp->enc_tunnel_encapsulations_supported != 0) {
+	if (encp->enc_tunnel_encapsulations_supported != 0 &&
+	    !want_inner_classes) {
 		/*
 		 * WANT_OUTER_CLASSES can only be specified on hardware which
 		 * supports tunnel encapsulation offloads, even though it is
@@ -959,6 +961,7 @@ ef10_rx_qcreate(
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_rc_t rc;
 	boolean_t disable_scatter;
+	boolean_t want_inner_classes;
 	unsigned int ps_buf_size;
 
 	_NOTE(ARGUNUSED(id, erp))
@@ -1037,8 +1040,14 @@ ef10_rx_qcreate(
 	else
 		disable_scatter = encp->enc_rx_disable_scatter_supported;
 
+	if (flags & EFX_RXQ_FLAG_INNER_CLASSES)
+		want_inner_classes = B_TRUE;
+	else
+		want_inner_classes = B_FALSE;
+
 	if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep->ee_index, label, index,
-		    esmp, disable_scatter, ps_buf_size)) != 0)
+		    esmp, disable_scatter, want_inner_classes,
+		    ps_buf_size)) != 0)
 		goto fail7;
 
 	erp->er_eep = eep;
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index d4e0bc5..ec65dcf 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -2012,6 +2012,15 @@ typedef enum efx_rxq_type_e {
  */
 #define	EFX_RXQ_FLAG_NONE		0x0
 #define	EFX_RXQ_FLAG_SCATTER		0x1
+/*
+ * If tunnels are supported and Rx event can provide information about
+ * either outer or inner packet classes (e.g. SFN8xxx adapters with
+ * full-feature firmware variant running), outer classes are requested by
+ * default. However, if the driver supports tunnels, the flag allows to
+ * request inner classes which are required to be able to interpret inner
+ * Rx checksum offload results.
+ */
+#define	EFX_RXQ_FLAG_INNER_CLASSES	0x2
 
 extern	__checkReturn	efx_rc_t
 efx_rx_qcreate(
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 08/14] net/sfc/base: add API to control UDP tunnel ports
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (6 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 07/14] net/sfc/base: allow to request inner classes for Rx packets Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 09/14] net/sfc: support UDP tunnel ports configuration Andrew Rybchenko
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev; +Cc: Ivan Malov

From: Ivan Malov <ivan.malov@oktetlabs.ru>

HW needs to know which UDP packets should be treated as tunnel
encapsulation to do inner packet recognition, classification and
offloads.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/Makefile          |   1 +
 drivers/net/sfc/base/ef10_nic.c   |  10 +-
 drivers/net/sfc/base/efx.h        |  51 ++++
 drivers/net/sfc/base/efx_check.h  |   7 +
 drivers/net/sfc/base/efx_impl.h   |  27 +++
 drivers/net/sfc/base/efx_mcdi.h   |   4 +
 drivers/net/sfc/base/efx_tunnel.c | 487 ++++++++++++++++++++++++++++++++++++++
 drivers/net/sfc/efsys.h           |   2 +
 8 files changed, 588 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/sfc/base/efx_tunnel.c

diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index 2cfd62a..9541815 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -122,6 +122,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_phy.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_port.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_rx.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_sram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_tunnel.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_tx.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_vpd.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += mcdi_mon.c
diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index cf56236..edda4ec 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -1076,12 +1076,20 @@ ef10_get_datapath_caps(
 	 * Check if firmware supports VXLAN and NVGRE tunnels.
 	 * The capability indicates Geneve protocol support as well.
 	 */
-	if (CAP_FLAG(flags, VXLAN_NVGRE))
+	if (CAP_FLAG(flags, VXLAN_NVGRE)) {
 		encp->enc_tunnel_encapsulations_supported =
 		    (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
 		    (1u << EFX_TUNNEL_PROTOCOL_GENEVE) |
 		    (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
 
+		EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES ==
+		    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM);
+		encp->enc_tunnel_config_udp_entries_max =
+		    EFX_TUNNEL_MAXNENTRIES;
+	} else {
+		encp->enc_tunnel_config_udp_entries_max = 0;
+	}
+
 #undef CAP_FLAG
 #undef CAP_FLAG2
 
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index ec65dcf..8c59a99 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1205,6 +1205,11 @@ typedef struct efx_nic_cfg_s {
 	boolean_t		enc_pm_and_rxdp_counters;
 	boolean_t		enc_mac_stats_40g_tx_size_bins;
 	uint32_t		enc_tunnel_encapsulations_supported;
+	/*
+	 * NIC global maximum for unique UDP tunnel ports shared by all
+	 * functions.
+	 */
+	uint32_t		enc_tunnel_config_udp_entries_max;
 	/* External port identifier */
 	uint8_t			enc_external_port;
 	uint32_t		enc_mcdi_max_payload_length;
@@ -2631,6 +2636,52 @@ efx_lic_finish_partition(
 
 #endif	/* EFSYS_OPT_LICENSING */
 
+/* TUNNEL */
+
+#if EFSYS_OPT_TUNNEL
+
+extern	__checkReturn	efx_rc_t
+efx_tunnel_init(
+	__in		efx_nic_t *enp);
+
+extern			void
+efx_tunnel_fini(
+	__in		efx_nic_t *enp);
+
+/*
+ * For overlay network encapsulation using UDP, the firmware needs to know
+ * the configured UDP port for the overlay so it can decode encapsulated
+ * frames correctly.
+ * The UDP port/protocol list is global.
+ */
+
+extern	__checkReturn	efx_rc_t
+efx_tunnel_config_udp_add(
+	__in		efx_nic_t *enp,
+	__in		uint16_t port /* host/cpu-endian */,
+	__in		efx_tunnel_protocol_t protocol);
+
+extern	__checkReturn	efx_rc_t
+efx_tunnel_config_udp_remove(
+	__in		efx_nic_t *enp,
+	__in		uint16_t port /* host/cpu-endian */,
+	__in		efx_tunnel_protocol_t protocol);
+
+extern			void
+efx_tunnel_config_clear(
+	__in		efx_nic_t *enp);
+
+/**
+ * Apply tunnel UDP ports configuration to hardware.
+ *
+ * EAGAIN is returned if hardware will be reset (datapath and managment CPU
+ * reboot).
+ */
+extern	__checkReturn	efx_rc_t
+efx_tunnel_reconfigure(
+	__in		efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_TUNNEL */
 
 
 #ifdef	__cplusplus
diff --git a/drivers/net/sfc/base/efx_check.h b/drivers/net/sfc/base/efx_check.h
index 33c16a6..ef5936b 100644
--- a/drivers/net/sfc/base/efx_check.h
+++ b/drivers/net/sfc/base/efx_check.h
@@ -343,4 +343,11 @@
 # endif
 #endif
 
+/* Support hardware assistance for tunnels */
+#if EFSYS_OPT_TUNNEL
+# if !EFSYS_OPT_MEDFORD
+#  error "TUNNEL requires MEDFORD"
+# endif
+#endif /* EFSYS_OPT_TUNNEL */
+
 #endif /* _SYS_EFX_CHECK_H */
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 16e5c20..7c971b3 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -74,6 +74,7 @@ extern "C" {
 #define	EFX_MOD_MON		0x00000400
 #define	EFX_MOD_FILTER		0x00001000
 #define	EFX_MOD_LIC		0x00002000
+#define	EFX_MOD_TUNNEL		0x00004000
 
 #define	EFX_RESET_PHY		0x00000001
 #define	EFX_RESET_RXQ_ERR	0x00000002
@@ -262,6 +263,12 @@ efx_filter_reconfigure(
 
 #endif /* EFSYS_OPT_FILTER */
 
+#if EFSYS_OPT_TUNNEL
+typedef struct efx_tunnel_ops_s {
+	boolean_t	(*eto_udp_encap_supported)(efx_nic_t *);
+	efx_rc_t	(*eto_reconfigure)(efx_nic_t *);
+} efx_tunnel_ops_t;
+#endif /* EFSYS_OPT_TUNNEL */
 
 typedef struct efx_port_s {
 	efx_mac_type_t		ep_mac_type;
@@ -433,6 +440,22 @@ siena_filter_tbl_clear(
 
 #if EFSYS_OPT_MCDI
 
+#define	EFX_TUNNEL_MAXNENTRIES	(16)
+
+#if EFSYS_OPT_TUNNEL
+
+typedef struct efx_tunnel_udp_entry_s {
+	uint16_t			etue_port; /* host/cpu-endian */
+	uint16_t			etue_protocol;
+} efx_tunnel_udp_entry_t;
+
+typedef struct efx_tunnel_cfg_s {
+	efx_tunnel_udp_entry_t	etc_udp_entries[EFX_TUNNEL_MAXNENTRIES];
+	unsigned int		etc_udp_entries_num;
+} efx_tunnel_cfg_t;
+
+#endif /* EFSYS_OPT_TUNNEL */
+
 typedef struct efx_mcdi_ops_s {
 	efx_rc_t	(*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
 	void		(*emco_send_request)(efx_nic_t *, void *, size_t,
@@ -645,6 +668,10 @@ struct efx_nic_s {
 	efx_filter_t		en_filter;
 	const efx_filter_ops_t	*en_efop;
 #endif	/* EFSYS_OPT_FILTER */
+#if EFSYS_OPT_TUNNEL
+	efx_tunnel_cfg_t	en_tunnel_cfg;
+	const efx_tunnel_ops_t	*en_etop;
+#endif /* EFSYS_OPT_TUNNEL */
 #if EFSYS_OPT_MCDI
 	efx_mcdi_t		en_mcdi;
 #endif	/* EFSYS_OPT_MCDI */
diff --git a/drivers/net/sfc/base/efx_mcdi.h b/drivers/net/sfc/base/efx_mcdi.h
index fba807a..a95cdc0 100644
--- a/drivers/net/sfc/base/efx_mcdi.h
+++ b/drivers/net/sfc/base/efx_mcdi.h
@@ -382,6 +382,10 @@ efx_mcdi_phy_module_get_info(
 	EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst),		\
 		    EFX_WORD_0)
 
+#define	MCDI_OUT_WORD_FIELD(_emr, _ofst, _field)			\
+	EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst),		\
+		       MC_CMD_ ## _field)
+
 #define	MCDI_OUT_DWORD(_emr, _ofst)					\
 	EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst),		\
 			EFX_DWORD_0)
diff --git a/drivers/net/sfc/base/efx_tunnel.c b/drivers/net/sfc/base/efx_tunnel.c
new file mode 100644
index 0000000..8a8ac32
--- /dev/null
+++ b/drivers/net/sfc/base/efx_tunnel.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2017 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_TUNNEL
+
+#if EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON
+static const efx_tunnel_ops_t	__efx_tunnel_dummy_ops = {
+	NULL,	/* eto_udp_encap_supported */
+	NULL,	/* eto_reconfigure */
+};
+#endif /* EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON */
+
+#if EFSYS_OPT_MEDFORD
+static	__checkReturn	boolean_t
+medford_udp_encap_supported(
+	__in		efx_nic_t *enp);
+
+static	__checkReturn	efx_rc_t
+medford_tunnel_reconfigure(
+	__in		efx_nic_t *enp);
+
+static const efx_tunnel_ops_t	__efx_tunnel_medford_ops = {
+	medford_udp_encap_supported,	/* eto_udp_encap_supported */
+	medford_tunnel_reconfigure,	/* eto_reconfigure */
+};
+#endif /* EFSYS_OPT_MEDFORD */
+
+static	__checkReturn		efx_rc_t
+efx_mcdi_set_tunnel_encap_udp_ports(
+	__in			efx_nic_t *enp,
+	__in			efx_tunnel_cfg_t *etcp,
+	__in			boolean_t unloading,
+	__out			boolean_t *resetting)
+{
+	efx_mcdi_req_t req;
+	uint8_t payload[MAX(MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LENMAX,
+			    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN)];
+	efx_word_t flags;
+	efx_rc_t rc;
+	unsigned int i;
+	unsigned int entries_num;
+
+	if (etcp == NULL)
+		entries_num = 0;
+	else
+		entries_num = etcp->etc_udp_entries_num;
+
+	(void) memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS;
+	req.emr_in_buf = payload;
+	req.emr_in_length =
+	    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_LEN(entries_num);
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN;
+
+	EFX_POPULATE_WORD_1(flags,
+	    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_UNLOADING,
+	    (unloading == B_TRUE) ? 1 : 0);
+	MCDI_IN_SET_WORD(req, SET_TUNNEL_ENCAP_UDP_PORTS_IN_FLAGS,
+	    EFX_WORD_FIELD(flags, EFX_WORD_0));
+
+	MCDI_IN_SET_WORD(req, SET_TUNNEL_ENCAP_UDP_PORTS_IN_NUM_ENTRIES,
+	    entries_num);
+
+	for (i = 0; i < entries_num; ++i) {
+		uint16_t mcdi_udp_protocol;
+
+		switch (etcp->etc_udp_entries[i].etue_protocol) {
+		case EFX_TUNNEL_PROTOCOL_VXLAN:
+			mcdi_udp_protocol = TUNNEL_ENCAP_UDP_PORT_ENTRY_VXLAN;
+			break;
+		case EFX_TUNNEL_PROTOCOL_GENEVE:
+			mcdi_udp_protocol = TUNNEL_ENCAP_UDP_PORT_ENTRY_GENEVE;
+			break;
+		default:
+			rc = EINVAL;
+			goto fail1;
+		}
+
+		/*
+		 * UDP port is MCDI native little-endian in the request
+		 * and EFX_POPULATE_DWORD cares about conversion from
+		 * host/CPU byte order to little-endian.
+		 */
+		EFX_STATIC_ASSERT(sizeof (efx_dword_t) ==
+		    TUNNEL_ENCAP_UDP_PORT_ENTRY_LEN);
+		EFX_POPULATE_DWORD_2(
+		    MCDI_IN2(req, efx_dword_t,
+			SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES)[i],
+		    TUNNEL_ENCAP_UDP_PORT_ENTRY_UDP_PORT,
+		    etcp->etc_udp_entries[i].etue_port,
+		    TUNNEL_ENCAP_UDP_PORT_ENTRY_PROTOCOL,
+		    mcdi_udp_protocol);
+	}
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail2;
+	}
+
+	if (req.emr_out_length_used !=
+	    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_OUT_LEN) {
+		rc = EMSGSIZE;
+		goto fail3;
+	}
+
+	*resetting = MCDI_OUT_WORD_FIELD(req,
+	    SET_TUNNEL_ENCAP_UDP_PORTS_OUT_FLAGS,
+	    SET_TUNNEL_ENCAP_UDP_PORTS_OUT_RESETTING);
+
+	return (0);
+
+fail3:
+	EFSYS_PROBE(fail3);
+
+fail2:
+	EFSYS_PROBE(fail2);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_tunnel_init(
+	__in		efx_nic_t *enp)
+{
+	efx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;
+	const efx_tunnel_ops_t *etop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TUNNEL));
+
+	EFX_STATIC_ASSERT(EFX_TUNNEL_MAXNENTRIES ==
+	    MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS_IN_ENTRIES_MAXNUM);
+
+	switch (enp->en_family) {
+#if EFSYS_OPT_SIENA
+	case EFX_FAMILY_SIENA:
+		etop = &__efx_tunnel_dummy_ops;
+		break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+	case EFX_FAMILY_HUNTINGTON:
+		etop = &__efx_tunnel_dummy_ops;
+		break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#if EFSYS_OPT_MEDFORD
+	case EFX_FAMILY_MEDFORD:
+		etop = &__efx_tunnel_medford_ops;
+		break;
+#endif /* EFSYS_OPT_MEDFORD */
+
+	default:
+		EFSYS_ASSERT(0);
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	memset(etcp->etc_udp_entries, 0, sizeof (etcp->etc_udp_entries));
+	etcp->etc_udp_entries_num = 0;
+
+	enp->en_etop = etop;
+	enp->en_mod_flags |= EFX_MOD_TUNNEL;
+
+	return (0);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	enp->en_etop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_TUNNEL;
+
+	return (rc);
+}
+
+			void
+efx_tunnel_fini(
+	__in		efx_nic_t *enp)
+{
+	boolean_t resetting;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);
+
+	if ((enp->en_etop->eto_udp_encap_supported != NULL) &&
+	    enp->en_etop->eto_udp_encap_supported(enp)) {
+		/*
+		 * The UNLOADING flag allows the MC to suppress the datapath
+		 * reset if it was set on the last call to
+		 * MC_CMD_SET_TUNNEL_ENCAP_UDP_PORTS by all functions
+		 */
+		(void) efx_mcdi_set_tunnel_encap_udp_ports(enp, NULL, B_TRUE,
+		    &resetting);
+	}
+
+	enp->en_etop = NULL;
+	enp->en_mod_flags &= ~EFX_MOD_TUNNEL;
+}
+
+static	__checkReturn	efx_rc_t
+efx_tunnel_config_find_udp_tunnel_entry(
+	__in		efx_tunnel_cfg_t *etcp,
+	__in		uint16_t port,
+	__out		unsigned int *entryp)
+{
+	unsigned int i;
+
+	for (i = 0; i < etcp->etc_udp_entries_num; ++i) {
+		efx_tunnel_udp_entry_t *p = &etcp->etc_udp_entries[i];
+
+		if (p->etue_port == port) {
+			*entryp = i;
+			return (0);
+		}
+	}
+
+	return (ENOENT);
+}
+
+	__checkReturn	efx_rc_t
+efx_tunnel_config_udp_add(
+	__in		efx_nic_t *enp,
+	__in		uint16_t port /* host/cpu-endian */,
+	__in		efx_tunnel_protocol_t protocol)
+{
+	const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+	efx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;
+	efsys_lock_state_t state;
+	efx_rc_t rc;
+	unsigned int entry;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);
+
+	if (protocol >= EFX_TUNNEL_NPROTOS) {
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if ((encp->enc_tunnel_encapsulations_supported &
+	    (1u << protocol)) == 0) {
+		rc = ENOTSUP;
+		goto fail2;
+	}
+
+	EFSYS_LOCK(enp->en_eslp, state);
+
+	rc = efx_tunnel_config_find_udp_tunnel_entry(etcp, port, &entry);
+	if (rc == 0) {
+		rc = EEXIST;
+		goto fail3;
+	}
+
+	if (etcp->etc_udp_entries_num ==
+	    encp->enc_tunnel_config_udp_entries_max) {
+		rc = ENOSPC;
+		goto fail4;
+	}
+
+	etcp->etc_udp_entries[etcp->etc_udp_entries_num].etue_port = port;
+	etcp->etc_udp_entries[etcp->etc_udp_entries_num].etue_protocol =
+	    protocol;
+
+	etcp->etc_udp_entries_num++;
+
+	EFSYS_UNLOCK(enp->en_eslp, state);
+
+	return (0);
+
+fail4:
+	EFSYS_PROBE(fail4);
+
+fail3:
+	EFSYS_PROBE(fail3);
+	EFSYS_UNLOCK(enp->en_eslp, state);
+
+fail2:
+	EFSYS_PROBE(fail2);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_tunnel_config_udp_remove(
+	__in		efx_nic_t *enp,
+	__in		uint16_t port /* host/cpu-endian */,
+	__in		efx_tunnel_protocol_t protocol)
+{
+	efx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;
+	efsys_lock_state_t state;
+	unsigned int entry;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);
+
+	EFSYS_LOCK(enp->en_eslp, state);
+
+	rc = efx_tunnel_config_find_udp_tunnel_entry(etcp, port, &entry);
+	if (rc != 0)
+		goto fail1;
+
+	if (etcp->etc_udp_entries[entry].etue_protocol != protocol) {
+		rc = EINVAL;
+		goto fail2;
+	}
+
+	EFSYS_ASSERT3U(etcp->etc_udp_entries_num, >, 0);
+	etcp->etc_udp_entries_num--;
+
+	if (entry < etcp->etc_udp_entries_num) {
+		memmove(&etcp->etc_udp_entries[entry],
+		    &etcp->etc_udp_entries[entry + 1],
+		    (etcp->etc_udp_entries_num - entry) *
+		    sizeof (etcp->etc_udp_entries[0]));
+	}
+
+	memset(&etcp->etc_udp_entries[etcp->etc_udp_entries_num], 0,
+	    sizeof (etcp->etc_udp_entries[0]));
+
+	EFSYS_UNLOCK(enp->en_eslp, state);
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	EFSYS_UNLOCK(enp->en_eslp, state);
+
+	return (rc);
+}
+
+			void
+efx_tunnel_config_clear(
+	__in			efx_nic_t *enp)
+{
+	efx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;
+	efsys_lock_state_t state;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);
+
+	EFSYS_LOCK(enp->en_eslp, state);
+
+	etcp->etc_udp_entries_num = 0;
+	memset(etcp->etc_udp_entries, 0, sizeof (etcp->etc_udp_entries));
+
+	EFSYS_UNLOCK(enp->en_eslp, state);
+}
+
+	__checkReturn	efx_rc_t
+efx_tunnel_reconfigure(
+	__in		efx_nic_t *enp)
+{
+	const efx_tunnel_ops_t *etop = enp->en_etop;
+	efx_rc_t rc;
+
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TUNNEL);
+
+	if (etop->eto_reconfigure == NULL) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if ((rc = enp->en_etop->eto_reconfigure(enp)) != 0)
+		goto fail2;
+
+	return (0);
+
+fail2:
+	EFSYS_PROBE(fail2);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+#if EFSYS_OPT_MEDFORD
+static	__checkReturn		boolean_t
+medford_udp_encap_supported(
+	__in		efx_nic_t *enp)
+{
+	const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+	uint32_t udp_tunnels_mask = 0;
+
+	udp_tunnels_mask |= (1u << EFX_TUNNEL_PROTOCOL_VXLAN);
+	udp_tunnels_mask |= (1u << EFX_TUNNEL_PROTOCOL_GENEVE);
+
+	return ((encp->enc_tunnel_encapsulations_supported &
+	    udp_tunnels_mask) == 0 ? B_FALSE : B_TRUE);
+}
+
+static	__checkReturn	efx_rc_t
+medford_tunnel_reconfigure(
+	__in		efx_nic_t *enp)
+{
+	efx_tunnel_cfg_t *etcp = &enp->en_tunnel_cfg;
+	efx_rc_t rc;
+	boolean_t resetting;
+	efsys_lock_state_t state;
+	efx_tunnel_cfg_t etc;
+
+	EFSYS_LOCK(enp->en_eslp, state);
+	memcpy(&etc, etcp, sizeof (etc));
+	EFSYS_UNLOCK(enp->en_eslp, state);
+
+	if (medford_udp_encap_supported(enp) == B_FALSE) {
+		/*
+		 * It is OK to apply empty UDP tunnel ports when UDP
+		 * tunnel encapsulations are not supported - just nothing
+		 * should be done.
+		 */
+		if (etc.etc_udp_entries_num == 0)
+			return (0);
+		rc = ENOTSUP;
+		goto fail1;
+	} else {
+		/*
+		 * All PCI functions can see a reset upon the
+		 * MCDI request completion
+		 */
+		rc = efx_mcdi_set_tunnel_encap_udp_ports(enp, &etc, B_FALSE,
+		    &resetting);
+		if (rc != 0)
+			goto fail2;
+
+		/*
+		 * Although the caller should be able to handle MC reboot,
+		 * it might come in handy to report the impending reboot
+		 * by returning EAGAIN
+		 */
+		return ((resetting) ? EAGAIN : 0);
+	}
+fail2:
+	EFSYS_PROBE(fail2);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+#endif /* EFSYS_OPT_MEDFORD */
+
+#endif /* EFSYS_OPT_TUNNEL */
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index f428b62..ba2ee9a 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -214,6 +214,8 @@ prefetch_read_once(const volatile void *addr)
 
 #define EFSYS_OPT_RX_PACKED_STREAM 0
 
+#define EFSYS_OPT_TUNNEL 0
+
 /* ID */
 
 typedef struct __efsys_identifier_s efsys_identifier_t;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 09/14] net/sfc: support UDP tunnel ports configuration
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (7 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 08/14] net/sfc/base: add API to control UDP tunnel ports Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 10/14] net/sfc: fix incorrect bitwise ORing of L3/L4 packet types Andrew Rybchenko
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 doc/guides/nics/sfc_efx.rst  |   9 ++++
 drivers/net/sfc/efsys.h      |   2 +-
 drivers/net/sfc/sfc.c        |  24 +++++++++
 drivers/net/sfc/sfc_ethdev.c | 119 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 153 insertions(+), 1 deletion(-)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index ae2b54a..bde3cc8 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -116,6 +116,15 @@ required in the receive buffer.
 It should be taken into account when mbuf pool for receive is created.
 
 
+Tunnels support
+---------------
+
+NVGRE, VXLAN and GENEVE tunnels are supported on SFN8xxx family adapters
+with full-feature firmware variant running.
+**sfboot** should be used to configure NIC to run full-feature firmware variant.
+See Solarflare Server Adapter User's Guide for details.
+
+
 Flow API support
 ----------------
 
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index ba2ee9a..37e3c02 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -214,7 +214,7 @@ prefetch_read_once(const volatile void *addr)
 
 #define EFSYS_OPT_RX_PACKED_STREAM 0
 
-#define EFSYS_OPT_TUNNEL 0
+#define EFSYS_OPT_TUNNEL 1
 
 /* ID */
 
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 1ca123a..59e535d 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -274,6 +274,7 @@ sfc_set_drv_limits(struct sfc_adapter *sa)
 static int
 sfc_try_start(struct sfc_adapter *sa)
 {
+	const efx_nic_cfg_t *encp;
 	int rc;
 
 	sfc_log_init(sa, "entry");
@@ -291,6 +292,14 @@ sfc_try_start(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_nic_init;
 
+	encp = efx_nic_cfg_get(sa->nic);
+	if (encp->enc_tunnel_encapsulations_supported != 0) {
+		sfc_log_init(sa, "apply tunnel config");
+		rc = efx_tunnel_reconfigure(sa->nic);
+		if (rc != 0)
+			goto fail_tunnel_reconfigure;
+	}
+
 	rc = sfc_intr_start(sa);
 	if (rc != 0)
 		goto fail_intr_start;
@@ -334,6 +343,7 @@ sfc_try_start(struct sfc_adapter *sa)
 	sfc_intr_stop(sa);
 
 fail_intr_start:
+fail_tunnel_reconfigure:
 	efx_nic_fini(sa->nic);
 
 fail_nic_init:
@@ -663,6 +673,16 @@ sfc_attach(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_nic_reset;
 
+	/*
+	 * Probed NIC is sufficient for tunnel init.
+	 * Initialize tunnel support to be able to use libefx
+	 * efx_tunnel_config_udp_{add,remove}() in any state and
+	 * efx_tunnel_reconfigure() on start up.
+	 */
+	rc = efx_tunnel_init(enp);
+	if (rc != 0)
+		goto fail_tunnel_init;
+
 	encp = efx_nic_cfg_get(sa->nic);
 
 	if (sa->dp_tx->features & SFC_DP_TX_FEAT_TSO) {
@@ -724,6 +744,9 @@ sfc_attach(struct sfc_adapter *sa)
 	efx_nic_fini(sa->nic);
 
 fail_estimate_rsrc_limits:
+fail_tunnel_init:
+	efx_tunnel_fini(sa->nic);
+
 fail_nic_reset:
 
 	sfc_log_init(sa, "failed %d", rc);
@@ -743,6 +766,7 @@ sfc_detach(struct sfc_adapter *sa)
 	sfc_port_detach(sa);
 	sfc_ev_detach(sa);
 	sfc_intr_detach(sa);
+	efx_tunnel_fini(sa->nic);
 
 	sa->state = SFC_ADAPTER_UNINITIALIZED;
 }
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 0ac9362..837fd55 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1225,6 +1225,123 @@ sfc_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+static efx_tunnel_protocol_t
+sfc_tunnel_rte_type_to_efx_udp_proto(enum rte_eth_tunnel_type rte_type)
+{
+	switch (rte_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		return EFX_TUNNEL_PROTOCOL_VXLAN;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		return EFX_TUNNEL_PROTOCOL_GENEVE;
+	default:
+		return EFX_TUNNEL_NPROTOS;
+	}
+}
+
+enum sfc_udp_tunnel_op_e {
+	SFC_UDP_TUNNEL_ADD_PORT,
+	SFC_UDP_TUNNEL_DEL_PORT,
+};
+
+static int
+sfc_dev_udp_tunnel_op(struct rte_eth_dev *dev,
+		      struct rte_eth_udp_tunnel *tunnel_udp,
+		      enum sfc_udp_tunnel_op_e op)
+{
+	struct sfc_adapter *sa = dev->data->dev_private;
+	efx_tunnel_protocol_t tunnel_proto;
+	int rc;
+
+	sfc_log_init(sa, "%s udp_port=%u prot_type=%u",
+		     (op == SFC_UDP_TUNNEL_ADD_PORT) ? "add" :
+		     (op == SFC_UDP_TUNNEL_DEL_PORT) ? "delete" : "unknown",
+		     tunnel_udp->udp_port, tunnel_udp->prot_type);
+
+	tunnel_proto =
+		sfc_tunnel_rte_type_to_efx_udp_proto(tunnel_udp->prot_type);
+	if (tunnel_proto >= EFX_TUNNEL_NPROTOS) {
+		rc = ENOTSUP;
+		goto fail_bad_proto;
+	}
+
+	sfc_adapter_lock(sa);
+
+	switch (op) {
+	case SFC_UDP_TUNNEL_ADD_PORT:
+		rc = efx_tunnel_config_udp_add(sa->nic,
+					       tunnel_udp->udp_port,
+					       tunnel_proto);
+		break;
+	case SFC_UDP_TUNNEL_DEL_PORT:
+		rc = efx_tunnel_config_udp_remove(sa->nic,
+						  tunnel_udp->udp_port,
+						  tunnel_proto);
+		break;
+	default:
+		rc = EINVAL;
+		goto fail_bad_op;
+	}
+
+	if (rc != 0)
+		goto fail_op;
+
+	if (sa->state == SFC_ADAPTER_STARTED) {
+		rc = efx_tunnel_reconfigure(sa->nic);
+		if (rc == EAGAIN) {
+			/*
+			 * Configuration is accepted by FW and MC reboot
+			 * is initiated to apply the changes. MC reboot
+			 * will be handled in a usual way (MC reboot
+			 * event on management event queue and adapter
+			 * restart).
+			 */
+			rc = 0;
+		} else if (rc != 0) {
+			goto fail_reconfigure;
+		}
+	}
+
+	sfc_adapter_unlock(sa);
+	return 0;
+
+fail_reconfigure:
+	/* Remove/restore entry since the change makes the trouble */
+	switch (op) {
+	case SFC_UDP_TUNNEL_ADD_PORT:
+		(void)efx_tunnel_config_udp_remove(sa->nic,
+						   tunnel_udp->udp_port,
+						   tunnel_proto);
+		break;
+	case SFC_UDP_TUNNEL_DEL_PORT:
+		(void)efx_tunnel_config_udp_add(sa->nic,
+						tunnel_udp->udp_port,
+						tunnel_proto);
+		break;
+	}
+
+fail_op:
+fail_bad_op:
+	sfc_adapter_unlock(sa);
+
+fail_bad_proto:
+	SFC_ASSERT(rc > 0);
+	return -rc;
+}
+
+static int
+sfc_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
+			    struct rte_eth_udp_tunnel *tunnel_udp)
+{
+	return sfc_dev_udp_tunnel_op(dev, tunnel_udp, SFC_UDP_TUNNEL_ADD_PORT);
+}
+
+static int
+sfc_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
+			    struct rte_eth_udp_tunnel *tunnel_udp)
+{
+	return sfc_dev_udp_tunnel_op(dev, tunnel_udp, SFC_UDP_TUNNEL_DEL_PORT);
+}
+
 #if EFSYS_OPT_RX_SCALE
 static int
 sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
@@ -1529,6 +1646,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
 	.flow_ctrl_get			= sfc_flow_ctrl_get,
 	.flow_ctrl_set			= sfc_flow_ctrl_set,
 	.mac_addr_set			= sfc_mac_addr_set,
+	.udp_tunnel_port_add		= sfc_dev_udp_tunnel_port_add,
+	.udp_tunnel_port_del		= sfc_dev_udp_tunnel_port_del,
 #if EFSYS_OPT_RX_SCALE
 	.reta_update			= sfc_dev_rss_reta_update,
 	.reta_query			= sfc_dev_rss_reta_query,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 10/14] net/sfc: fix incorrect bitwise ORing of L3/L4 packet types
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (8 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 09/14] net/sfc: support UDP tunnel ports configuration Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 11/14] net/sfc: support VXLAN and NVGRE packet types classification Andrew Rybchenko
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev; +Cc: stable

Not a bug since value is set only once, but it is still incorrect.

Fixes: 638bddc99faa ("net/sfc: implement EF10 native Rx datapath")
Cc: stable@dpdk.org

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/sfc_ef10_rx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 18d60c6..4c76f74 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -286,10 +286,10 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 			 PKT_RX_IP_CKSUM_BAD : PKT_RX_IP_CKSUM_GOOD);
 		break;
 	case ESE_DZ_L3_CLASS_IP6_FRAG:
-		l4_ptype |= RTE_PTYPE_L4_FRAG;
+		l4_ptype = RTE_PTYPE_L4_FRAG;
 		/* FALLTHROUGH */
 	case ESE_DZ_L3_CLASS_IP6:
-		l3_ptype |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		l3_ptype = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
 		ol_flags |= PKT_RX_RSS_HASH;
 		break;
 	case ESE_DZ_L3_CLASS_ARP:
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 11/14] net/sfc: support VXLAN and NVGRE packet types classification
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (9 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 10/14] net/sfc: fix incorrect bitwise ORing of L3/L4 packet types Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 12/14] net/sfc: correct Rx checksum offloads for tunnel packets Andrew Rybchenko
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 doc/guides/nics/sfc_efx.rst   |  11 +++++
 drivers/net/sfc/sfc_dp_rx.h   |   4 +-
 drivers/net/sfc/sfc_ef10_rx.c | 102 ++++++++++++++++++++++++++++++++++++------
 drivers/net/sfc/sfc_ethdev.c  |   8 +++-
 drivers/net/sfc/sfc_rx.c      |   6 ++-
 5 files changed, 114 insertions(+), 17 deletions(-)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index bde3cc8..994e111 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -124,6 +124,17 @@ with full-feature firmware variant running.
 **sfboot** should be used to configure NIC to run full-feature firmware variant.
 See Solarflare Server Adapter User's Guide for details.
 
+SFN8xxx family adapters provide either inner or outer packet classes.
+If adapter firmware advertises support for tunnels then the PMD
+configures the hardware to report inner classes, and outer classes are
+not reported in received packets.
+However, for VXLAN and GENEVE tunnels the PMD does report UDP as the
+outer layer 4 packet type.
+
+SFN8xxx family adapters report GENEVE packets as VXLAN.
+If UDP ports are configured for only one tunnel type then it is safe to
+treat VXLAN packet type indication as the corresponding UDP tunnel type.
+
 
 Flow API support
 ----------------
diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3f6a604..33e06ac 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -150,7 +150,8 @@ typedef bool (sfc_dp_rx_qrx_ev_t)(struct sfc_dp_rxq *dp_rxq, unsigned int id);
 typedef void (sfc_dp_rx_qpurge_t)(struct sfc_dp_rxq *dp_rxq);
 
 /** Get packet types recognized/classified */
-typedef const uint32_t * (sfc_dp_rx_supported_ptypes_get_t)(void);
+typedef const uint32_t * (sfc_dp_rx_supported_ptypes_get_t)(
+				uint32_t tunnel_encaps);
 
 /** Get number of pending Rx descriptors */
 typedef unsigned int (sfc_dp_rx_qdesc_npending_t)(struct sfc_dp_rxq *dp_rxq);
@@ -166,6 +167,7 @@ struct sfc_dp_rx {
 	unsigned int				features;
 #define SFC_DP_RX_FEAT_SCATTER			0x1
 #define SFC_DP_RX_FEAT_MULTI_PROCESS		0x2
+#define SFC_DP_RX_FEAT_TUNNELS			0x4
 	sfc_dp_rx_qcreate_t			*qcreate;
 	sfc_dp_rx_qdestroy_t			*qdestroy;
 	sfc_dp_rx_qstart_t			*qstart;
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 4c76f74..41c2885 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -251,6 +251,7 @@ static void
 sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 			   struct rte_mbuf *m)
 {
+	uint32_t tun_ptype = 0;
 	uint32_t l2_ptype = 0;
 	uint32_t l3_ptype = 0;
 	uint32_t l4_ptype = 0;
@@ -259,15 +260,40 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 	if (unlikely(EFX_TEST_QWORD_BIT(rx_ev, ESF_DZ_RX_PARSE_INCOMPLETE_LBN)))
 		goto done;
 
+	switch (EFX_QWORD_FIELD(rx_ev, ESF_EZ_RX_ENCAP_HDR)) {
+	default:
+		/* Unexpected encapsulation tag class */
+		SFC_ASSERT(false);
+		/* FALLTHROUGH */
+	case ESE_EZ_ENCAP_HDR_NONE:
+		break;
+	case ESE_EZ_ENCAP_HDR_VXLAN:
+		/*
+		 * It is definitely UDP, but we have no information
+		 * about IPv4 vs IPv6 and VLAN tagging.
+		 */
+		tun_ptype = RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP;
+		break;
+	case ESE_EZ_ENCAP_HDR_GRE:
+		/*
+		 * We have no information about IPv4 vs IPv6 and VLAN tagging.
+		 */
+		tun_ptype = RTE_PTYPE_TUNNEL_NVGRE;
+		break;
+	}
+
 	switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_ETH_TAG_CLASS)) {
 	case ESE_DZ_ETH_TAG_CLASS_NONE:
-		l2_ptype = RTE_PTYPE_L2_ETHER;
+		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER :
+			RTE_PTYPE_INNER_L2_ETHER;
 		break;
 	case ESE_DZ_ETH_TAG_CLASS_VLAN1:
-		l2_ptype = RTE_PTYPE_L2_ETHER_VLAN;
+		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER_VLAN :
+			RTE_PTYPE_INNER_L2_ETHER_VLAN;
 		break;
 	case ESE_DZ_ETH_TAG_CLASS_VLAN2:
-		l2_ptype = RTE_PTYPE_L2_ETHER_QINQ;
+		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER_QINQ :
+			RTE_PTYPE_INNER_L2_ETHER_QINQ;
 		break;
 	default:
 		/* Unexpected Eth tag class */
@@ -276,25 +302,31 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 
 	switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_L3_CLASS)) {
 	case ESE_DZ_L3_CLASS_IP4_FRAG:
-		l4_ptype = RTE_PTYPE_L4_FRAG;
+		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_FRAG :
+			RTE_PTYPE_INNER_L4_FRAG;
 		/* FALLTHROUGH */
 	case ESE_DZ_L3_CLASS_IP4:
-		l3_ptype = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+		l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV4_EXT_UNKNOWN :
+			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
 		ol_flags |= PKT_RX_RSS_HASH |
 			((EFX_TEST_QWORD_BIT(rx_ev,
 					     ESF_DZ_RX_IPCKSUM_ERR_LBN)) ?
 			 PKT_RX_IP_CKSUM_BAD : PKT_RX_IP_CKSUM_GOOD);
 		break;
 	case ESE_DZ_L3_CLASS_IP6_FRAG:
-		l4_ptype = RTE_PTYPE_L4_FRAG;
+		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_FRAG :
+			RTE_PTYPE_INNER_L4_FRAG;
 		/* FALLTHROUGH */
 	case ESE_DZ_L3_CLASS_IP6:
-		l3_ptype = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV6_EXT_UNKNOWN :
+			RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
 		ol_flags |= PKT_RX_RSS_HASH;
 		break;
 	case ESE_DZ_L3_CLASS_ARP:
 		/* Override Layer 2 packet type */
-		l2_ptype = RTE_PTYPE_L2_ETHER_ARP;
+		/* There is no ARP classification for inner packets */
+		if (tun_ptype == 0)
+			l2_ptype = RTE_PTYPE_L2_ETHER_ARP;
 		break;
 	default:
 		/* Unexpected Layer 3 class */
@@ -303,14 +335,16 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 
 	switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_L4_CLASS)) {
 	case ESE_DZ_L4_CLASS_TCP:
-		l4_ptype = RTE_PTYPE_L4_TCP;
+		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_TCP :
+			RTE_PTYPE_INNER_L4_TCP;
 		ol_flags |=
 			(EFX_TEST_QWORD_BIT(rx_ev,
 					    ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN)) ?
 			PKT_RX_L4_CKSUM_BAD : PKT_RX_L4_CKSUM_GOOD;
 		break;
 	case ESE_DZ_L4_CLASS_UDP:
-		l4_ptype = RTE_PTYPE_L4_UDP;
+		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_UDP :
+			RTE_PTYPE_INNER_L4_UDP;
 		ol_flags |=
 			(EFX_TEST_QWORD_BIT(rx_ev,
 					    ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN)) ?
@@ -329,7 +363,7 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 
 done:
 	m->ol_flags = ol_flags;
-	m->packet_type = l2_ptype | l3_ptype | l4_ptype;
+	m->packet_type = tun_ptype | l2_ptype | l3_ptype | l4_ptype;
 }
 
 static uint16_t
@@ -515,7 +549,7 @@ sfc_ef10_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 }
 
 static const uint32_t *
-sfc_ef10_supported_ptypes_get(void)
+sfc_ef10_supported_ptypes_get(uint32_t tunnel_encaps)
 {
 	static const uint32_t ef10_native_ptypes[] = {
 		RTE_PTYPE_L2_ETHER,
@@ -529,8 +563,47 @@ sfc_ef10_supported_ptypes_get(void)
 		RTE_PTYPE_L4_UDP,
 		RTE_PTYPE_UNKNOWN
 	};
+	static const uint32_t ef10_overlay_ptypes[] = {
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L2_ETHER_VLAN,
+		RTE_PTYPE_L2_ETHER_QINQ,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_VXLAN,
+		RTE_PTYPE_TUNNEL_NVGRE,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L2_ETHER_QINQ,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
 
-	return ef10_native_ptypes;
+	/*
+	 * The function returns static set of supported packet types,
+	 * so we can't build it dynamically based on supported tunnel
+	 * encapsulations and should limit to known sets.
+	 */
+	switch (tunnel_encaps) {
+	case (1u << EFX_TUNNEL_PROTOCOL_VXLAN |
+	      1u << EFX_TUNNEL_PROTOCOL_GENEVE |
+	      1u << EFX_TUNNEL_PROTOCOL_NVGRE):
+		return ef10_overlay_ptypes;
+	default:
+		RTE_LOG(ERR, PMD,
+			"Unexpected set of supported tunnel encapsulations: %#x\n",
+			tunnel_encaps);
+		/* FALLTHROUGH */
+	case 0:
+		return ef10_native_ptypes;
+	}
 }
 
 static sfc_dp_rx_qdesc_npending_t sfc_ef10_rx_qdesc_npending;
@@ -707,7 +780,8 @@ struct sfc_dp_rx sfc_ef10_rx = {
 		.type		= SFC_DP_RX,
 		.hw_fw_caps	= SFC_DP_HW_FW_CAP_EF10,
 	},
-	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS,
+	.features		= SFC_DP_RX_FEAT_MULTI_PROCESS |
+				  SFC_DP_RX_FEAT_TUNNELS,
 	.qcreate		= sfc_ef10_rx_qcreate,
 	.qdestroy		= sfc_ef10_rx_qdestroy,
 	.qstart			= sfc_ef10_rx_qstart,
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 837fd55..0fea997 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -131,6 +131,10 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		DEV_RX_OFFLOAD_UDP_CKSUM |
 		DEV_RX_OFFLOAD_TCP_CKSUM;
 
+	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
+	    (sa->dp_rx->features & SFC_DP_RX_FEAT_TUNNELS))
+		dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+
 	dev_info->tx_offload_capa =
 		DEV_TX_OFFLOAD_IPV4_CKSUM |
 		DEV_TX_OFFLOAD_UDP_CKSUM |
@@ -183,8 +187,10 @@ static const uint32_t *
 sfc_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 {
 	struct sfc_adapter *sa = dev->data->dev_private;
+	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+	uint32_t tunnel_encaps = encp->enc_tunnel_encapsulations_supported;
 
-	return sa->dp_rx->supported_ptypes_get();
+	return sa->dp_rx->supported_ptypes_get(tunnel_encaps);
 }
 
 static int
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 22bf372..70a72b3 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -193,7 +193,7 @@ sfc_efx_rx_desc_flags_to_packet_type(const unsigned int desc_flags)
 }
 
 static const uint32_t *
-sfc_efx_supported_ptypes_get(void)
+sfc_efx_supported_ptypes_get(__rte_unused uint32_t tunnel_encaps)
 {
 	static const uint32_t ptypes[] = {
 		RTE_PTYPE_L2_ETHER,
@@ -947,6 +947,10 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
 		sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
 		EFX_RXQ_FLAG_SCATTER : EFX_RXQ_FLAG_NONE;
 
+	if ((encp->enc_tunnel_encapsulations_supported != 0) &&
+	    (sa->dp_rx->features & SFC_DP_RX_FEAT_TUNNELS))
+		rxq_info->type_flags |= EFX_RXQ_FLAG_INNER_CLASSES;
+
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
 			  rxq_info->entries, socket_id, &evq);
 	if (rc != 0)
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 12/14] net/sfc: correct Rx checksum offloads for tunnel packets
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (10 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 11/14] net/sfc: support VXLAN and NVGRE packet types classification Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 13/14] net/sfc: support inner checksum offload on transmit Andrew Rybchenko
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

In the case of tunnel packet, PKT_RX_{IP,L4}_CSUM_* flags correspond
to inner packet checksums. There is only one flag to indicate bad
external IPv4 header checksum.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 doc/guides/nics/features/sfc_efx.ini |  2 ++
 doc/guides/nics/sfc_efx.rst          |  2 ++
 drivers/net/sfc/sfc_ef10_rx.c        | 24 ++++++++++++++++++------
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 03890f3..6b73af9 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -24,6 +24,8 @@ Flow API             = Y
 VLAN offload         = P
 L3 checksum offload  = Y
 L4 checksum offload  = Y
+Inner L3 checksum    = Y
+Inner L4 checksum    = Y
 Packet type parsing  = Y
 Rx descriptor status = Y
 Tx descriptor status = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 994e111..813cb6f 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -69,6 +69,8 @@ SFC EFX PMD has support for:
 
 - IPv4/IPv6 TCP/UDP receive checksum offload
 
+- Inner IPv4/IPv6 TCP/UDP receive checksum offload
+
 - Received packet type information
 
 - Receive side scaling (RSS)
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 41c2885..e860a39 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -252,6 +252,10 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 			   struct rte_mbuf *m)
 {
 	uint32_t tun_ptype = 0;
+	/* Which event bit is mapped to PKT_RX_IP_CKSUM_* */
+	int8_t ip_csum_err_bit;
+	/* Which event bit is mapped to PKT_RX_L4_CKSUM_* */
+	int8_t l4_csum_err_bit;
 	uint32_t l2_ptype = 0;
 	uint32_t l3_ptype = 0;
 	uint32_t l4_ptype = 0;
@@ -282,6 +286,17 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 		break;
 	}
 
+	if (tun_ptype == 0) {
+		ip_csum_err_bit = ESF_DZ_RX_IPCKSUM_ERR_LBN;
+		l4_csum_err_bit = ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN;
+	} else {
+		ip_csum_err_bit = ESF_EZ_RX_IP_INNER_CHKSUM_ERR_LBN;
+		l4_csum_err_bit = ESF_EZ_RX_TCP_UDP_INNER_CHKSUM_ERR_LBN;
+		if (unlikely(EFX_TEST_QWORD_BIT(rx_ev,
+						ESF_DZ_RX_IPCKSUM_ERR_LBN)))
+			ol_flags |= PKT_RX_EIP_CKSUM_BAD;
+	}
+
 	switch (EFX_QWORD_FIELD(rx_ev, ESF_DZ_RX_ETH_TAG_CLASS)) {
 	case ESE_DZ_ETH_TAG_CLASS_NONE:
 		l2_ptype = (tun_ptype == 0) ? RTE_PTYPE_L2_ETHER :
@@ -309,8 +324,7 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 		l3_ptype = (tun_ptype == 0) ? RTE_PTYPE_L3_IPV4_EXT_UNKNOWN :
 			RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
 		ol_flags |= PKT_RX_RSS_HASH |
-			((EFX_TEST_QWORD_BIT(rx_ev,
-					     ESF_DZ_RX_IPCKSUM_ERR_LBN)) ?
+			((EFX_TEST_QWORD_BIT(rx_ev, ip_csum_err_bit)) ?
 			 PKT_RX_IP_CKSUM_BAD : PKT_RX_IP_CKSUM_GOOD);
 		break;
 	case ESE_DZ_L3_CLASS_IP6_FRAG:
@@ -338,16 +352,14 @@ sfc_ef10_rx_ev_to_offloads(struct sfc_ef10_rxq *rxq, const efx_qword_t rx_ev,
 		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_TCP :
 			RTE_PTYPE_INNER_L4_TCP;
 		ol_flags |=
-			(EFX_TEST_QWORD_BIT(rx_ev,
-					    ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN)) ?
+			(EFX_TEST_QWORD_BIT(rx_ev, l4_csum_err_bit)) ?
 			PKT_RX_L4_CKSUM_BAD : PKT_RX_L4_CKSUM_GOOD;
 		break;
 	case ESE_DZ_L4_CLASS_UDP:
 		l4_ptype = (tun_ptype == 0) ? RTE_PTYPE_L4_UDP :
 			RTE_PTYPE_INNER_L4_UDP;
 		ol_flags |=
-			(EFX_TEST_QWORD_BIT(rx_ev,
-					    ESF_DZ_RX_TCPUDP_CKSUM_ERR_LBN)) ?
+			(EFX_TEST_QWORD_BIT(rx_ev, l4_csum_err_bit)) ?
 			PKT_RX_L4_CKSUM_BAD : PKT_RX_L4_CKSUM_GOOD;
 		break;
 	case ESE_DZ_L4_CLASS_UNKNOWN:
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 13/14] net/sfc: support inner checksum offload on transmit
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (11 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 12/14] net/sfc: correct Rx checksum offloads for tunnel packets Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 14/14] doc: add net/sfc tunnels support to release features Andrew Rybchenko
  2018-01-09 17:31 ` [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Ferruh Yigit
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

There is no dedicated controls for inner checksum offload on
device/queue level. So, enable together with outer offloads.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
---
 doc/guides/nics/sfc_efx.rst  | 2 ++
 drivers/net/sfc/sfc_ethdev.c | 3 +++
 drivers/net/sfc/sfc_tx.c     | 8 ++++++++
 3 files changed, 13 insertions(+)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 813cb6f..8e0782c 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -48,6 +48,8 @@ SFC EFX PMD has support for:
 
 - IPv4/IPv6 TCP/UDP transmit checksum offload
 
+- Inner IPv4/IPv6 TCP/UDP transmit checksum offload
+
 - Port hardware statistics
 
 - Extended statistics (see Solarflare Server Adapter User's Guide for
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 0fea997..1b700b1 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -140,6 +140,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		DEV_TX_OFFLOAD_UDP_CKSUM |
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 
+	if (encp->enc_tunnel_encapsulations_supported != 0)
+		dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+
 	dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP;
 	if ((~sa->dp_tx->features & SFC_DP_TX_FEAT_VLAN_INSERT) ||
 	    !encp->enc_hw_tx_insert_vlan_enabled)
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index d1320f4..f580fb5 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -410,6 +410,7 @@ sfc_tx_close(struct sfc_adapter *sa)
 int
 sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 {
+	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
 	struct rte_eth_dev_data *dev_data;
 	struct sfc_txq_info *txq_info;
 	struct sfc_txq *txq;
@@ -440,9 +441,16 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	if ((txq->flags & ETH_TXQ_FLAGS_NOXSUMTCP) ||
 	    (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP)) {
 		flags = EFX_TXQ_CKSUM_IPV4;
+
+		if (encp->enc_tunnel_encapsulations_supported != 0)
+			flags |= EFX_TXQ_CKSUM_INNER_IPV4;
 	} else {
 		flags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;
 
+		if (encp->enc_tunnel_encapsulations_supported != 0)
+			flags |= EFX_TXQ_CKSUM_INNER_IPV4 |
+				 EFX_TXQ_CKSUM_INNER_TCPUDP;
+
 		if (sa->tso)
 			flags |= EFX_TXQ_FATSOV2;
 	}
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [dpdk-dev] [PATCH 14/14] doc: add net/sfc tunnels support to release features
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (12 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 13/14] net/sfc: support inner checksum offload on transmit Andrew Rybchenko
@ 2017-12-24 10:46 ` Andrew Rybchenko
  2018-01-09 17:31 ` [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Ferruh Yigit
  14 siblings, 0 replies; 16+ messages in thread
From: Andrew Rybchenko @ 2017-12-24 10:46 UTC (permalink / raw)
  To: dev

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
 doc/guides/rel_notes/release_18_02.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 24b67bb..3e5867f 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -41,6 +41,14 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Added NVGRE and UDP tunnels support in Solarflare network PMD.**
+
+  Added support for NVGRE, VXLAN and GENEVE tunnels.
+
+  * Added support for UDP tunnel ports configuration.
+  * Added tunneled packets classification.
+  * Added inner checksum offload.
+
 
 API Changes
 -----------
-- 
2.7.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels
  2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
                   ` (13 preceding siblings ...)
  2017-12-24 10:46 ` [dpdk-dev] [PATCH 14/14] doc: add net/sfc tunnels support to release features Andrew Rybchenko
@ 2018-01-09 17:31 ` Ferruh Yigit
  14 siblings, 0 replies; 16+ messages in thread
From: Ferruh Yigit @ 2018-01-09 17:31 UTC (permalink / raw)
  To: Andrew Rybchenko, dev

On 12/24/2017 10:46 AM, Andrew Rybchenko wrote:
> MC reboot handling is required for tunnels support since tunnel UDP
> ports reconfiguration triggers MC reboot.
> 
> Support tunnel packet types classification and inner/outer Rx checksum
> offload in EF10 native Rx datapath.
> 
> Support for inner checksum offload on transmit is datapath-independent
> since it just requires to enable the offload.
> 
> checkpatches.sh generates errors/warnings for base driver patches
> because of coding standard difference.
> 
> Warning about positive errno is expected since positive error codes are
> used inside the driver (since base driver uses positive error code) and
> conversion to negative is done in net/sfc ethdev interface implementation.
> 
> Andrew Rybchenko (13):
>   net/sfc: fix label name to be consistent
>   net/sfc: do not hold management event queue lock while MCDI
>   net/sfc: handle MC reboot event
>   net/sfc: retry port start to handle MC reboot in the middle
>   net/sfc/base: control RxQ scatter using flag instead of type
>   net/sfc/base: add function to create packed stream RxQ
>   net/sfc/base: allow to request inner classes for Rx packets
>   net/sfc: support UDP tunnel ports configuration
>   net/sfc: fix incorrect bitwise ORing of L3/L4 packet types
>   net/sfc: support VXLAN and NVGRE packet types classification
>   net/sfc: correct Rx checksum offloads for tunnel packets
>   net/sfc: support inner checksum offload on transmit
>   doc: add net/sfc tunnels support to release features
> 
> Ivan Malov (1):
>   net/sfc/base: add API to control UDP tunnel ports

Series applied to dpdk-next-net/master, thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-01-09 17:31 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-24 10:46 [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 01/14] net/sfc: fix label name to be consistent Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 02/14] net/sfc: do not hold management event queue lock while MCDI Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 03/14] net/sfc: handle MC reboot event Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 04/14] net/sfc: retry port start to handle MC reboot in the middle Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 05/14] net/sfc/base: control RxQ scatter using flag instead of type Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 06/14] net/sfc/base: add function to create packed stream RxQ Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 07/14] net/sfc/base: allow to request inner classes for Rx packets Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 08/14] net/sfc/base: add API to control UDP tunnel ports Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 09/14] net/sfc: support UDP tunnel ports configuration Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 10/14] net/sfc: fix incorrect bitwise ORing of L3/L4 packet types Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 11/14] net/sfc: support VXLAN and NVGRE packet types classification Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 12/14] net/sfc: correct Rx checksum offloads for tunnel packets Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 13/14] net/sfc: support inner checksum offload on transmit Andrew Rybchenko
2017-12-24 10:46 ` [dpdk-dev] [PATCH 14/14] doc: add net/sfc tunnels support to release features Andrew Rybchenko
2018-01-09 17:31 ` [dpdk-dev] [PATCH 00/14] net/sfc: support NVGRE, VXLAN and GENEVE tunnels Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).