* [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD
@ 2016-12-02 7:44 Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 01/31] net/sfc: implement MCDI logging callback Andrew Rybchenko
` (32 more replies)
0 siblings, 33 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
The patch series adds a number of features to Solarflare libefx-based
PMD. Basically one patch per feature.
The patches are grouped into one series since they touch nearby lines
in either PMD feature list, or dev_ops structure, or documentation.
So, patches cannot be applied in arbitrary order.
The patch series should be applied after
[PATCH v2 00/55] Solarflare libefx-based PMD
(Message-ID: 1480436367-20749-1-git-send-email-arybchenko@solarflare.com)
Andrew Rybchenko (16):
net/sfc: implement MCDI logging callback
net/sfc: support parameter to choose performance profile
net/sfc: implement ethdev hook to get basic statistics
net/sfc: support extended statistics
net/sfc: support flow control settings get/set
net/sfc: support link status change interrupt
net/sfc: implement device operation to change MTU
net/sfc: support link speed and duplex settings
net/sfc: support checksum offloads on receive
net/sfc: handle received packet type info provided by HW
net/sfc: support callback to get receive queue information
net/sfc: support Rx free threshold
net/sfc: add callback to get RxQ pending descriptors count
net/sfc: add RxQ descriptor done callback
net/sfc: support scattered Rx DMA
net/sfc: support deferred start of receive queues
Artem Andreev (1):
net/sfc: support link up/down
Ivan Malov (14):
net/sfc: support promiscuous and all-multicast control
net/sfc: support main (the first) MAC address change
net/sfc: support multicast addresses list controls
net/sfc: add callback to get transmit queue information
net/sfc: support Tx free threshold
net/sfc: support deferred start of transmit queues
net/sfc: support VLAN offload on transmit path
net/sfc: add basic stubs for RSS support on driver attach
net/sfc: support RSS hash offload
net/sfc: add callback to query RSS key and hash types config
net/sfc: add callback to set RSS key and hash types config
net/sfc: add callback to query RSS redirection table
net/sfc: add callback to update RSS redirection table
net/sfc: support firmware-assisted TSOv2
config/common_base | 1 +
doc/guides/nics/features/sfc_efx.ini | 22 +-
doc/guides/nics/sfc_efx.rst | 55 ++-
drivers/net/sfc/Makefile | 4 +
drivers/net/sfc/efsys.h | 8 +-
drivers/net/sfc/sfc.c | 126 ++++-
drivers/net/sfc/sfc.h | 46 ++
drivers/net/sfc/sfc_ethdev.c | 893 ++++++++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_ev.c | 64 ++-
drivers/net/sfc/sfc_ev.h | 2 +
drivers/net/sfc/sfc_intr.c | 204 ++++++++
drivers/net/sfc/sfc_kvargs.c | 2 +
drivers/net/sfc/sfc_kvargs.h | 12 +
drivers/net/sfc/sfc_mcdi.c | 69 +++
drivers/net/sfc/sfc_port.c | 107 ++++-
drivers/net/sfc/sfc_rx.c | 288 ++++++++++-
drivers/net/sfc/sfc_rx.h | 16 +
drivers/net/sfc/sfc_tso.c | 203 ++++++++
drivers/net/sfc/sfc_tweak.h | 3 +
drivers/net/sfc/sfc_tx.c | 165 ++++++-
drivers/net/sfc/sfc_tx.h | 41 +-
21 files changed, 2259 insertions(+), 72 deletions(-)
create mode 100644 drivers/net/sfc/sfc_tso.c
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 01/31] net/sfc: implement MCDI logging callback
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 02/31] net/sfc: support parameter to choose performance profile Andrew Rybchenko
` (31 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/sfc_efx.rst | 6 ++++
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc.h | 1 +
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_kvargs.c | 1 +
drivers/net/sfc/sfc_kvargs.h | 2 ++
drivers/net/sfc/sfc_mcdi.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index aadd775..2cca287 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -155,3 +155,9 @@ boolean parameters value.
- ``debug_init`` [bool] (default **n**)
Enable extra logging during device intialization and startup.
+
+- ``mcdi_logging`` [bool] (default **n**)
+
+ Enable extra logging of the communication with the NIC's management CPU.
+ The logging is done using RTE_LOG() with INFO level and PMD type.
+ The format is consumed by the Solarflare netlogdecode cross-platform tool.
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index e4d5035..d48eb4c 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -175,7 +175,7 @@ prefetch_read_once(const volatile void *addr)
/* MCDI is required for SFN7xxx and SFN8xx */
#define EFSYS_OPT_MCDI 1
-#define EFSYS_OPT_MCDI_LOGGING 0
+#define EFSYS_OPT_MCDI_LOGGING 1
#define EFSYS_OPT_MCDI_PROXY_AUTH 0
#define EFSYS_OPT_MAC_STATS 0
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 29d3a6b..0064fcb 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -107,6 +107,7 @@ struct sfc_mcdi {
efsys_mem_t mem;
enum sfc_mcdi_state state;
efx_mcdi_transport_t transport;
+ bool logging;
};
struct sfc_intr {
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c28082c..12309ee 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -464,4 +464,5 @@ static struct eth_driver sfc_efx_pmd = {
RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
+ SFC_KVARG_MCDI_LOGGING "=" SFC_KVARG_VALUES_BOOL " "
SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);
diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c
index f1bab28..bbbd026 100644
--- a/drivers/net/sfc/sfc_kvargs.c
+++ b/drivers/net/sfc/sfc_kvargs.c
@@ -42,6 +42,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa)
struct rte_devargs *devargs = sa->eth_dev->pci_dev->device.devargs;
const char **params = (const char *[]){
SFC_KVARG_DEBUG_INIT,
+ SFC_KVARG_MCDI_LOGGING,
NULL,
};
diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h
index 0b53963..ffce851 100644
--- a/drivers/net/sfc/sfc_kvargs.h
+++ b/drivers/net/sfc/sfc_kvargs.h
@@ -40,6 +40,8 @@ extern "C" {
#define SFC_KVARG_DEBUG_INIT "debug_init"
+#define SFC_KVARG_MCDI_LOGGING "mcdi_logging"
+
struct sfc_adapter;
int sfc_kvargs_parse(struct sfc_adapter *sa);
diff --git a/drivers/net/sfc/sfc_mcdi.c b/drivers/net/sfc/sfc_mcdi.c
index 9ba28e1..3bed2e0 100644
--- a/drivers/net/sfc/sfc_mcdi.c
+++ b/drivers/net/sfc/sfc_mcdi.c
@@ -35,6 +35,7 @@
#include "sfc.h"
#include "sfc_log.h"
+#include "sfc_kvargs.h"
#define SFC_MCDI_POLL_INTERVAL_MIN_US 10 /* 10us in 1us units */
#define SFC_MCDI_POLL_INTERVAL_MAX_US (US_PER_S / 10) /* 100ms in 1us units */
@@ -125,6 +126,65 @@ sfc_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
sfc_panic(sa, "MCDI exceptions handling is not implemented\n");
}
+#define SFC_MCDI_LOG_BUF_SIZE 128
+
+static size_t
+sfc_mcdi_do_log(const struct sfc_adapter *sa,
+ char *buffer, void *data, size_t data_size,
+ size_t pfxsize, size_t position)
+{
+ uint32_t *words = data;
+ /* Space separator plus 2 characters per byte */
+ const size_t word_str_space = 1 + 2 * sizeof(*words);
+ size_t i;
+
+ for (i = 0; i < data_size; i += sizeof(*words)) {
+ if (position + word_str_space >=
+ SFC_MCDI_LOG_BUF_SIZE) {
+ /* Flush at SFC_MCDI_LOG_BUF_SIZE with backslash
+ * at the end which is required by netlogdecode.
+ */
+ buffer[position] = '\0';
+ sfc_info(sa, "%s \\", buffer);
+ /* Preserve prefix for the next log message */
+ position = pfxsize;
+ }
+ position += snprintf(buffer + position,
+ SFC_MCDI_LOG_BUF_SIZE - position,
+ " %08x", *words);
+ words++;
+ }
+ return position;
+}
+
+static void
+sfc_mcdi_logger(void *arg, efx_log_msg_t type,
+ void *header, size_t header_size,
+ void *data, size_t data_size)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)arg;
+ char buffer[SFC_MCDI_LOG_BUF_SIZE];
+ size_t pfxsize;
+ size_t start;
+
+ if (!sa->mcdi.logging)
+ return;
+
+ /* The format including prefix added by sfc_info() is the format
+ * consumed by the Solarflare netlogdecode tool.
+ */
+ pfxsize = snprintf(buffer, sizeof(buffer), "MCDI RPC %s:",
+ type == EFX_LOG_MCDI_REQUEST ? "REQ" :
+ type == EFX_LOG_MCDI_RESPONSE ? "RESP" : "???");
+ start = sfc_mcdi_do_log(sa, buffer, header, header_size,
+ pfxsize, pfxsize);
+ start = sfc_mcdi_do_log(sa, buffer, data, data_size, pfxsize, start);
+ if (start != pfxsize) {
+ buffer[start] = '\0';
+ sfc_info(sa, "%s", buffer);
+ }
+}
+
int
sfc_mcdi_init(struct sfc_adapter *sa)
{
@@ -149,12 +209,19 @@ sfc_mcdi_init(struct sfc_adapter *sa)
if (rc != 0)
goto fail_dma_alloc;
+ /* Convert negative error to positive used in the driver */
+ rc = sfc_kvargs_process(sa, SFC_KVARG_MCDI_LOGGING,
+ sfc_kvarg_bool_handler, &mcdi->logging);
+ if (rc != 0)
+ goto fail_kvargs_process;
+
emtp = &mcdi->transport;
emtp->emt_context = sa;
emtp->emt_dma_mem = &mcdi->mem;
emtp->emt_execute = sfc_mcdi_execute;
emtp->emt_ev_cpl = sfc_mcdi_ev_cpl;
emtp->emt_exception = sfc_mcdi_exception;
+ emtp->emt_logger = sfc_mcdi_logger;
sfc_log_init(sa, "init MCDI");
rc = efx_mcdi_init(sa->nic, emtp);
@@ -165,6 +232,8 @@ sfc_mcdi_init(struct sfc_adapter *sa)
fail_mcdi_init:
memset(emtp, 0, sizeof(*emtp));
+
+fail_kvargs_process:
sfc_dma_free(sa, &mcdi->mem);
fail_dma_alloc:
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 02/31] net/sfc: support parameter to choose performance profile
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 01/31] net/sfc: implement MCDI logging callback Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 03/31] net/sfc: implement ethdev hook to get basic statistics Andrew Rybchenko
` (30 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Supported options are auto (based on NIC firmware variant and
installed licences), throughput, low-latency.
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/sfc_efx.rst | 7 +++++++
drivers/net/sfc/sfc.h | 1 +
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_ev.c | 36 +++++++++++++++++++++++++++++++++---
drivers/net/sfc/sfc_ev.h | 2 ++
drivers/net/sfc/sfc_kvargs.c | 1 +
drivers/net/sfc/sfc_kvargs.h | 10 ++++++++++
7 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 2cca287..36d0974 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -152,6 +152,13 @@ whitelist option like "-w 02:00.0,arg1=value1,...".
Case-insensitive 1/y/yes/on or 0/n/no/off may be used to specify
boolean parameters value.
+- ``perf_profile`` [auto|throughput|low-latency] (default **throughput**)
+
+ Choose hardware tunning to be optimized for either throughput or
+ low-latency.
+ **auto** allows NIC firmware to make a choice based on
+ installed licences and firmware variant configured using **sfboot**.
+
- ``debug_init`` [bool] (default **n**)
Enable extra logging during device intialization and startup.
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 0064fcb..d0aafa3 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -152,6 +152,7 @@ struct sfc_adapter {
unsigned int txq_max_entries;
+ uint32_t evq_flags;
unsigned int evq_count;
struct sfc_evq_info *evq_info;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 12309ee..1df227e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -464,5 +464,6 @@ static struct eth_driver sfc_efx_pmd = {
RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
+ SFC_KVARG_PERF_PROFILE "=" SFC_KVARG_VALUES_PERF_PROFILE " "
SFC_KVARG_MCDI_LOGGING "=" SFC_KVARG_VALUES_BOOL " "
SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 96b95cc..34c1127 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -39,6 +39,7 @@
#include "sfc_ev.h"
#include "sfc_rx.h"
#include "sfc_tx.h"
+#include "sfc_kvargs.h"
/* Initial delay when waiting for event queue init complete event */
@@ -365,9 +366,7 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
/* Create the common code event queue */
rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq_info->entries,
- 0 /* unused on EF10 */, 0,
- EFX_EVQ_FLAGS_TYPE_THROUGHPUT |
- EFX_EVQ_FLAGS_NOTIFY_DISABLED,
+ 0 /* unused on EF10 */, 0, evq_info->flags,
&evq->common);
if (rc != 0)
goto fail_ev_qcreate;
@@ -600,6 +599,25 @@ sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
SFC_ASSERT(rte_is_power_of_2(max_entries));
evq_info->max_entries = max_entries;
+ evq_info->flags = sa->evq_flags | EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+
+ return 0;
+}
+
+static int
+sfc_kvarg_perf_profile_handler(__rte_unused const char *key,
+ const char *value_str, void *opaque)
+{
+ uint64_t *value = opaque;
+
+ if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_THROUGHPUT) == 0)
+ *value = EFX_EVQ_FLAGS_TYPE_THROUGHPUT;
+ else if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_LOW_LATENCY) == 0)
+ *value = EFX_EVQ_FLAGS_TYPE_LOW_LATENCY;
+ else if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_AUTO) == 0)
+ *value = EFX_EVQ_FLAGS_TYPE_AUTO;
+ else
+ return -EINVAL;
return 0;
}
@@ -620,6 +638,16 @@ sfc_ev_init(struct sfc_adapter *sa)
sfc_log_init(sa, "entry");
+ sa->evq_flags = EFX_EVQ_FLAGS_TYPE_THROUGHPUT;
+ rc = sfc_kvargs_process(sa, SFC_KVARG_PERF_PROFILE,
+ sfc_kvarg_perf_profile_handler,
+ &sa->evq_flags);
+ if (rc != 0) {
+ sfc_err(sa, "invalid %s parameter value",
+ SFC_KVARG_PERF_PROFILE);
+ goto fail_kvarg_perf_profile;
+ }
+
sa->evq_count = sfc_ev_qcount(sa);
sa->mgmt_evq_index = 0;
rte_spinlock_init(&sa->mgmt_evq_lock);
@@ -660,6 +688,8 @@ sfc_ev_init(struct sfc_adapter *sa)
fail_evqs_alloc:
sa->evq_count = 0;
+
+fail_kvarg_perf_profile:
sfc_log_init(sa, "failed %d", rc);
return rc;
}
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index 110f3b6..346e3ec 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -74,6 +74,8 @@ struct sfc_evq_info {
unsigned int max_entries;
/* Real number of EVQ entries, less or equal to max_entries */
unsigned int entries;
+ /* Event queue creation flags */
+ uint32_t flags;
/* NUMA-aware EVQ data structure used on datapath */
struct sfc_evq *evq;
};
diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c
index bbbd026..2ced47c 100644
--- a/drivers/net/sfc/sfc_kvargs.c
+++ b/drivers/net/sfc/sfc_kvargs.c
@@ -43,6 +43,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa)
const char **params = (const char *[]){
SFC_KVARG_DEBUG_INIT,
SFC_KVARG_MCDI_LOGGING,
+ SFC_KVARG_PERF_PROFILE,
NULL,
};
diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h
index ffce851..2fea9c7 100644
--- a/drivers/net/sfc/sfc_kvargs.h
+++ b/drivers/net/sfc/sfc_kvargs.h
@@ -42,6 +42,16 @@ extern "C" {
#define SFC_KVARG_MCDI_LOGGING "mcdi_logging"
+#define SFC_KVARG_PERF_PROFILE "perf_profile"
+
+#define SFC_KVARG_PERF_PROFILE_AUTO "auto"
+#define SFC_KVARG_PERF_PROFILE_THROUGHPUT "throughput"
+#define SFC_KVARG_PERF_PROFILE_LOW_LATENCY "low-latency"
+#define SFC_KVARG_VALUES_PERF_PROFILE \
+ "[" SFC_KVARG_PERF_PROFILE_AUTO "|" \
+ SFC_KVARG_PERF_PROFILE_THROUGHPUT "|" \
+ SFC_KVARG_PERF_PROFILE_LOW_LATENCY "]"
+
struct sfc_adapter;
int sfc_kvargs_parse(struct sfc_adapter *sa);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 03/31] net/sfc: implement ethdev hook to get basic statistics
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 01/31] net/sfc: implement MCDI logging callback Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 02/31] net/sfc: support parameter to choose performance profile Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 04/31] net/sfc: support extended statistics Andrew Rybchenko
` (29 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Does not implement any deprecated statistics.
No per-queue statistics yet.
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 +
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc.h | 7 ++++
drivers/net/sfc/sfc_ethdev.c | 69 +++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 75 ++++++++++++++++++++++++++++++++++++
6 files changed, 155 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 67df1c6..f55a988 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,6 +7,7 @@
Link status = Y
L3 checksum offload = P
L4 checksum offload = P
+Basic stats = Y
BSD nic_uio = Y
Linux UIO = Y
Linux VFIO = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 36d0974..cbb51de 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
+- Port hardware statistics
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index d48eb4c..fe8615f 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -178,7 +178,7 @@ prefetch_read_once(const volatile void *addr)
#define EFSYS_OPT_MCDI_LOGGING 1
#define EFSYS_OPT_MCDI_PROXY_AUTH 0
-#define EFSYS_OPT_MAC_STATS 0
+#define EFSYS_OPT_MAC_STATS 1
#define EFSYS_OPT_LOOPBACK 0
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index d0aafa3..1189283 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -122,6 +122,12 @@ struct sfc_port {
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
+
+ rte_spinlock_t mac_stats_lock;
+ uint64_t *mac_stats_buf;
+ efsys_mem_t mac_stats_dma_mem;
+
+ uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES];
};
/* Adapter private data */
@@ -229,6 +235,7 @@ int sfc_port_start(struct sfc_adapter *sa);
void sfc_port_stop(struct sfc_adapter *sa);
void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info);
+int sfc_port_update_mac_stats(struct sfc_adapter *sa);
#ifdef __cplusplus
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1df227e..f31330c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -324,12 +324,81 @@ sfc_tx_queue_release(void *queue)
sfc_adapter_unlock(sa);
}
+static void
+sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ uint64_t *mac_stats;
+
+ rte_spinlock_lock(&port->mac_stats_lock);
+
+ if (sfc_port_update_mac_stats(sa) != 0)
+ goto unlock;
+
+ mac_stats = port->mac_stats_buf;
+
+ if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask,
+ EFX_MAC_VADAPTER_RX_UNICAST_PACKETS)) {
+ stats->ipackets =
+ mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS];
+ stats->opackets =
+ mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
+ stats->ibytes =
+ mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES];
+ stats->obytes =
+ mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
+ stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_OVERFLOW];
+ stats->ierrors = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
+ stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
+ } else {
+ stats->ipackets = mac_stats[EFX_MAC_RX_PKTS];
+ stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
+ stats->ibytes = mac_stats[EFX_MAC_RX_OCTETS];
+ stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
+ /*
+ * Take into account stats which are whenever supported
+ * on EF10. If some stat is not supported by current
+ * firmware variant or HW revision, it is guaranteed
+ * to be zero in mac_stats.
+ */
+ stats->imissed =
+ mac_stats[EFX_MAC_RX_NODESC_DROP_CNT] +
+ mac_stats[EFX_MAC_PM_TRUNC_BB_OVERFLOW] +
+ mac_stats[EFX_MAC_PM_DISCARD_BB_OVERFLOW] +
+ mac_stats[EFX_MAC_PM_TRUNC_VFIFO_FULL] +
+ mac_stats[EFX_MAC_PM_DISCARD_VFIFO_FULL] +
+ mac_stats[EFX_MAC_PM_TRUNC_QBB] +
+ mac_stats[EFX_MAC_PM_DISCARD_QBB] +
+ mac_stats[EFX_MAC_PM_DISCARD_MAPPING] +
+ mac_stats[EFX_MAC_RXDP_Q_DISABLED_PKTS] +
+ mac_stats[EFX_MAC_RXDP_DI_DROPPED_PKTS];
+ stats->ierrors =
+ mac_stats[EFX_MAC_RX_FCS_ERRORS] +
+ mac_stats[EFX_MAC_RX_ALIGN_ERRORS] +
+ mac_stats[EFX_MAC_RX_JABBER_PKTS];
+ /* no oerrors counters supported on EF10 */
+ }
+
+unlock:
+ rte_spinlock_unlock(&port->mac_stats_lock);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
.dev_stop = sfc_dev_stop,
.dev_close = sfc_dev_close,
.link_update = sfc_dev_link_update,
+ .stats_get = sfc_stats_get,
.dev_infos_get = sfc_dev_infos_get,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index c124181..d8ff097 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -32,6 +32,34 @@
#include "sfc.h"
#include "sfc_log.h"
+/**
+ * Update MAC statistics in the buffer.
+ *
+ * @param sa Adapter
+ *
+ * @return Status code
+ * @retval 0 Success
+ * @retval EAGAIN Try again
+ * @retval ENOMEM Memory allocation failure
+ */
+int
+sfc_port_update_mac_stats(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ int rc;
+
+ SFC_ASSERT(rte_spinlock_is_locked(&port->mac_stats_lock));
+
+ if (sa->state != SFC_ADAPTER_STARTED)
+ return EINVAL;
+
+ rc = efx_mac_stats_update(sa->nic, &port->mac_stats_dma_mem,
+ port->mac_stats_buf, NULL);
+ if (rc != 0)
+ return rc;
+
+ return 0;
+}
int
sfc_port_start(struct sfc_adapter *sa)
@@ -67,6 +95,19 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mac_filter_set;
+ efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
+ sizeof(port->mac_stats_mask));
+
+ /* Update MAC stats using periodic DMA.
+ * Common code always uses 1000ms update period, so period_ms
+ * parameter only needs to be non-zero to start updates.
+ */
+ sfc_log_init(sa, "request MAC stats DMA'ing");
+ rc = efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
+ 1000, B_FALSE);
+ if (rc != 0)
+ goto fail_mac_stats_periodic;
+
sfc_log_init(sa, "disable MAC drain");
rc = efx_mac_drain(sa->nic, B_FALSE);
if (rc != 0)
@@ -76,6 +117,10 @@ sfc_port_start(struct sfc_adapter *sa)
return 0;
fail_mac_drain:
+ (void)efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
+ 0, B_FALSE);
+
+fail_mac_stats_periodic:
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
@@ -95,6 +140,10 @@ sfc_port_stop(struct sfc_adapter *sa)
sfc_log_init(sa, "entry");
efx_mac_drain(sa->nic, B_TRUE);
+
+ (void)efx_mac_stats_periodic(sa->nic, &sa->port.mac_stats_dma_mem,
+ 0, B_FALSE);
+
efx_port_fini(sa->nic);
efx_filter_fini(sa->nic);
@@ -106,6 +155,7 @@ sfc_port_init(struct sfc_adapter *sa)
{
const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
struct sfc_port *port = &sa->port;
+ int rc;
sfc_log_init(sa, "entry");
@@ -118,15 +168,40 @@ sfc_port_init(struct sfc_adapter *sa)
else
port->pdu = EFX_MAC_PDU(dev_data->mtu);
+ rte_spinlock_init(&port->mac_stats_lock);
+
+ rc = ENOMEM;
+ port->mac_stats_buf = rte_calloc_socket("mac_stats_buf", EFX_MAC_NSTATS,
+ sizeof(uint64_t), 0,
+ sa->socket_id);
+ if (port->mac_stats_buf == NULL)
+ goto fail_mac_stats_buf_alloc;
+
+ rc = sfc_dma_alloc(sa, "mac_stats", 0, EFX_MAC_STATS_SIZE,
+ sa->socket_id, &port->mac_stats_dma_mem);
+ if (rc != 0)
+ goto fail_mac_stats_dma_alloc;
+
sfc_log_init(sa, "done");
return 0;
+
+fail_mac_stats_dma_alloc:
+ rte_free(port->mac_stats_buf);
+fail_mac_stats_buf_alloc:
+ sfc_log_init(sa, "failed %d", rc);
+ return rc;
}
void
sfc_port_fini(struct sfc_adapter *sa)
{
+ struct sfc_port *port = &sa->port;
+
sfc_log_init(sa, "entry");
+ sfc_dma_free(sa, &port->mac_stats_dma_mem);
+ rte_free(port->mac_stats_buf);
+
sfc_log_init(sa, "done");
}
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 04/31] net/sfc: support extended statistics
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (2 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 03/31] net/sfc: implement ethdev hook to get basic statistics Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 05/31] net/sfc: support flow control settings get/set Andrew Rybchenko
` (28 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc_ethdev.c | 63 ++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index f55a988..698553c 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -8,6 +8,7 @@ Link status = Y
L3 checksum offload = P
L4 checksum offload = P
Basic stats = Y
+Extended stats = Y
BSD nic_uio = Y
Linux UIO = Y
Linux VFIO = Y
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index fe8615f..0f941e6 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -159,7 +159,7 @@ prefetch_read_once(const volatile void *addr)
/* Code inclusion options */
-#define EFSYS_OPT_NAMES 0
+#define EFSYS_OPT_NAMES 1
/* Disable SFN5xxx/SFN6xxx since it requires specific support in the PMD */
#define EFSYS_OPT_SIENA 0
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f31330c..d5ae1a0 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -392,6 +392,67 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
rte_spinlock_unlock(&port->mac_stats_lock);
}
+static int
+sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+ unsigned int xstats_count)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ uint64_t *mac_stats;
+ int rc;
+ unsigned int i;
+ int nstats = 0;
+
+ rte_spinlock_lock(&port->mac_stats_lock);
+
+ rc = sfc_port_update_mac_stats(sa);
+ if (rc != 0) {
+ SFC_ASSERT(rc > 0);
+ nstats = -rc;
+ goto unlock;
+ }
+
+ mac_stats = port->mac_stats_buf;
+
+ for (i = 0; i < EFX_MAC_NSTATS; ++i) {
+ if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
+ if (xstats != NULL && nstats < (int)xstats_count) {
+ xstats[nstats].id = nstats;
+ xstats[nstats].value = mac_stats[i];
+ }
+ nstats++;
+ }
+ }
+
+unlock:
+ rte_spinlock_unlock(&port->mac_stats_lock);
+
+ return nstats;
+}
+
+static int
+sfc_xstats_get_names(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int xstats_count)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ unsigned int i;
+ unsigned int nstats = 0;
+
+ for (i = 0; i < EFX_MAC_NSTATS; ++i) {
+ if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
+ if (xstats_names != NULL && nstats < xstats_count)
+ strncpy(xstats_names[nstats].name,
+ efx_mac_stat_name(sa->nic, i),
+ sizeof(xstats_names[0].name));
+ nstats++;
+ }
+ }
+
+ return nstats;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -399,6 +460,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_close = sfc_dev_close,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
+ .xstats_get = sfc_xstats_get,
+ .xstats_get_names = sfc_xstats_get_names,
.dev_infos_get = sfc_dev_infos_get,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 05/31] net/sfc: support flow control settings get/set
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (3 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 04/31] net/sfc: support extended statistics Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 06/31] net/sfc: support link status change interrupt Andrew Rybchenko
` (27 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 +
drivers/net/sfc/sfc_ethdev.c | 98 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 8 +++
4 files changed, 109 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 698553c..25472f8 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -5,6 +5,7 @@
;
[Features]
Link status = Y
+Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
Basic stats = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index cbb51de..1cfed6a 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -50,6 +50,8 @@ SFC EFX PMD has support for:
- Port hardware statistics
+- Basic flow control
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index d5ae1a0..eff648b 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -453,6 +453,102 @@ sfc_xstats_get_names(struct rte_eth_dev *dev,
return nstats;
}
+static int
+sfc_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ unsigned int wanted_fc, link_fc;
+
+ memset(fc_conf, 0, sizeof(*fc_conf));
+
+ sfc_adapter_lock(sa);
+
+ if (sa->state == SFC_ADAPTER_STARTED)
+ efx_mac_fcntl_get(sa->nic, &wanted_fc, &link_fc);
+ else
+ link_fc = sa->port.flow_ctrl;
+
+ switch (link_fc) {
+ case 0:
+ fc_conf->mode = RTE_FC_NONE;
+ break;
+ case EFX_FCNTL_RESPOND:
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ break;
+ case EFX_FCNTL_GENERATE:
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ break;
+ case (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE):
+ fc_conf->mode = RTE_FC_FULL;
+ break;
+ default:
+ sfc_err(sa, "%s: unexpected flow control value %#x",
+ __func__, link_fc);
+ }
+
+ fc_conf->autoneg = sa->port.flow_ctrl_autoneg;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+
+static int
+sfc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ unsigned int fcntl;
+ int rc;
+
+ if (fc_conf->high_water != 0 || fc_conf->low_water != 0 ||
+ fc_conf->pause_time != 0 || fc_conf->send_xon != 0 ||
+ fc_conf->mac_ctrl_frame_fwd != 0) {
+ sfc_err(sa, "unsupported flow control settings specified");
+ rc = EINVAL;
+ goto fail_inval;
+ }
+
+ switch (fc_conf->mode) {
+ case RTE_FC_NONE:
+ fcntl = 0;
+ break;
+ case RTE_FC_RX_PAUSE:
+ fcntl = EFX_FCNTL_RESPOND;
+ break;
+ case RTE_FC_TX_PAUSE:
+ fcntl = EFX_FCNTL_GENERATE;
+ break;
+ case RTE_FC_FULL:
+ fcntl = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+ break;
+ default:
+ rc = EINVAL;
+ goto fail_inval;
+ }
+
+ sfc_adapter_lock(sa);
+
+ if (sa->state == SFC_ADAPTER_STARTED) {
+ rc = efx_mac_fcntl_set(sa->nic, fcntl, fc_conf->autoneg);
+ if (rc != 0)
+ goto fail_mac_fcntl_set;
+ }
+
+ port->flow_ctrl = fcntl;
+ port->flow_ctrl_autoneg = fc_conf->autoneg;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+
+fail_mac_fcntl_set:
+ sfc_adapter_unlock(sa);
+fail_inval:
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -467,6 +563,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.rx_queue_release = sfc_rx_queue_release,
.tx_queue_setup = sfc_tx_queue_setup,
.tx_queue_release = sfc_tx_queue_release,
+ .flow_ctrl_get = sfc_flow_ctrl_get,
+ .flow_ctrl_set = sfc_flow_ctrl_set,
};
static int
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index d8ff097..ccc0854 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -79,6 +79,13 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_port_init;
+ sfc_log_init(sa, "set flow control to %#x autoneg=%u",
+ port->flow_ctrl, port->flow_ctrl_autoneg);
+ rc = efx_mac_fcntl_set(sa->nic, port->flow_ctrl,
+ port->flow_ctrl_autoneg);
+ if (rc != 0)
+ goto fail_mac_fcntl_set;
+
sfc_log_init(sa, "set MAC PDU %u", (unsigned int)port->pdu);
rc = efx_mac_pdu_set(sa->nic, port->pdu);
if (rc != 0)
@@ -124,6 +131,7 @@ sfc_port_start(struct sfc_adapter *sa)
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
+fail_mac_fcntl_set:
efx_port_fini(sa->nic);
fail_port_init:
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 06/31] net/sfc: support link status change interrupt
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (4 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 05/31] net/sfc: support flow control settings get/set Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 07/31] net/sfc: implement device operation to change MTU Andrew Rybchenko
` (26 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 4 +-
drivers/net/sfc/sfc.c | 4 +-
drivers/net/sfc/sfc.h | 4 +
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_ev.c | 30 +++++-
drivers/net/sfc/sfc_intr.c | 204 +++++++++++++++++++++++++++++++++++
7 files changed, 242 insertions(+), 6 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 25472f8..693d35e 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -5,6 +5,7 @@
;
[Features]
Link status = Y
+Link status event = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 1cfed6a..94eedd1 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -44,7 +44,7 @@ SFC EFX PMD has support for:
- Multiple transmit and receive queues
-- Link state information
+- Link state information including link status change interrupt
- IPv4/IPv6 TCP/UDP transmit checksum offload
@@ -58,8 +58,6 @@ Non-supported Features
The features not yet supported include:
-- Link status change interrupt
-
- Receive queue interupts
- Priority-based flow control
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index ef9e0d4..36044a0 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -116,7 +116,9 @@ sfc_check_conf(struct sfc_adapter *sa)
rc = EINVAL;
}
- if (conf->intr_conf.lsc != 0) {
+ if ((conf->intr_conf.lsc != 0) &&
+ (sa->intr.type != EFX_INTR_LINE) &&
+ (sa->intr.type != EFX_INTR_MESSAGE)) {
sfc_err(sa, "Link status change interrupt not supported");
rc = EINVAL;
}
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 1189283..257622f 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -112,6 +112,8 @@ struct sfc_mcdi {
struct sfc_intr {
efx_intr_type_t type;
+ rte_intr_callback_fn handler;
+ boolean_t lsc_intr;
};
struct sfc_evq_info;
@@ -119,6 +121,8 @@ struct sfc_rxq_info;
struct sfc_txq_info;
struct sfc_port {
+ unsigned int lsc_seq;
+
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index eff648b..8c46500 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -682,6 +682,7 @@ static struct eth_driver sfc_efx_pmd = {
.pci_drv = {
.id_table = pci_id_sfc_efx_map,
.drv_flags =
+ RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index 34c1127..c8a2d23 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -286,11 +286,25 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
struct sfc_adapter *sa = evq->sa;
struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
struct rte_eth_link new_link;
+ uint64_t new_link_u64;
+ uint64_t old_link_u64;
EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
sfc_port_link_mode_to_info(link_mode, &new_link);
- rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link);
+
+ new_link_u64 = *(uint64_t *)&new_link;
+ do {
+ old_link_u64 = rte_atomic64_read((rte_atomic64_t *)dev_link);
+ if (old_link_u64 == new_link_u64)
+ break;
+
+ if (rte_atomic64_cmpset((volatile uint64_t *)dev_link,
+ old_link_u64, new_link_u64)) {
+ evq->sa->port.lsc_seq++;
+ break;
+ }
+ } while (B_TRUE);
return B_FALSE;
}
@@ -481,6 +495,12 @@ sfc_ev_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mgmt_evq_start;
+ if (sa->intr.lsc_intr) {
+ rc = sfc_ev_qprime(sa->evq_info[sa->mgmt_evq_index].evq);
+ if (rc != 0)
+ goto fail_evq0_prime;
+ }
+
rte_spinlock_unlock(&sa->mgmt_evq_lock);
/*
@@ -498,6 +518,9 @@ sfc_ev_start(struct sfc_adapter *sa)
return 0;
+fail_evq0_prime:
+ sfc_ev_qstop(sa, 0);
+
fail_mgmt_evq_start:
rte_spinlock_unlock(&sa->mgmt_evq_lock);
efx_ev_fini(sa->nic);
@@ -599,7 +622,10 @@ sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
SFC_ASSERT(rte_is_power_of_2(max_entries));
evq_info->max_entries = max_entries;
- evq_info->flags = sa->evq_flags | EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+ evq_info->flags = sa->evq_flags |
+ ((sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index) ?
+ EFX_EVQ_FLAGS_NOTIFY_INTERRUPT :
+ EFX_EVQ_FLAGS_NOTIFY_DISABLED);
return 0;
}
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index 1b7dcdd..e0b1693 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -27,10 +27,130 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * At the momemt of writing DPDK v16.07 has notion of two types of
+ * interrupts: LSC (link status change) and RXQ (receive indication).
+ * It allows to register interrupt callback for entire device which is
+ * not intended to be used for receive indication (i.e. link status
+ * change indication only). The handler has no information which HW
+ * interrupt has triggered it, so we don't know which event queue should
+ * be polled/reprimed (except qmask in the case of legacy line interrupt).
+ */
+
+#include <rte_common.h>
+#include <rte_interrupts.h>
+
#include "efx.h"
#include "sfc.h"
#include "sfc_log.h"
+#include "sfc_ev.h"
+
+static void
+sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa)
+{
+ struct sfc_evq *evq;
+
+ rte_spinlock_lock(&sa->mgmt_evq_lock);
+
+ evq = sa->evq_info[sa->mgmt_evq_index].evq;
+
+ if (evq->init_state != SFC_EVQ_STARTED) {
+ sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index);
+ } else {
+ sfc_ev_qpoll(evq);
+
+ if (sfc_ev_qprime(evq) != 0)
+ sfc_err(sa, "cannot prime EVQ %u", evq->evq_index);
+ }
+
+ rte_spinlock_unlock(&sa->mgmt_evq_lock);
+}
+
+static void
+sfc_intr_line_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg;
+ efx_nic_t *enp = sa->nic;
+ boolean_t fatal;
+ uint32_t qmask;
+ unsigned int lsc_seq = sa->port.lsc_seq;
+
+ sfc_log_init(sa, "entry");
+
+ if (sa->state != SFC_ADAPTER_STARTED &&
+ sa->state != SFC_ADAPTER_STARTING &&
+ sa->state != SFC_ADAPTER_STOPPING) {
+ sfc_log_init(sa,
+ "interrupt on stopped adapter, don't reenable");
+ goto exit;
+ }
+
+ efx_intr_status_line(enp, &fatal, &qmask);
+ if (fatal) {
+ (void)efx_intr_disable(enp);
+ (void)efx_intr_fatal(enp);
+ sfc_err(sa, "fatal, interrupts disabled");
+ goto exit;
+ }
+
+ if (qmask & (1 << sa->mgmt_evq_index))
+ sfc_intr_handle_mgmt_evq(sa);
+
+ if (rte_intr_enable(intr_handle) != 0)
+ sfc_err(sa, "cannot reenable interrupts");
+
+ sfc_log_init(sa, "done");
+
+exit:
+ if (lsc_seq != sa->port.lsc_seq) {
+ sfc_info(sa, "link status change event: link %s",
+ sa->eth_dev->data->dev_link.link_status ?
+ "UP" : "DOWN");
+ _rte_eth_dev_callback_process(sa->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC, NULL);
+ }
+}
+
+static void
+sfc_intr_message_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg;
+ efx_nic_t *enp = sa->nic;
+ boolean_t fatal;
+ unsigned int lsc_seq = sa->port.lsc_seq;
+
+ sfc_log_init(sa, "entry");
+
+ if (sa->state != SFC_ADAPTER_STARTED &&
+ sa->state != SFC_ADAPTER_STARTING &&
+ sa->state != SFC_ADAPTER_STOPPING) {
+ sfc_log_init(sa, "adapter not-started, don't reenable");
+ goto exit;
+ }
+
+ efx_intr_status_message(enp, sa->mgmt_evq_index, &fatal);
+ if (fatal) {
+ (void)efx_intr_disable(enp);
+ (void)efx_intr_fatal(enp);
+ sfc_err(sa, "fatal, interrupts disabled");
+ goto exit;
+ }
+
+ sfc_intr_handle_mgmt_evq(sa);
+
+ if (rte_intr_enable(intr_handle) != 0)
+ sfc_err(sa, "cannot reenable interrupts");
+
+ sfc_log_init(sa, "done");
+
+exit:
+ if (lsc_seq != sa->port.lsc_seq) {
+ sfc_info(sa, "link status change event");
+ _rte_eth_dev_callback_process(sa->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC, NULL);
+ }
+}
int
sfc_intr_start(struct sfc_adapter *sa)
@@ -54,11 +174,49 @@ sfc_intr_start(struct sfc_adapter *sa)
intr_handle = &sa->eth_dev->pci_dev->intr_handle;
+ if (intr->handler != NULL) {
+ sfc_log_init(sa, "rte_intr_callback_register");
+ rc = rte_intr_callback_register(intr_handle, intr->handler,
+ (void *)sa);
+ if (rc != 0) {
+ sfc_err(sa,
+ "cannot register interrupt handler (rc=%d)",
+ rc);
+ /*
+ * Convert error code from negative returned by RTE API
+ * to positive used in the driver.
+ */
+ rc = -rc;
+ goto fail_rte_intr_cb_reg;
+ }
+
+ sfc_log_init(sa, "rte_intr_enable");
+ rc = rte_intr_enable(intr_handle);
+ if (rc != 0) {
+ sfc_err(sa, "cannot enable interrupts (rc=%d)", rc);
+ /*
+ * Convert error code from negative returned by RTE API
+ * to positive used in the driver.
+ */
+ rc = -rc;
+ goto fail_rte_intr_enable;
+ }
+
+ sfc_log_init(sa, "efx_intr_enable");
+ efx_intr_enable(sa->nic);
+ }
+
sfc_log_init(sa, "done type=%u max_intr=%d nb_efd=%u vec=%p",
intr_handle->type, intr_handle->max_intr,
intr_handle->nb_efd, intr_handle->intr_vec);
return 0;
+fail_rte_intr_enable:
+ rte_intr_callback_unregister(intr_handle, intr->handler, (void *)sa);
+
+fail_rte_intr_cb_reg:
+ efx_intr_fini(sa->nic);
+
fail_intr_init:
sfc_log_init(sa, "failed %d", rc);
return rc;
@@ -67,8 +225,29 @@ sfc_intr_start(struct sfc_adapter *sa)
void
sfc_intr_stop(struct sfc_adapter *sa)
{
+ struct sfc_intr *intr = &sa->intr;
+
sfc_log_init(sa, "entry");
+ if (intr->handler != NULL) {
+ struct rte_intr_handle *intr_handle;
+ int rc;
+
+ efx_intr_disable(sa->nic);
+
+ intr_handle = &sa->eth_dev->pci_dev->intr_handle;
+ if (rte_intr_disable(intr_handle) != 0)
+ sfc_err(sa, "cannot disable interrupts");
+
+ while ((rc = rte_intr_callback_unregister(intr_handle,
+ intr->handler, (void *)sa)) == -EAGAIN)
+ ;
+ if (rc != 1)
+ sfc_err(sa,
+ "cannot unregister interrupt handler %d",
+ rc);
+ }
+
efx_intr_fini(sa->nic);
sfc_log_init(sa, "done");
@@ -77,8 +256,33 @@ sfc_intr_stop(struct sfc_adapter *sa)
int
sfc_intr_init(struct sfc_adapter *sa)
{
+ struct sfc_intr *intr = &sa->intr;
+
sfc_log_init(sa, "entry");
+ intr->handler = NULL;
+ intr->lsc_intr = (sa->eth_dev->data->dev_conf.intr_conf.lsc != 0);
+ if (!intr->lsc_intr) {
+ sfc_info(sa, "LSC tracking using interrupts is disabled");
+ goto done;
+ }
+
+ switch (intr->type) {
+ case EFX_INTR_MESSAGE:
+ intr->handler = sfc_intr_message_handler;
+ break;
+ case EFX_INTR_LINE:
+ intr->handler = sfc_intr_line_handler;
+ break;
+ case EFX_INTR_INVALID:
+ sfc_warn(sa, "interrupts are not supported");
+ break;
+ default:
+ sfc_panic(sa, "unexpected EFX interrupt type %u\n", intr->type);
+ break;
+ }
+
+done:
sfc_log_init(sa, "done");
return 0;
}
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 07/31] net/sfc: implement device operation to change MTU
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (5 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 06/31] net/sfc: support link status change interrupt Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 08/31] net/sfc: support link speed and duplex settings Andrew Rybchenko
` (25 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 ++
doc/guides/nics/sfc_efx.rst | 4 +++
drivers/net/sfc/sfc_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 693d35e..a845bfc 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -6,6 +6,8 @@
[Features]
Link status = Y
Link status event = Y
+MTU update = Y
+Jumbo frame = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 94eedd1..adab9fd 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -52,6 +52,10 @@ SFC EFX PMD has support for:
- Basic flow control
+- MTU update
+
+- Jumbo frames up to 9K
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 8c46500..6690755 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -549,6 +549,72 @@ sfc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
return -rc;
}
+static int
+sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ size_t pdu = EFX_MAC_PDU(mtu);
+ size_t old_pdu;
+ int rc;
+
+ sfc_log_init(sa, "mtu=%u", mtu);
+
+ rc = EINVAL;
+ if (pdu < EFX_MAC_PDU_MIN) {
+ sfc_err(sa, "too small MTU %u (PDU size %u less than min %u)",
+ (unsigned int)mtu, (unsigned int)pdu,
+ EFX_MAC_PDU_MIN);
+ goto fail_inval;
+ }
+ if (pdu > EFX_MAC_PDU_MAX) {
+ sfc_err(sa, "too big MTU %u (PDU size %u greater than max %u)",
+ (unsigned int)mtu, (unsigned int)pdu,
+ EFX_MAC_PDU_MAX);
+ goto fail_inval;
+ }
+
+ sfc_adapter_lock(sa);
+
+ if (pdu != sa->port.pdu) {
+ if (sa->state == SFC_ADAPTER_STARTED) {
+ sfc_stop(sa);
+
+ old_pdu = sa->port.pdu;
+ sa->port.pdu = pdu;
+ rc = sfc_start(sa);
+ if (rc != 0)
+ goto fail_start;
+ } else {
+ sa->port.pdu = pdu;
+ }
+ }
+
+ /*
+ * The driver does not use it, but other PMDs update jumbo_frame
+ * flag and max_rx_pkt_len when MTU is set.
+ */
+ dev->data->dev_conf.rxmode.jumbo_frame = (mtu > ETHER_MAX_LEN);
+ dev->data->dev_conf.rxmode.max_rx_pkt_len = sa->port.pdu;
+
+ sfc_adapter_unlock(sa);
+
+ sfc_log_init(sa, "done");
+ return 0;
+
+fail_start:
+ sa->port.pdu = old_pdu;
+ if (sfc_start(sa) != 0)
+ sfc_err(sa, "cannot start with neither new (%u) nor old (%u) "
+ "PDU max size - port is stopped",
+ (unsigned int)pdu, (unsigned int)old_pdu);
+ sfc_adapter_unlock(sa);
+
+fail_inval:
+ sfc_log_init(sa, "failed %d", rc);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -559,6 +625,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.xstats_get = sfc_xstats_get,
.xstats_get_names = sfc_xstats_get_names,
.dev_infos_get = sfc_dev_infos_get,
+ .mtu_set = sfc_dev_set_mtu,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.tx_queue_setup = sfc_tx_queue_setup,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 08/31] net/sfc: support link speed and duplex settings
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (6 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 07/31] net/sfc: implement device operation to change MTU Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 09/31] net/sfc: support link up/down Andrew Rybchenko
` (24 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/sfc.c | 38 ++++++++++++++++++++++++++++++++++--
drivers/net/sfc/sfc.h | 3 +++
drivers/net/sfc/sfc_ethdev.c | 9 +++++++++
drivers/net/sfc/sfc_port.c | 6 ++++++
5 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index a845bfc..60ecca0 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Speed capabilities = Y
Link status = Y
Link status event = Y
MTU update = Y
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 36044a0..e2e6c9e 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -85,6 +85,33 @@ sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp)
memset(esmp, 0, sizeof(*esmp));
}
+static uint32_t
+sfc_phy_cap_from_link_speeds(uint32_t speeds)
+{
+ uint32_t phy_caps = 0;
+
+ if (~speeds & ETH_LINK_SPEED_FIXED) {
+ phy_caps |= (1 << EFX_PHY_CAP_AN);
+ /*
+ * If no speeds are specified in the mask, any supported
+ * may be negotiated
+ */
+ if (speeds == ETH_LINK_SPEED_AUTONEG)
+ phy_caps |=
+ (1 << EFX_PHY_CAP_1000FDX) |
+ (1 << EFX_PHY_CAP_10000FDX) |
+ (1 << EFX_PHY_CAP_40000FDX);
+ }
+ if (speeds & ETH_LINK_SPEED_1G)
+ phy_caps |= (1 << EFX_PHY_CAP_1000FDX);
+ if (speeds & ETH_LINK_SPEED_10G)
+ phy_caps |= (1 << EFX_PHY_CAP_10000FDX);
+ if (speeds & ETH_LINK_SPEED_40G)
+ phy_caps |= (1 << EFX_PHY_CAP_40000FDX);
+
+ return phy_caps;
+}
+
/*
* Check requested device level configuration.
* Receive and transmit configuration is checked in corresponding
@@ -96,8 +123,12 @@ sfc_check_conf(struct sfc_adapter *sa)
const struct rte_eth_conf *conf = &sa->eth_dev->data->dev_conf;
int rc = 0;
- if (conf->link_speeds != ETH_LINK_SPEED_AUTONEG) {
- sfc_err(sa, "Manual link speed/duplex choice not supported");
+ sa->port.phy_adv_cap =
+ sfc_phy_cap_from_link_speeds(conf->link_speeds) &
+ sa->port.phy_adv_cap_mask;
+ if ((sa->port.phy_adv_cap & ~(1 << EFX_PHY_CAP_AN)) == 0) {
+ sfc_err(sa, "No link speeds from mask %#x are supported",
+ conf->link_speeds);
rc = EINVAL;
}
@@ -516,6 +547,9 @@ sfc_attach(struct sfc_adapter *sa)
if (rc != 0)
goto fail_intr_attach;
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
+ &sa->port.phy_adv_cap_mask);
+
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 257622f..5883547 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -123,6 +123,9 @@ struct sfc_txq_info;
struct sfc_port {
unsigned int lsc_seq;
+ uint32_t phy_adv_cap_mask;
+ uint32_t phy_adv_cap;
+
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6690755..42c488e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -53,6 +53,15 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
+ /* Autonegotiation may be disabled */
+ dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
+ if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_1000FDX)
+ dev_info->speed_capa |= ETH_LINK_SPEED_1G;
+ if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_10000FDX)
+ dev_info->speed_capa |= ETH_LINK_SPEED_10G;
+ if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_40000FDX)
+ dev_info->speed_capa |= ETH_LINK_SPEED_40G;
+
dev_info->max_rx_queues = sa->rxq_max;
dev_info->max_tx_queues = sa->txq_max;
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index ccc0854..1241af7 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -86,6 +86,11 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mac_fcntl_set;
+ sfc_log_init(sa, "set phy adv caps to %#x", port->phy_adv_cap);
+ rc = efx_phy_adv_cap_set(sa->nic, port->phy_adv_cap);
+ if (rc != 0)
+ goto fail_phy_adv_cap_set;
+
sfc_log_init(sa, "set MAC PDU %u", (unsigned int)port->pdu);
rc = efx_mac_pdu_set(sa->nic, port->pdu);
if (rc != 0)
@@ -131,6 +136,7 @@ sfc_port_start(struct sfc_adapter *sa)
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
+fail_phy_adv_cap_set:
fail_mac_fcntl_set:
efx_port_fini(sa->nic);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 09/31] net/sfc: support link up/down
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (7 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 08/31] net/sfc: support link speed and duplex settings Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 10/31] net/sfc: support promiscuous and all-multicast control Andrew Rybchenko
` (23 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Artem Andreev
From: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 42c488e..1716d78 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -195,6 +195,36 @@ sfc_dev_stop(struct rte_eth_dev *dev)
sfc_log_init(sa, "done");
}
+static int
+sfc_dev_set_link_up(struct rte_eth_dev *dev)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "entry");
+
+ sfc_adapter_lock(sa);
+ rc = sfc_start(sa);
+ sfc_adapter_unlock(sa);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
+}
+
+static int
+sfc_dev_set_link_down(struct rte_eth_dev *dev)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "entry");
+
+ sfc_adapter_lock(sa);
+ sfc_stop(sa);
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+
static void
sfc_dev_close(struct rte_eth_dev *dev)
{
@@ -628,6 +658,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
.dev_stop = sfc_dev_stop,
+ .dev_set_link_up = sfc_dev_set_link_up,
+ .dev_set_link_down = sfc_dev_set_link_down,
.dev_close = sfc_dev_close,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 10/31] net/sfc: support promiscuous and all-multicast control
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (8 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 09/31] net/sfc: support link up/down Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 11/31] net/sfc: support main (the first) MAC address change Andrew Rybchenko
` (22 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 ++
doc/guides/nics/sfc_efx.rst | 4 +++
drivers/net/sfc/sfc.h | 11 +++++++
drivers/net/sfc/sfc_ethdev.c | 57 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 18 +++++++++++-
5 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 60ecca0..aaea993 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -9,6 +9,8 @@ Link status = Y
Link status event = Y
MTU update = Y
Jumbo frame = Y
+Promiscuous mode = Y
+Allmulticast mode = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index adab9fd..360ed98 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -56,6 +56,10 @@ SFC EFX PMD has support for:
- Jumbo frames up to 9K
+- Promiscuous mode
+
+- Allmulticast mode
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 5883547..f0bbaf8 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -93,6 +93,13 @@ enum sfc_adapter_state {
SFC_ADAPTER_NSTATES
};
+enum sfc_dev_filter_mode {
+ SFC_DEV_FILTER_MODE_PROMISC = 0,
+ SFC_DEV_FILTER_MODE_ALLMULTI,
+
+ SFC_DEV_FILTER_NMODES
+};
+
enum sfc_mcdi_state {
SFC_MCDI_UNINITIALIZED = 0,
SFC_MCDI_INITIALIZED,
@@ -130,6 +137,9 @@ struct sfc_port {
boolean_t flow_ctrl_autoneg;
size_t pdu;
+ boolean_t promisc;
+ boolean_t allmulti;
+
rte_spinlock_t mac_stats_lock;
uint64_t *mac_stats_buf;
efsys_mem_t mac_stats_dma_mem;
@@ -243,6 +253,7 @@ void sfc_port_stop(struct sfc_adapter *sa);
void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info);
int sfc_port_update_mac_stats(struct sfc_adapter *sa);
+int sfc_set_rx_mode(struct sfc_adapter *sa);
#ifdef __cplusplus
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1716d78..c6095ad 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -253,6 +253,59 @@ sfc_dev_close(struct rte_eth_dev *dev)
sfc_log_init(sa, "done");
}
+static void
+sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
+ boolean_t enabled)
+{
+ struct sfc_port *port;
+ boolean_t *toggle;
+ struct sfc_adapter *sa = dev->data->dev_private;
+ boolean_t allmulti = (mode == SFC_DEV_FILTER_MODE_ALLMULTI);
+ const char *desc = (allmulti) ? "all-multi" : "promiscuous";
+
+ sfc_adapter_lock(sa);
+
+ port = &sa->port;
+ toggle = (allmulti) ? (&port->allmulti) : (&port->promisc);
+
+ if (*toggle != enabled) {
+ *toggle = enabled;
+
+ if ((sa->state == SFC_ADAPTER_STARTED) &&
+ (sfc_set_rx_mode(sa) != 0)) {
+ *toggle = !(enabled);
+ sfc_warn(sa, "Failed to %s %s mode",
+ ((enabled) ? "enable" : "disable"), desc);
+ }
+ }
+
+ sfc_adapter_unlock(sa);
+}
+
+static void
+sfc_dev_promisc_enable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
+}
+
+static void
+sfc_dev_promisc_disable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
+}
+
+static void
+sfc_dev_allmulti_enable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_TRUE);
+}
+
+static void
+sfc_dev_allmulti_disable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_FALSE);
+}
+
static int
sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
uint16_t nb_rx_desc, unsigned int socket_id,
@@ -661,6 +714,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_set_link_up = sfc_dev_set_link_up,
.dev_set_link_down = sfc_dev_set_link_down,
.dev_close = sfc_dev_close,
+ .promiscuous_enable = sfc_dev_promisc_enable,
+ .promiscuous_disable = sfc_dev_promisc_disable,
+ .allmulticast_enable = sfc_dev_allmulti_enable,
+ .allmulticast_disable = sfc_dev_allmulti_disable,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
.xstats_get = sfc_xstats_get,
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 1241af7..dc6ecdf 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -103,7 +103,11 @@ sfc_port_start(struct sfc_adapter *sa)
goto fail_mac_addr_set;
sfc_log_init(sa, "set MAC filters");
- rc = efx_mac_filter_set(sa->nic, B_TRUE, B_TRUE, B_TRUE, B_TRUE);
+ port->promisc = (sa->eth_dev->data->promiscuous != 0) ?
+ B_TRUE : B_FALSE;
+ port->allmulti = (sa->eth_dev->data->all_multicast != 0) ?
+ B_TRUE : B_FALSE;
+ rc = sfc_set_rx_mode(sa);
if (rc != 0)
goto fail_mac_filter_set;
@@ -219,6 +223,18 @@ sfc_port_fini(struct sfc_adapter *sa)
sfc_log_init(sa, "done");
}
+int
+sfc_set_rx_mode(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ int rc;
+
+ rc = efx_mac_filter_set(sa->nic, port->promisc, B_TRUE,
+ port->promisc || port->allmulti, B_TRUE);
+
+ return rc;
+}
+
void
sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info)
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 11/31] net/sfc: support main (the first) MAC address change
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (9 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 10/31] net/sfc: support promiscuous and all-multicast control Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 12/31] net/sfc: support multicast addresses list controls Andrew Rybchenko
` (21 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c6095ad..79e2761 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -706,6 +706,58 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
SFC_ASSERT(rc > 0);
return -rc;
}
+static void
+sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+ int rc;
+
+ sfc_adapter_lock(sa);
+
+ if (sa->state != SFC_ADAPTER_STARTED) {
+ sfc_info(sa, "the port is not started");
+ sfc_info(sa, "the new MAC address will be set on port start");
+
+ goto unlock;
+ }
+
+ if (encp->enc_allow_set_mac_with_installed_filters) {
+ rc = efx_mac_addr_set(sa->nic, mac_addr->addr_bytes);
+ if (rc != 0) {
+ sfc_err(sa, "cannot set MAC address (rc = %u)", rc);
+ goto unlock;
+ }
+
+ /*
+ * Changing the MAC address by means of MCDI request
+ * has no effect on received traffic, therefore
+ * we also need to update unicast filters
+ */
+ rc = sfc_set_rx_mode(sa);
+ if (rc != 0)
+ sfc_err(sa, "cannot set filter (rc = %u)", rc);
+ } else {
+ sfc_warn(sa, "cannot set MAC address with filters installed");
+ sfc_warn(sa, "adapter will be restarted to pick the new MAC");
+ sfc_warn(sa, "(some traffic may be dropped)");
+
+ /*
+ * Since setting MAC address with filters installed is not
+ * allowed on the adapter, one needs to simply restart adapter
+ * so that the new MAC address will be taken from an outer
+ * storage and set flawlessly by means of sfc_start() call
+ */
+ sfc_stop(sa);
+ rc = sfc_start(sa);
+ if (rc != 0)
+ sfc_err(sa, "cannot restart adapter (rc = %u)", rc);
+ }
+
+unlock:
+ sfc_adapter_unlock(sa);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
@@ -730,6 +782,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.tx_queue_release = sfc_tx_queue_release,
.flow_ctrl_get = sfc_flow_ctrl_get,
.flow_ctrl_set = sfc_flow_ctrl_set,
+ .mac_addr_set = sfc_mac_addr_set,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 12/31] net/sfc: support multicast addresses list controls
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (10 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 11/31] net/sfc: support main (the first) MAC address change Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 13/31] net/sfc: support checksum offloads on receive Andrew Rybchenko
` (20 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 40 ++++++++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index aaea993..35633cb 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -11,6 +11,7 @@ MTU update = Y
Jumbo frame = Y
Promiscuous mode = Y
Allmulticast mode = Y
+Multicast MAC filter = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 360ed98..529928d 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -60,6 +60,8 @@ SFC EFX PMD has support for:
- Allmulticast mode
+- Multicast MAC filter
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 79e2761..268b76a 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -759,6 +759,45 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
}
+static int
+sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ uint8_t *mc_addrs_p;
+ uint8_t *mc_addrs;
+ int rc;
+ unsigned int i;
+
+ if (nb_mc_addr > EFX_MAC_MULTICAST_LIST_MAX) {
+ sfc_err(sa, "too many multicast addresses: %u > %u",
+ nb_mc_addr, EFX_MAC_MULTICAST_LIST_MAX);
+ return -EINVAL;
+ }
+
+ mc_addrs_p = rte_calloc("mc-addrs", nb_mc_addr, EFX_MAC_ADDR_LEN, 0);
+ if (mc_addrs_p == NULL)
+ return -ENOMEM;
+
+ mc_addrs = mc_addrs_p;
+
+ for (i = 0; i < nb_mc_addr; ++i) {
+ (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes,
+ EFX_MAC_ADDR_LEN);
+ mc_addrs += EFX_MAC_ADDR_LEN;
+ }
+
+ rc = efx_mac_multicast_list_set(sa->nic, mc_addrs_p, nb_mc_addr);
+
+ rte_free(mc_addrs_p);
+
+ if (rc != 0)
+ sfc_err(sa, "cannot set multicast address list (rc = %u)", rc);
+
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -783,6 +822,7 @@ 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,
+ .set_mc_addr_list = sfc_set_mc_addr_list,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 13/31] net/sfc: support checksum offloads on receive
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (11 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 12/31] net/sfc: support multicast addresses list controls Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 14/31] net/sfc: handle received packet type info provided by HW Andrew Rybchenko
` (19 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
IPv4 header and TCP/UDP checksums for both IPv4 and IPv6 are supported.
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 4 ++--
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 5 +++++
drivers/net/sfc/sfc_rx.c | 40 ++++++++++++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 35633cb..ec1d1db 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -13,8 +13,8 @@ Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
Flow control = Y
-L3 checksum offload = P
-L4 checksum offload = P
+L3 checksum offload = Y
+L4 checksum offload = Y
Basic stats = Y
Extended stats = Y
BSD nic_uio = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 529928d..452a9ff 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -62,6 +62,8 @@ SFC EFX PMD has support for:
- Multicast MAC filter
+- IPv4/IPv6 TCP/UDP receive checksum offload
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 268b76a..235582d 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -68,6 +68,11 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
/* By default packets are dropped if no descriptors are available */
dev_info->default_rxconf.rx_drop_en = 1;
+ dev_info->rx_offload_capa =
+ DEV_RX_OFFLOAD_IPV4_CKSUM |
+ DEV_RX_OFFLOAD_UDP_CKSUM |
+ DEV_RX_OFFLOAD_TCP_CKSUM;
+
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_IPV4_CKSUM |
DEV_TX_OFFLOAD_UDP_CKSUM |
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index bd41131..4df4132 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -130,6 +130,45 @@ sfc_rx_qrefill(struct sfc_rxq *rxq)
}
}
+static uint64_t
+sfc_rx_desc_flags_to_offload_flags(const unsigned int desc_flags)
+{
+ uint64_t mbuf_flags = 0;
+
+ switch (desc_flags & (EFX_PKT_IPV4 | EFX_CKSUM_IPV4)) {
+ case (EFX_PKT_IPV4 | EFX_CKSUM_IPV4):
+ mbuf_flags |= PKT_RX_IP_CKSUM_GOOD;
+ break;
+ case EFX_PKT_IPV4:
+ mbuf_flags |= PKT_RX_IP_CKSUM_BAD;
+ break;
+ default:
+ RTE_BUILD_BUG_ON(PKT_RX_IP_CKSUM_UNKNOWN != 0);
+ SFC_ASSERT((mbuf_flags & PKT_RX_IP_CKSUM_MASK) ==
+ PKT_RX_IP_CKSUM_UNKNOWN);
+ break;
+ }
+
+ switch ((desc_flags &
+ (EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP))) {
+ case (EFX_PKT_TCP | EFX_CKSUM_TCPUDP):
+ case (EFX_PKT_UDP | EFX_CKSUM_TCPUDP):
+ mbuf_flags |= PKT_RX_L4_CKSUM_GOOD;
+ break;
+ case EFX_PKT_TCP:
+ case EFX_PKT_UDP:
+ mbuf_flags |= PKT_RX_L4_CKSUM_BAD;
+ break;
+ default:
+ RTE_BUILD_BUG_ON(PKT_RX_L4_CKSUM_UNKNOWN != 0);
+ SFC_ASSERT((mbuf_flags & PKT_RX_L4_CKSUM_MASK) ==
+ PKT_RX_L4_CKSUM_UNKNOWN);
+ break;
+ }
+
+ return mbuf_flags;
+}
+
uint16_t
sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
@@ -182,6 +221,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_data_len(m) = seg_len;
rte_pktmbuf_pkt_len(m) = seg_len;
+ m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
m->packet_type = RTE_PTYPE_L2_ETHER;
*rx_pkts++ = m;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 14/31] net/sfc: handle received packet type info provided by HW
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (12 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 13/31] net/sfc: support checksum offloads on receive Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 15/31] net/sfc: support callback to get receive queue information Andrew Rybchenko
` (18 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 19 +++++++++++++++++++
drivers/net/sfc/sfc_rx.c | 14 +++++++++++++-
4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index ec1d1db..b5887d5 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -15,6 +15,7 @@ Multicast MAC filter = Y
Flow control = Y
L3 checksum offload = Y
L4 checksum offload = Y
+Packet type parsing = Y
Basic stats = Y
Extended stats = Y
BSD nic_uio = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 452a9ff..57e8318 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -64,6 +64,8 @@ SFC EFX PMD has support for:
- IPv4/IPv6 TCP/UDP receive checksum offload
+- Received packet type information
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 235582d..03c9a01 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -97,6 +97,24 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
}
+static const uint32_t *
+sfc_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+ static const uint32_t ptypes[] = {
+ RTE_PTYPE_L2_ETHER,
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+ RTE_PTYPE_L4_TCP,
+ RTE_PTYPE_L4_UDP,
+ RTE_PTYPE_UNKNOWN
+ };
+
+ if (dev->rx_pkt_burst == sfc_recv_pkts)
+ return ptypes;
+
+ return NULL;
+}
+
static int
sfc_dev_configure(struct rte_eth_dev *dev)
{
@@ -819,6 +837,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.xstats_get = sfc_xstats_get,
.xstats_get_names = sfc_xstats_get_names,
.dev_infos_get = sfc_dev_infos_get,
+ .dev_supported_ptypes_get = sfc_dev_supported_ptypes_get,
.mtu_set = sfc_dev_set_mtu,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 4df4132..be8fa23 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -169,6 +169,18 @@ sfc_rx_desc_flags_to_offload_flags(const unsigned int desc_flags)
return mbuf_flags;
}
+static uint32_t
+sfc_rx_desc_flags_to_packet_type(const unsigned int desc_flags)
+{
+ return RTE_PTYPE_L2_ETHER |
+ ((desc_flags & EFX_PKT_IPV4) ?
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN : 0) |
+ ((desc_flags & EFX_PKT_IPV6) ?
+ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN : 0) |
+ ((desc_flags & EFX_PKT_TCP) ? RTE_PTYPE_L4_TCP : 0) |
+ ((desc_flags & EFX_PKT_UDP) ? RTE_PTYPE_L4_UDP : 0);
+}
+
uint16_t
sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
@@ -222,7 +234,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_pkt_len(m) = seg_len;
m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
- m->packet_type = RTE_PTYPE_L2_ETHER;
+ m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
*rx_pkts++ = m;
done_pkts++;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 15/31] net/sfc: support callback to get receive queue information
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (13 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 14/31] net/sfc: handle received packet type info provided by HW Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 16/31] net/sfc: support Rx free threshold Andrew Rybchenko
` (17 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 03c9a01..e67ca61 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -821,6 +821,29 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
return -rc;
}
+static void
+sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+ struct rte_eth_rxq_info *qinfo)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_rxq_info *rxq_info;
+ struct sfc_rxq *rxq;
+
+ sfc_adapter_lock(sa);
+
+ SFC_ASSERT(rx_queue_id < sa->rxq_count);
+
+ rxq_info = &sa->rxq_info[rx_queue_id];
+ rxq = rxq_info->rxq;
+ SFC_ASSERT(rxq != NULL);
+
+ qinfo->mp = rxq->refill_mb_pool;
+ qinfo->conf.rx_drop_en = 1;
+ qinfo->nb_desc = rxq_info->entries;
+
+ sfc_adapter_unlock(sa);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -847,6 +870,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
.set_mc_addr_list = sfc_set_mc_addr_list,
+ .rxq_info_get = sfc_rx_queue_info_get,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 16/31] net/sfc: support Rx free threshold
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (14 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 15/31] net/sfc: support callback to get receive queue information Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 17/31] net/sfc: add callback to get RxQ pending descriptors count Andrew Rybchenko
` (16 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Rx free threshold defines minimum number of free Rx descriptors
when Rx ring refill should be done.
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_rx.c | 16 ++++++++++++----
drivers/net/sfc/sfc_rx.h | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e67ca61..1d7993f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -838,6 +838,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
SFC_ASSERT(rxq != NULL);
qinfo->mp = rxq->refill_mb_pool;
+ qinfo->conf.rx_free_thresh = rxq->refill_threshold;
qinfo->conf.rx_drop_en = 1;
qinfo->nb_desc = rxq_info->entries;
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index be8fa23..278d583 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -87,6 +87,10 @@ sfc_rx_qrefill(struct sfc_rxq *rxq)
free_space = EFX_RXQ_LIMIT(rxq->ptr_mask + 1) -
(added - rxq->completed);
+
+ if (free_space < rxq->refill_threshold)
+ return;
+
bulks = free_space / RTE_DIM(objs);
id = added & rxq->ptr_mask;
@@ -410,9 +414,10 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
}
static int
-sfc_rx_qcheck_conf(struct sfc_adapter *sa,
+sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
const struct rte_eth_rxconf *rx_conf)
{
+ const uint16_t rx_free_thresh_max = EFX_RXQ_LIMIT(nb_rx_desc);
int rc = 0;
if (rx_conf->rx_thresh.pthresh != 0 ||
@@ -423,8 +428,10 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa,
rc = EINVAL;
}
- if (rx_conf->rx_free_thresh != 0) {
- sfc_err(sa, "RxQ free threshold is not supported");
+ if (rx_conf->rx_free_thresh > rx_free_thresh_max) {
+ sfc_err(sa,
+ "RxQ free threshold too large: %u vs maximum %u",
+ rx_conf->rx_free_thresh, rx_free_thresh_max);
rc = EINVAL;
}
@@ -555,7 +562,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
struct sfc_evq *evq;
struct sfc_rxq *rxq;
- rc = sfc_rx_qcheck_conf(sa, rx_conf);
+ rc = sfc_rx_qcheck_conf(sa, nb_rx_desc, rx_conf);
if (rc != 0)
goto fail_bad_conf;
@@ -615,6 +622,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
evq->rxq = rxq;
rxq->evq = evq;
rxq->ptr_mask = rxq_info->entries - 1;
+ rxq->refill_threshold = rx_conf->rx_free_thresh;
rxq->refill_mb_pool = mb_pool;
rxq->buf_size = buf_size;
rxq->hw_index = sw_index;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index e4385b9..69318ab 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -87,6 +87,7 @@ struct sfc_rxq {
/* Used on refill */
unsigned int added;
unsigned int pushed;
+ unsigned int refill_threshold;
uint8_t port_id;
uint16_t buf_size;
struct rte_mempool *refill_mb_pool;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 17/31] net/sfc: add callback to get RxQ pending descriptors count
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (15 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 16/31] net/sfc: support Rx free threshold Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 18/31] net/sfc: add RxQ descriptor done callback Andrew Rybchenko
` (15 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 11 +++++++++++
drivers/net/sfc/sfc_rx.c | 16 ++++++++++++++++
drivers/net/sfc/sfc_rx.h | 3 +++
3 files changed, 30 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1d7993f..163f9ed 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -845,6 +845,16 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
sfc_adapter_unlock(sa);
}
+static uint32_t
+sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+ return sfc_rx_qdesc_npending(sa, rx_queue_id);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -865,6 +875,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.mtu_set = sfc_dev_set_mtu,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
+ .rx_queue_count = sfc_rx_queue_count,
.tx_queue_setup = sfc_tx_queue_setup,
.tx_queue_release = sfc_tx_queue_release,
.flow_ctrl_get = sfc_flow_ctrl_get,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 278d583..ff9d799 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -257,6 +257,22 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
return done_pkts;
}
+unsigned int
+sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ struct sfc_rxq *rxq;
+
+ SFC_ASSERT(sw_index < sa->rxq_count);
+ rxq = sa->rxq_info[sw_index].rxq;
+
+ if (rxq == NULL || (rxq->state & SFC_RXQ_RUNNING) == 0)
+ return 0;
+
+ sfc_ev_qpoll(rxq->evq);
+
+ return rxq->pending - rxq->completed;
+}
+
static void
sfc_rx_qpurge(struct sfc_rxq *rxq)
{
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 69318ab..8064af6 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -140,6 +140,9 @@ void sfc_rx_qflush_failed(struct sfc_rxq *rxq);
uint16_t sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
+unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa,
+ unsigned int sw_index);
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 18/31] net/sfc: add RxQ descriptor done callback
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (16 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 17/31] net/sfc: add callback to get RxQ pending descriptors count Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 19/31] net/sfc: support scattered Rx DMA Andrew Rybchenko
` (14 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 9 +++++++++
drivers/net/sfc/sfc_rx.c | 11 +++++++++++
drivers/net/sfc/sfc_rx.h | 1 +
3 files changed, 21 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 163f9ed..59dcdb4 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -855,6 +855,14 @@ sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
return sfc_rx_qdesc_npending(sa, rx_queue_id);
}
+static int
+sfc_rx_descriptor_done(void *queue, uint16_t offset)
+{
+ struct sfc_rxq *rxq = queue;
+
+ return sfc_rx_qdesc_done(rxq, offset);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -876,6 +884,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.rx_queue_count = sfc_rx_queue_count,
+ .rx_descriptor_done = sfc_rx_descriptor_done,
.tx_queue_setup = sfc_tx_queue_setup,
.tx_queue_release = sfc_tx_queue_release,
.flow_ctrl_get = sfc_flow_ctrl_get,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index ff9d799..802beb2 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -273,6 +273,17 @@ sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index)
return rxq->pending - rxq->completed;
}
+int
+sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset)
+{
+ if ((rxq->state & SFC_RXQ_RUNNING) == 0)
+ return 0;
+
+ sfc_ev_qpoll(rxq->evq);
+
+ return offset < (rxq->pending - rxq->completed);
+}
+
static void
sfc_rx_qpurge(struct sfc_rxq *rxq)
{
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 8064af6..8d8e709 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -142,6 +142,7 @@ uint16_t sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa,
unsigned int sw_index);
+int sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset);
#ifdef __cplusplus
}
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 19/31] net/sfc: support scattered Rx DMA
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (17 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 18/31] net/sfc: add RxQ descriptor done callback Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 20/31] net/sfc: support deferred start of receive queues Andrew Rybchenko
` (13 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 4 ++--
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_rx.c | 39 +++++++++++++++++++++++++++---------
4 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index b5887d5..74cc942 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -9,6 +9,7 @@ Link status = Y
Link status event = Y
MTU update = Y
Jumbo frame = Y
+Scattered Rx = Y
Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 57e8318..a0f25d3 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -66,6 +66,8 @@ SFC EFX PMD has support for:
- Received packet type information
+- Scattered Rx DMA for packet that are larger that a single Rx descriptor
+
Non-supported Features
----------------------
@@ -86,8 +88,6 @@ The features not yet supported include:
- VLAN stripping
-- Scattered receive
-
- LRO
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 59dcdb4..f1b655b 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -840,6 +840,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
qinfo->mp = rxq->refill_mb_pool;
qinfo->conf.rx_free_thresh = rxq->refill_threshold;
qinfo->conf.rx_drop_en = 1;
+ qinfo->scattered_rx = (rxq_info->type == EFX_RXQ_TYPE_SCATTER);
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 802beb2..2909ec0 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -193,6 +193,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
unsigned int prefix_size = rxq->prefix_size;
unsigned int done_pkts = 0;
boolean_t discard_next = B_FALSE;
+ struct rte_mbuf *scatter_pkt = NULL;
if (unlikely((rxq->state & SFC_RXQ_RUNNING) == 0))
return 0;
@@ -218,9 +219,6 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
if (desc_flags & (EFX_ADDR_MISMATCH | EFX_DISCARD))
goto discard;
- if (desc_flags & EFX_PKT_CONT)
- goto discard;
-
if (desc_flags & EFX_PKT_PREFIX_LEN) {
uint16_t tmp_size;
int rc __rte_unused;
@@ -237,6 +235,29 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_data_len(m) = seg_len;
rte_pktmbuf_pkt_len(m) = seg_len;
+ if (scatter_pkt != NULL) {
+ if (rte_pktmbuf_chain(scatter_pkt, m) != 0) {
+ rte_mempool_put(rxq->refill_mb_pool,
+ scatter_pkt);
+ goto discard;
+ }
+ /* The packet to deliver */
+ m = scatter_pkt;
+ }
+
+ if (desc_flags & EFX_PKT_CONT) {
+ /* The packet is scattered, more fragments to come */
+ scatter_pkt = m;
+ /* Futher fragments have no prefix */
+ prefix_size = 0;
+ continue;
+ }
+
+ /* Scattered packet is done */
+ scatter_pkt = NULL;
+ /* The first fragment of the packet has prefix */
+ prefix_size = rxq->prefix_size;
+
m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
@@ -250,6 +271,9 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxd->mbuf = NULL;
}
+ /* pending is only moved when entire packet is received */
+ SFC_ASSERT(scatter_pkt == NULL);
+
rxq->completed = completed;
sfc_rx_qrefill(rxq);
@@ -618,7 +642,9 @@ 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 = EFX_RXQ_TYPE_DEFAULT;
+ rxq_info->type =
+ sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
+ EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT;
evq_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
@@ -806,11 +832,6 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
rxmode->hw_strip_crc = 1;
}
- if (rxmode->enable_scatter) {
- sfc_err(sa, "Scatter on Rx not supported");
- rc = EINVAL;
- }
-
if (rxmode->enable_lro) {
sfc_err(sa, "LRO not supported");
rc = EINVAL;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 20/31] net/sfc: support deferred start of receive queues
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (18 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 19/31] net/sfc: support scattered Rx DMA Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 21/31] net/sfc: add callback to get transmit queue information Andrew Rybchenko
` (12 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_rx.c | 18 +++++++------
drivers/net/sfc/sfc_rx.h | 2 ++
5 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 74cc942..4a887f0 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,6 +7,7 @@
Speed capabilities = Y
Link status = Y
Link status event = Y
+Queue start/stop = P
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index a0f25d3..3d705bc 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -68,6 +68,8 @@ SFC EFX PMD has support for:
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
+- Deferred receive queue start
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f1b655b..c531fdb 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -840,6 +840,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
qinfo->mp = rxq->refill_mb_pool;
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->nb_desc = rxq_info->entries;
@@ -864,6 +865,54 @@ sfc_rx_descriptor_done(void *queue, uint16_t offset)
return sfc_rx_qdesc_done(rxq, offset);
}
+static int
+sfc_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+ sfc_adapter_lock(sa);
+
+ rc = EINVAL;
+ if (sa->state != SFC_ADAPTER_STARTED)
+ goto fail_not_started;
+
+ rc = sfc_rx_qstart(sa, rx_queue_id);
+ if (rc != 0)
+ goto fail_rx_qstart;
+
+ sa->rxq_info[rx_queue_id].deferred_started = B_TRUE;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+
+fail_rx_qstart:
+fail_not_started:
+ sfc_adapter_unlock(sa);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
+static int
+sfc_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+ sfc_adapter_lock(sa);
+ sfc_rx_qstop(sa, rx_queue_id);
+
+ sa->rxq_info[rx_queue_id].deferred_started = B_FALSE;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -882,6 +931,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_infos_get = sfc_dev_infos_get,
.dev_supported_ptypes_get = sfc_dev_supported_ptypes_get,
.mtu_set = sfc_dev_set_mtu,
+ .rx_queue_start = sfc_rx_queue_start,
+ .rx_queue_stop = sfc_rx_queue_stop,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.rx_queue_count = sfc_rx_queue_count,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 2909ec0..3bfce1c 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -444,6 +444,9 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
rxq_info = &sa->rxq_info[sw_index];
rxq = rxq_info->rxq;
+
+ if (rxq->state == SFC_RXQ_INITIALIZED)
+ return;
SFC_ASSERT(rxq->state & SFC_RXQ_STARTED);
/* It seems to be used by DPDK for debug purposes only ('rte_ether') */
@@ -491,11 +494,6 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
rc = EINVAL;
}
- if (rx_conf->rx_deferred_start != 0) {
- sfc_err(sa, "RxQ deferred start is not supported");
- rc = EINVAL;
- }
-
return rc;
}
@@ -688,6 +686,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
rxq->state = SFC_RXQ_INITIALIZED;
rxq_info->rxq = rxq;
+ rxq_info->deferred_start = (rx_conf->rx_deferred_start != 0);
return 0;
@@ -742,9 +741,12 @@ sfc_rx_start(struct sfc_adapter *sa)
goto fail_rx_init;
for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
- rc = sfc_rx_qstart(sa, sw_index);
- if (rc != 0)
- goto fail_rx_qstart;
+ if ((!sa->rxq_info[sw_index].deferred_start ||
+ sa->rxq_info[sw_index].deferred_started)) {
+ rc = sfc_rx_qstart(sa, sw_index);
+ if (rc != 0)
+ goto fail_rx_qstart;
+ }
}
return 0;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 8d8e709..4aa6aea 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -119,6 +119,8 @@ struct sfc_rxq_info {
unsigned int entries;
efx_rxq_type_t type;
struct sfc_rxq *rxq;
+ boolean_t deferred_start;
+ boolean_t deferred_started;
};
int sfc_rx_init(struct sfc_adapter *sa);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 21/31] net/sfc: add callback to get transmit queue information
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (19 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 20/31] net/sfc: support deferred start of receive queues Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 22/31] net/sfc: support Tx free threshold Andrew Rybchenko
` (11 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c531fdb..73e8fe2 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -847,6 +847,28 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
sfc_adapter_unlock(sa);
}
+static void
+sfc_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+ struct rte_eth_txq_info *qinfo)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_txq_info *txq_info;
+
+ sfc_adapter_lock(sa);
+
+ SFC_ASSERT(tx_queue_id < sa->txq_count);
+
+ txq_info = &sa->txq_info[tx_queue_id];
+ SFC_ASSERT(txq_info->txq != NULL);
+
+ memset(qinfo, 0, sizeof(*qinfo));
+
+ qinfo->conf.txq_flags = txq_info->txq->flags;
+ qinfo->nb_desc = txq_info->entries;
+
+ sfc_adapter_unlock(sa);
+}
+
static uint32_t
sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
{
@@ -944,6 +966,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.mac_addr_set = sfc_mac_addr_set,
.set_mc_addr_list = sfc_set_mc_addr_list,
.rxq_info_get = sfc_rx_queue_info_get,
+ .txq_info_get = sfc_tx_queue_info_get,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 22/31] net/sfc: support Tx free threshold
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (20 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 21/31] net/sfc: add callback to get transmit queue information Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 23/31] net/sfc: support deferred start of transmit queues Andrew Rybchenko
` (10 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_tweak.h | 3 +++
drivers/net/sfc/sfc_tx.c | 14 ++++++++------
drivers/net/sfc/sfc_tx.h | 10 +---------
4 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 73e8fe2..5d0d774 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -864,6 +864,7 @@ sfc_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
memset(qinfo, 0, sizeof(*qinfo));
qinfo->conf.txq_flags = txq_info->txq->flags;
+ qinfo->conf.tx_free_thresh = txq_info->txq->free_thresh;
qinfo->nb_desc = txq_info->entries;
sfc_adapter_unlock(sa);
diff --git a/drivers/net/sfc/sfc_tweak.h b/drivers/net/sfc/sfc_tweak.h
index 8a60f35..be39a5e 100644
--- a/drivers/net/sfc/sfc_tweak.h
+++ b/drivers/net/sfc/sfc_tweak.h
@@ -48,4 +48,7 @@
*/
#define SFC_TX_XMIT_PKTS_REAP_AT_LEAST_ONCE 0
+/** Default free threshold follows recommendations from DPDK documentation */
+#define SFC_TX_DEFAULT_FREE_THRESH 32
+
#endif /* _SFC_TWEAK_H_ */
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index a240610..13b24f7 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -54,7 +54,7 @@
#define SFC_TX_QFLUSH_POLL_ATTEMPTS (2000)
static int
-sfc_tx_qcheck_conf(struct sfc_adapter *sa,
+sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
const struct rte_eth_txconf *tx_conf)
{
unsigned int flags = tx_conf->txq_flags;
@@ -65,9 +65,10 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa,
rc = EINVAL;
}
- if (tx_conf->tx_free_thresh != 0) {
+ if (tx_conf->tx_free_thresh > EFX_TXQ_LIMIT(nb_tx_desc)) {
sfc_err(sa,
- "setting explicit TX free threshold is not supported");
+ "TxQ free threshold too large: %u vs maximum %u",
+ tx_conf->tx_free_thresh, EFX_TXQ_LIMIT(nb_tx_desc));
rc = EINVAL;
}
@@ -147,7 +148,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
sfc_log_init(sa, "TxQ = %u", sw_index);
- rc = sfc_tx_qcheck_conf(sa, tx_conf);
+ rc = sfc_tx_qcheck_conf(sa, nb_tx_desc, tx_conf);
if (rc != 0)
goto fail_bad_conf;
@@ -188,6 +189,8 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
txq->state = SFC_TXQ_INITIALIZED;
txq->ptr_mask = txq_info->entries - 1;
+ txq->free_thresh = (tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
+ SFC_TX_DEFAULT_FREE_THRESH;
txq->hw_index = sw_index;
txq->flags = tx_conf->txq_flags;
txq->evq = evq;
@@ -537,8 +540,7 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
unsigned int pkts_sent = 0;
efx_desc_t *pend = &txq->pend_desc[0];
const unsigned int hard_max_fill = EFX_TXQ_LIMIT(txq->ptr_mask + 1);
- const unsigned int soft_max_fill = hard_max_fill -
- SFC_TX_MAX_PKT_DESC;
+ const unsigned int soft_max_fill = hard_max_fill - txq->free_thresh;
unsigned int fill_level = added - txq->completed;
boolean_t reap_done;
int rc __rte_unused;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index fe2736b..f9eecc0 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -40,15 +40,6 @@ extern "C" {
#endif
/**
- * Estimated maximum number of segments that transmit packet consists of;
- * it is determined with respect to the expectation of a packet to consist
- * of a header plus a couple of data segments one of those crossing 4K page;
- * it is used by transmit path to avoid redundant reaping and, thus,
- * to avoid increase of latency
- */
-#define SFC_TX_MAX_PKT_DESC 4
-
-/**
* A segment must not cross 4K boundary
* (this is a requirement of NIC TX descriptors)
*/
@@ -85,6 +76,7 @@ struct sfc_txq {
unsigned int added;
unsigned int pending;
unsigned int completed;
+ unsigned int free_thresh;
unsigned int hw_index;
unsigned int flags;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 23/31] net/sfc: support deferred start of transmit queues
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (21 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 22/31] net/sfc: support Tx free threshold Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 24/31] net/sfc: support VLAN offload on transmit path Andrew Rybchenko
` (9 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 +-
doc/guides/nics/sfc_efx.rst | 2 +-
drivers/net/sfc/sfc_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_tx.c | 18 +++++++------
drivers/net/sfc/sfc_tx.h | 2 ++
5 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 4a887f0..38bf9d2 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,7 +7,7 @@
Speed capabilities = Y
Link status = Y
Link status event = Y
-Queue start/stop = P
+Queue start/stop = Y
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 3d705bc..c2e7149 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -68,7 +68,7 @@ SFC EFX PMD has support for:
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
-- Deferred receive queue start
+- Deferred receive and transmit queue start
Non-supported Features
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 5d0d774..ba3c838 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -865,6 +865,7 @@ sfc_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
qinfo->conf.txq_flags = txq_info->txq->flags;
qinfo->conf.tx_free_thresh = txq_info->txq->free_thresh;
+ qinfo->conf.tx_deferred_start = txq_info->deferred_start;
qinfo->nb_desc = txq_info->entries;
sfc_adapter_unlock(sa);
@@ -936,6 +937,54 @@ sfc_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
return 0;
}
+static int
+sfc_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "TxQ = %u", tx_queue_id);
+
+ sfc_adapter_lock(sa);
+
+ rc = EINVAL;
+ if (sa->state != SFC_ADAPTER_STARTED)
+ goto fail_not_started;
+
+ rc = sfc_tx_qstart(sa, tx_queue_id);
+ if (rc != 0)
+ goto fail_tx_qstart;
+
+ sa->txq_info[tx_queue_id].deferred_started = B_TRUE;
+
+ sfc_adapter_unlock(sa);
+ return 0;
+
+fail_tx_qstart:
+
+fail_not_started:
+ sfc_adapter_unlock(sa);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
+static int
+sfc_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "TxQ = %u", tx_queue_id);
+
+ sfc_adapter_lock(sa);
+
+ sfc_tx_qstop(sa, tx_queue_id);
+
+ sa->txq_info[tx_queue_id].deferred_started = B_FALSE;
+
+ sfc_adapter_unlock(sa);
+ return 0;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -956,6 +1005,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.mtu_set = sfc_dev_set_mtu,
.rx_queue_start = sfc_rx_queue_start,
.rx_queue_stop = sfc_rx_queue_stop,
+ .tx_queue_start = sfc_tx_queue_start,
+ .tx_queue_stop = sfc_tx_queue_stop,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.rx_queue_count = sfc_rx_queue_count,
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 13b24f7..15a6f9f 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -72,11 +72,6 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
rc = EINVAL;
}
- if (tx_conf->tx_deferred_start != 0) {
- sfc_err(sa, "TX queue deferred start is not supported (yet)");
- rc = EINVAL;
- }
-
if (tx_conf->tx_thresh.pthresh != 0 ||
tx_conf->tx_thresh.hthresh != 0 ||
tx_conf->tx_thresh.wthresh != 0) {
@@ -198,6 +193,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
evq->txq = txq;
txq_info->txq = txq;
+ txq_info->deferred_start = (tx_conf->tx_deferred_start != 0);
return 0;
@@ -425,6 +421,9 @@ sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
txq = txq_info->txq;
+ if (txq->state == SFC_TXQ_INITIALIZED)
+ return;
+
SFC_ASSERT(txq->state & SFC_TXQ_STARTED);
txq->state &= ~SFC_TXQ_RUNNING;
@@ -497,9 +496,12 @@ sfc_tx_start(struct sfc_adapter *sa)
goto fail_efx_tx_init;
for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
- rc = sfc_tx_qstart(sa, sw_index);
- if (rc != 0)
- goto fail_tx_qstart;
+ if (!(sa->txq_info[sw_index].deferred_start) ||
+ sa->txq_info[sw_index].deferred_started) {
+ rc = sfc_tx_qstart(sa, sw_index);
+ if (rc != 0)
+ goto fail_tx_qstart;
+ }
}
return 0;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index f9eecc0..632e3be 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -91,6 +91,8 @@ sfc_txq_sw_index(const struct sfc_txq *txq)
struct sfc_txq_info {
unsigned int entries;
struct sfc_txq *txq;
+ boolean_t deferred_start;
+ boolean_t deferred_started;
};
int sfc_tx_init(struct sfc_adapter *sa);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 24/31] net/sfc: support VLAN offload on transmit path
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (22 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 23/31] net/sfc: support deferred start of transmit queues Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 25/31] net/sfc: add basic stubs for RSS support on driver attach Andrew Rybchenko
` (8 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 8 +++++--
drivers/net/sfc/sfc_tx.c | 45 +++++++++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_tx.h | 1 +
5 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 38bf9d2..e7a1143 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -15,6 +15,7 @@ Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
Flow control = Y
+VLAN offload = P
L3 checksum offload = Y
L4 checksum offload = Y
Packet type parsing = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index c2e7149..ee2ba27 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -70,6 +70,8 @@ SFC EFX PMD has support for:
- Deferred receive and transmit queue start
+- Transmit VLAN insertion (if running firmware variant supports it)
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index ba3c838..0de17ca 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -46,6 +46,7 @@ static void
sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct sfc_adapter *sa = dev->data->dev_private;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
RTE_SET_USED(dev_info);
@@ -78,8 +79,11 @@ 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;
- dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOVLANOFFL |
- ETH_TXQ_FLAGS_NOXSUMSCTP;
+ dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP;
+ if (!encp->enc_hw_tx_insert_vlan_enabled)
+ dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOVLANOFFL;
+ else
+ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_VLAN_INSERT;
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 15a6f9f..86bcfec 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -58,6 +58,7 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
const struct rte_eth_txconf *tx_conf)
{
unsigned int flags = tx_conf->txq_flags;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
int rc = 0;
if (tx_conf->tx_rs_thresh != 0) {
@@ -80,7 +81,8 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
rc = EINVAL;
}
- if ((flags & ETH_TXQ_FLAGS_NOVLANOFFL) == 0) {
+ if (!encp->enc_hw_tx_insert_vlan_enabled &&
+ (flags & ETH_TXQ_FLAGS_NOVLANOFFL) == 0) {
sfc_err(sa, "VLAN offload is not supported");
rc = EINVAL;
}
@@ -384,6 +386,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
goto fail_tx_qcreate;
txq->added = txq->pending = txq->completed = desc_index;
+ txq->hw_vlan_tci = 0;
efx_tx_qenable(txq->common);
@@ -533,6 +536,37 @@ sfc_tx_stop(struct sfc_adapter *sa)
efx_tx_fini(sa->nic);
}
+/*
+ * The function is used to insert or update VLAN tag;
+ * the firmware has state of the firmware tag to insert per TxQ
+ * (controlled by option descriptors), hence, if the tag of the
+ * packet to be sent is different from one remembered by the firmware,
+ * the function will update it
+ */
+static unsigned int
+sfc_tx_maybe_insert_tag(struct sfc_txq *txq, struct rte_mbuf *m,
+ efx_desc_t **pend)
+{
+ uint16_t this_tag = ((m->ol_flags & PKT_TX_VLAN_PKT) ?
+ m->vlan_tci : 0);
+
+ if (this_tag == txq->hw_vlan_tci)
+ return 0;
+
+ /*
+ * The expression inside SFC_ASSERT() is not desired to be checked in
+ * a non-debug build because it might be too expensive on the data path
+ */
+ SFC_ASSERT(efx_nic_cfg_get(txq->evq->sa->nic)->enc_hw_tx_insert_vlan_enabled);
+
+ efx_tx_qdesc_vlantci_create(txq->common, rte_cpu_to_be_16(this_tag),
+ *pend);
+ (*pend)++;
+ txq->hw_vlan_tci = this_tag;
+
+ return 1;
+}
+
uint16_t
sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -574,6 +608,15 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
size_t pkt_len = m_seg->pkt_len;
unsigned int pkt_descs = 0;
+ /*
+ * Here VLAN TCI is expected to be zero in case if no
+ * DEV_TX_VLAN_OFFLOAD capability is advertised;
+ * if the calling app ignores the absence of
+ * DEV_TX_VLAN_OFFLOAD and pushes VLAN TCI, then
+ * TX_ERROR will occur
+ */
+ pkt_descs += sfc_tx_maybe_insert_tag(txq, m_seg, &pend);
+
for (; m_seg != NULL; m_seg = m_seg->next) {
efsys_dma_addr_t next_frag;
size_t seg_len;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 632e3be..4d25c6a 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -77,6 +77,7 @@ struct sfc_txq {
unsigned int pending;
unsigned int completed;
unsigned int free_thresh;
+ uint16_t hw_vlan_tci;
unsigned int hw_index;
unsigned int flags;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 25/31] net/sfc: add basic stubs for RSS support on driver attach
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (23 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 24/31] net/sfc: support VLAN offload on transmit path Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 26/31] net/sfc: support RSS hash offload Andrew Rybchenko
` (7 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc.c | 76 +++++++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc.h | 17 ++++++++++
drivers/net/sfc/sfc_ethdev.c | 8 +++++
drivers/net/sfc/sfc_rx.c | 81 +++++++++++++++++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_rx.h | 8 +++++
7 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index ee2ba27..4f674c0 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -66,6 +66,8 @@ SFC EFX PMD has support for:
- Received packet type information
+- Receive side scaling (RSS)
+
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
- Deferred receive and transmit queue start
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index 0f941e6..fb2f3b5 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -195,7 +195,7 @@ prefetch_read_once(const volatile void *addr)
#define EFSYS_OPT_BOOTCFG 0
#define EFSYS_OPT_DIAG 0
-#define EFSYS_OPT_RX_SCALE 0
+#define EFSYS_OPT_RX_SCALE 1
#define EFSYS_OPT_QSTATS 0
/* Filters support is required for SFN7xxx and SFN8xx */
#define EFSYS_OPT_FILTER 1
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index e2e6c9e..e79367d 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -484,6 +484,73 @@ sfc_mem_bar_fini(struct sfc_adapter *sa)
memset(ebp, 0, sizeof(*ebp));
}
+#if EFSYS_OPT_RX_SCALE
+/*
+ * A fixed RSS key which has a property of being symmetric
+ * (symmetrical flows are distributed to the same CPU)
+ * and also known to give a uniform distribution
+ * (a good distribution of traffic between different CPUs)
+ */
+static const uint8_t default_rss_key[SFC_RSS_KEY_SIZE] = {
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+};
+#endif
+
+static int
+sfc_set_rss_defaults(struct sfc_adapter *sa)
+{
+#if EFSYS_OPT_RX_SCALE
+ int rc;
+
+ rc = efx_intr_init(sa->nic, sa->intr.type, NULL);
+ if (rc != 0)
+ goto fail_intr_init;
+
+ rc = efx_ev_init(sa->nic);
+ if (rc != 0)
+ goto fail_ev_init;
+
+ rc = efx_rx_init(sa->nic);
+ if (rc != 0)
+ goto fail_rx_init;
+
+ rc = efx_rx_scale_support_get(sa->nic, &sa->rss_support);
+ if (rc != 0)
+ goto fail_scale_support_get;
+
+ rc = efx_rx_hash_support_get(sa->nic, &sa->hash_support);
+ if (rc != 0)
+ goto fail_hash_support_get;
+
+ efx_rx_fini(sa->nic);
+ efx_ev_fini(sa->nic);
+ efx_intr_fini(sa->nic);
+
+ sa->rss_hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS);
+
+ rte_memcpy(sa->rss_key, default_rss_key, sizeof(sa->rss_key));
+
+ return 0;
+
+fail_hash_support_get:
+fail_scale_support_get:
+fail_rx_init:
+ efx_ev_fini(sa->nic);
+
+fail_ev_init:
+ efx_intr_fini(sa->nic);
+
+fail_intr_init:
+ return rc;
+#else
+ return 0;
+#endif
+}
+
int
sfc_attach(struct sfc_adapter *sa)
{
@@ -550,6 +617,10 @@ sfc_attach(struct sfc_adapter *sa)
efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
&sa->port.phy_adv_cap_mask);
+ rc = sfc_set_rss_defaults(sa);
+ if (rc != 0)
+ goto fail_set_rss_defaults;
+
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
@@ -558,7 +629,12 @@ sfc_attach(struct sfc_adapter *sa)
sfc_log_init(sa, "done");
return 0;
+fail_set_rss_defaults:
+ sfc_intr_detach(sa);
+
fail_intr_attach:
+ efx_nic_fini(sa->nic);
+
fail_estimate_rsrc_limits:
fail_nic_reset:
sfc_log_init(sa, "unprobe nic");
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index f0bbaf8..01dbfb6 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -42,6 +42,13 @@
extern "C" {
#endif
+#if EFSYS_OPT_RX_SCALE
+/** RSS key length (bytes) */
+#define SFC_RSS_KEY_SIZE 40
+/** RSS hash offloads mask */
+#define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP)
+#endif
+
/*
* +---------------+
* | UNINITIALIZED |<-----------+
@@ -187,6 +194,16 @@ struct sfc_adapter {
unsigned int txq_count;
struct sfc_txq_info *txq_info;
+
+ unsigned int rss_channels;
+
+#if EFSYS_OPT_RX_SCALE
+ efx_rx_scale_support_t rss_support;
+ efx_rx_hash_support_t hash_support;
+ unsigned int rss_hash_types;
+ unsigned int rss_tbl[EFX_RSS_TBL_SIZE];
+ uint8_t rss_key[SFC_RSS_KEY_SIZE];
+#endif
};
/*
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 0de17ca..b17607f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -85,6 +85,14 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
else
dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_VLAN_INSERT;
+#if EFSYS_OPT_RX_SCALE
+ if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) {
+ dev_info->reta_size = EFX_RSS_TBL_SIZE;
+ dev_info->hash_key_size = SFC_RSS_KEY_SIZE;
+ dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS;
+ }
+#endif
+
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
/* The RXQ hardware requires that the descriptor count is a power
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 3bfce1c..f0fe1b8 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -411,7 +411,8 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
if (sw_index == 0) {
rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common,
- B_FALSE);
+ (sa->rss_channels > 1) ?
+ B_TRUE : B_FALSE);
if (rc != 0)
goto fail_mac_filter_default_rxq_set;
}
@@ -683,6 +684,11 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
rxq->batch_max = encp->enc_rx_batch_max;
rxq->prefix_size = encp->enc_rx_prefix_size;
+#if EFSYS_OPT_RX_SCALE
+ if (sa->hash_support == EFX_RX_HASH_AVAILABLE)
+ rxq->flags |= SFC_RXQ_RSS_HASH;
+#endif
+
rxq->state = SFC_RXQ_INITIALIZED;
rxq_info->rxq = rxq;
@@ -728,6 +734,56 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
rte_free(rxq);
}
+#if EFSYS_OPT_RX_SCALE
+unsigned int
+sfc_rte_to_efx_hash_type(uint64_t rss_hf)
+{
+ unsigned int efx_hash_types = 0;
+
+ if ((rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 |
+ ETH_RSS_NONFRAG_IPV4_OTHER)) != 0)
+ efx_hash_types |= (1 << EFX_RX_HASH_IPV4);
+
+ if ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != 0)
+ efx_hash_types |= (1 << EFX_RX_HASH_TCPIPV4);
+
+ if ((rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
+ ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX)) != 0)
+ efx_hash_types |= (1 << EFX_RX_HASH_IPV6);
+
+ if ((rss_hf & (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX)) != 0)
+ efx_hash_types |= (1 << EFX_RX_HASH_TCPIPV6);
+
+ return efx_hash_types;
+}
+#endif
+
+static int
+sfc_rx_rss_config(struct sfc_adapter *sa)
+{
+ int rc = 0;
+
+#if EFSYS_OPT_RX_SCALE
+ if (sa->rss_channels > 1) {
+ rc = efx_rx_scale_mode_set(sa->nic, EFX_RX_HASHALG_TOEPLITZ,
+ sa->rss_hash_types, B_TRUE);
+ if (rc != 0)
+ goto finish;
+
+ rc = efx_rx_scale_key_set(sa->nic, sa->rss_key,
+ sizeof(sa->rss_key));
+ if (rc != 0)
+ goto finish;
+
+ rc = efx_rx_scale_tbl_set(sa->nic, sa->rss_tbl,
+ sizeof(sa->rss_tbl));
+ }
+
+finish:
+#endif
+ return rc;
+}
+
int
sfc_rx_start(struct sfc_adapter *sa)
{
@@ -740,6 +796,10 @@ sfc_rx_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_rx_init;
+ rc = sfc_rx_rss_config(sa);
+ if (rc != 0)
+ goto fail_rss_config;
+
for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
if ((!sa->rxq_info[sw_index].deferred_start ||
sa->rxq_info[sw_index].deferred_started)) {
@@ -755,6 +815,7 @@ sfc_rx_start(struct sfc_adapter *sa)
while (sw_index-- > 0)
sfc_rx_qstop(sa, sw_index);
+fail_rss_config:
efx_rx_fini(sa->nic);
fail_rx_init:
@@ -801,6 +862,14 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
case ETH_MQ_RX_NONE:
/* No special checks are required */
break;
+#if EFSYS_OPT_RX_SCALE
+ case ETH_MQ_RX_RSS:
+ if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ sfc_err(sa, "RSS is not available");
+ rc = EINVAL;
+ }
+ break;
+#endif
default:
sfc_err(sa, "Rx multi-queue mode %u not supported",
rxmode->mq_mode);
@@ -876,6 +945,16 @@ sfc_rx_init(struct sfc_adapter *sa)
goto fail_rx_qinit_info;
}
+#if EFSYS_OPT_RX_SCALE
+ sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ?
+ MIN(sa->rxq_count, EFX_MAXRSS) : 1;
+
+ if (sa->rss_channels > 1) {
+ for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index)
+ sa->rss_tbl[sw_index] = sw_index % sa->rss_channels;
+ }
+#endif
+
return 0;
fail_rx_qinit_info:
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 4aa6aea..2b8b9eb 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -83,6 +83,10 @@ struct sfc_rxq {
unsigned int completed;
uint16_t batch_max;
uint16_t prefix_size;
+#if EFSYS_OPT_RX_SCALE
+ unsigned int flags;
+#define SFC_RXQ_RSS_HASH 0x1
+#endif
/* Used on refill */
unsigned int added;
@@ -146,6 +150,10 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa,
unsigned int sw_index);
int sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset);
+#if EFSYS_OPT_RX_SCALE
+unsigned int sfc_rte_to_efx_hash_type(uint64_t rss_hf);
+#endif
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 26/31] net/sfc: support RSS hash offload
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (24 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 25/31] net/sfc: add basic stubs for RSS support on driver attach Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 27/31] net/sfc: add callback to query RSS key and hash types config Andrew Rybchenko
` (6 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Extract RSS hash provided by the HW in the prefix and put it to mbuf.
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_rx.c | 31 ++++++++++++++++++++++++++++++-
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index e7a1143..debea27 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -14,6 +14,7 @@ Scattered Rx = Y
Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
+RSS hash = Y
Flow control = Y
VLAN offload = P
L3 checksum offload = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 4f674c0..64489de 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -68,6 +68,8 @@ SFC EFX PMD has support for:
- Receive side scaling (RSS)
+- RSS hash
+
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
- Deferred receive and transmit queue start
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index f0fe1b8..1e254a8 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -185,6 +185,28 @@ sfc_rx_desc_flags_to_packet_type(const unsigned int desc_flags)
((desc_flags & EFX_PKT_UDP) ? RTE_PTYPE_L4_UDP : 0);
}
+static void
+sfc_rx_set_rss_hash(struct sfc_rxq *rxq, unsigned int flags, struct rte_mbuf *m)
+{
+#if EFSYS_OPT_RX_SCALE
+ uint8_t *mbuf_data;
+
+
+ if ((rxq->flags & SFC_RXQ_RSS_HASH) == 0)
+ return;
+
+ mbuf_data = rte_pktmbuf_mtod(m, uint8_t *);
+
+ if (flags & (EFX_PKT_IPV4 | EFX_PKT_IPV6)) {
+ m->hash.rss = efx_pseudo_hdr_hash_get(rxq->common,
+ EFX_RX_HASHALG_TOEPLITZ,
+ mbuf_data);
+
+ m->ol_flags |= PKT_RX_RSS_HASH;
+ }
+#endif
+}
+
uint16_t
sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
@@ -231,7 +253,6 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
seg_len = rxd->size - prefix_size;
}
- m->data_off += prefix_size;
rte_pktmbuf_data_len(m) = seg_len;
rte_pktmbuf_pkt_len(m) = seg_len;
@@ -261,6 +282,14 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
+ /*
+ * Extract RSS hash from the packet prefix and
+ * set the corresponding field (if needed and possible)
+ */
+ sfc_rx_set_rss_hash(rxq, desc_flags, m);
+
+ m->data_off += prefix_size;
+
*rx_pkts++ = m;
done_pkts++;
continue;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 27/31] net/sfc: add callback to query RSS key and hash types config
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (25 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 26/31] net/sfc: support RSS hash offload Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 28/31] net/sfc: add callback to set " Andrew Rybchenko
` (5 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 33 +++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_rx.c | 22 ++++++++++++++++++++++
drivers/net/sfc/sfc_rx.h | 1 +
3 files changed, 56 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index b17607f..c78d798 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -997,6 +997,36 @@ sfc_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
return 0;
}
+#if EFSYS_OPT_RX_SCALE
+static int
+sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE))
+ return -ENOTSUP;
+
+ sfc_adapter_lock(sa);
+
+ /*
+ * Mapping of hash configuration between RTE and EFX is not one-to-one,
+ * hence, conversion is done here to derive a correct set of ETH_RSS
+ * flags which corresponds to the active EFX configuration stored
+ * locally in 'sfc_adapter' and kept up-to-date
+ */
+ rss_conf->rss_hf = sfc_efx_to_rte_hash_type(sa->rss_hash_types);
+ rss_conf->rss_key_len = SFC_RSS_KEY_SIZE;
+ if (rss_conf->rss_key != NULL)
+ rte_memcpy(rss_conf->rss_key, sa->rss_key, SFC_RSS_KEY_SIZE);
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+#endif
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -1028,6 +1058,9 @@ 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,
+#if EFSYS_OPT_RX_SCALE
+ .rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
+#endif
.set_mc_addr_list = sfc_set_mc_addr_list,
.rxq_info_get = sfc_rx_queue_info_get,
.txq_info_get = sfc_tx_queue_info_get,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 1e254a8..ca26b1e 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -785,6 +785,28 @@ sfc_rte_to_efx_hash_type(uint64_t rss_hf)
return efx_hash_types;
}
+
+uint64_t
+sfc_efx_to_rte_hash_type(unsigned int efx_hash_types)
+{
+ uint64_t rss_hf = 0;
+
+ if ((efx_hash_types & (1 << EFX_RX_HASH_IPV4)) != 0)
+ rss_hf |= (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 |
+ ETH_RSS_NONFRAG_IPV4_OTHER);
+
+ if ((efx_hash_types & (1 << EFX_RX_HASH_TCPIPV4)) != 0)
+ rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+
+ if ((efx_hash_types & (1 << EFX_RX_HASH_IPV6)) != 0)
+ rss_hf |= (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
+ ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX);
+
+ if ((efx_hash_types & (1 << EFX_RX_HASH_TCPIPV6)) != 0)
+ rss_hf |= (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX);
+
+ return rss_hf;
+}
#endif
static int
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 2b8b9eb..aa7264c 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -152,6 +152,7 @@ int sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset);
#if EFSYS_OPT_RX_SCALE
unsigned int sfc_rte_to_efx_hash_type(uint64_t rss_hf);
+uint64_t sfc_efx_to_rte_hash_type(unsigned int efx_hash_types);
#endif
#ifdef __cplusplus
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 28/31] net/sfc: add callback to set RSS key and hash types config
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (26 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 27/31] net/sfc: add callback to query RSS key and hash types config Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 29/31] net/sfc: add callback to query RSS redirection table Andrew Rybchenko
` (4 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/sfc_ethdev.c | 63 ++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index debea27..4f6f117 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -15,6 +15,7 @@ Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
RSS hash = Y
+RSS key update = Y
Flow control = Y
VLAN offload = P
L3 checksum offload = Y
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c78d798..f9a766c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1025,6 +1025,68 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
return 0;
}
+
+static int
+sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ unsigned int efx_hash_types;
+ int rc = 0;
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)) {
+ sfc_err(sa, "RSS is not available");
+ return -ENOTSUP;
+ }
+
+ if ((rss_conf->rss_key != NULL) &&
+ (rss_conf->rss_key_len != sizeof(sa->rss_key))) {
+ sfc_err(sa, "RSS key size is wrong (should be %lu)",
+ sizeof(sa->rss_key));
+ return -EINVAL;
+ }
+
+ if ((rss_conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) {
+ sfc_err(sa, "unsupported hash functions requested");
+ return -EINVAL;
+ }
+
+ sfc_adapter_lock(sa);
+
+ efx_hash_types = sfc_rte_to_efx_hash_type(rss_conf->rss_hf);
+
+ rc = efx_rx_scale_mode_set(sa->nic, EFX_RX_HASHALG_TOEPLITZ,
+ efx_hash_types, B_TRUE);
+ if (rc != 0)
+ goto fail_scale_mode_set;
+
+ if (rss_conf->rss_key != NULL) {
+ if (sa->state == SFC_ADAPTER_STARTED) {
+ rc = efx_rx_scale_key_set(sa->nic, rss_conf->rss_key,
+ sizeof(sa->rss_key));
+ if (rc != 0)
+ goto fail_scale_key_set;
+ }
+
+ rte_memcpy(sa->rss_key, rss_conf->rss_key, sizeof(sa->rss_key));
+ }
+
+ sa->rss_hash_types = efx_hash_types;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+
+fail_scale_key_set:
+ if (efx_rx_scale_mode_set(sa->nic, EFX_RX_HASHALG_TOEPLITZ,
+ sa->rss_hash_types, B_TRUE) != 0)
+ sfc_err(sa, "failed to restore RSS mode");
+
+fail_scale_mode_set:
+ sfc_adapter_unlock(sa);
+ return -rc;
+}
#endif
static const struct eth_dev_ops sfc_eth_dev_ops = {
@@ -1059,6 +1121,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
#if EFSYS_OPT_RX_SCALE
+ .rss_hash_update = sfc_dev_rss_hash_update,
.rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
#endif
.set_mc_addr_list = sfc_set_mc_addr_list,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 29/31] net/sfc: add callback to query RSS redirection table
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (27 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 28/31] net/sfc: add callback to set " Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 30/31] net/sfc: add callback to update " Andrew Rybchenko
` (3 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f9a766c..0cd96ac 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1087,6 +1087,36 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
sfc_adapter_unlock(sa);
return -rc;
}
+
+static int
+sfc_dev_rss_reta_query(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int entry;
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE))
+ return -ENOTSUP;
+
+ if (reta_size != EFX_RSS_TBL_SIZE)
+ return -EINVAL;
+
+ sfc_adapter_lock(sa);
+
+ for (entry = 0; entry < reta_size; entry++) {
+ int grp = entry / RTE_RETA_GROUP_SIZE;
+ int grp_idx = entry % RTE_RETA_GROUP_SIZE;
+
+ if ((reta_conf[grp].mask >> grp_idx) & 1)
+ reta_conf[grp].reta[grp_idx] = sa->rss_tbl[entry];
+ }
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
#endif
static const struct eth_dev_ops sfc_eth_dev_ops = {
@@ -1121,6 +1151,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
#if EFSYS_OPT_RX_SCALE
+ .reta_query = sfc_dev_rss_reta_query,
.rss_hash_update = sfc_dev_rss_hash_update,
.rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 30/31] net/sfc: add callback to update RSS redirection table
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (28 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 29/31] net/sfc: add callback to query RSS redirection table Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 31/31] net/sfc: support firmware-assisted TSOv2 Andrew Rybchenko
` (2 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/sfc_ethdev.c | 60 ++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 4f6f117..07c58d5 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -16,6 +16,7 @@ Allmulticast mode = Y
Multicast MAC filter = Y
RSS hash = Y
RSS key update = Y
+RSS reta update = Y
Flow control = Y
VLAN offload = P
L3 checksum offload = Y
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 0cd96ac..09cc46b 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1117,6 +1117,65 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev,
return 0;
}
+
+static int
+sfc_dev_rss_reta_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ unsigned int *rss_tbl_new;
+ uint16_t entry;
+ int rc;
+
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)) {
+ sfc_err(sa, "RSS is not available");
+ return -ENOTSUP;
+ }
+
+ if (reta_size != EFX_RSS_TBL_SIZE) {
+ sfc_err(sa, "RETA size is wrong (should be %hu)",
+ EFX_RSS_TBL_SIZE);
+ return -EINVAL;
+ }
+
+ rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(sa->rss_tbl), 0);
+ if (rss_tbl_new == NULL)
+ return -ENOMEM;
+
+ sfc_adapter_lock(sa);
+
+ rte_memcpy(rss_tbl_new, sa->rss_tbl, sizeof(sa->rss_tbl));
+
+ for (entry = 0; entry < reta_size; entry++) {
+ int grp_idx = entry % RTE_RETA_GROUP_SIZE;
+ struct rte_eth_rss_reta_entry64 *grp;
+
+ grp = &reta_conf[entry / RTE_RETA_GROUP_SIZE];
+
+ if (grp->mask & (1ull << grp_idx)) {
+ if (grp->reta[grp_idx] >= sa->rss_channels) {
+ rc = EINVAL;
+ goto bad_reta_entry;
+ }
+ rss_tbl_new[entry] = grp->reta[grp_idx];
+ }
+ }
+
+ rc = efx_rx_scale_tbl_set(sa->nic, rss_tbl_new, EFX_RSS_TBL_SIZE);
+ if (rc == 0)
+ rte_memcpy(sa->rss_tbl, rss_tbl_new, sizeof(sa->rss_tbl));
+
+bad_reta_entry:
+ sfc_adapter_unlock(sa);
+
+ rte_free(rss_tbl_new);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
+}
#endif
static const struct eth_dev_ops sfc_eth_dev_ops = {
@@ -1151,6 +1210,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
#if EFSYS_OPT_RX_SCALE
+ .reta_update = sfc_dev_rss_reta_update,
.reta_query = sfc_dev_rss_reta_query,
.rss_hash_update = sfc_dev_rss_hash_update,
.rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH 31/31] net/sfc: support firmware-assisted TSOv2
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (29 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 30/31] net/sfc: add callback to update " Andrew Rybchenko
@ 2016-12-02 7:44 ` Andrew Rybchenko
2016-12-09 17:34 ` [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Ferruh Yigit
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-02 7:44 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Mark Spender <mspender@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
config/common_base | 1 +
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 8 ++
drivers/net/sfc/Makefile | 4 +
drivers/net/sfc/sfc.c | 8 ++
drivers/net/sfc/sfc.h | 2 +
drivers/net/sfc/sfc_ethdev.c | 3 +
drivers/net/sfc/sfc_tso.c | 203 +++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_tx.c | 88 ++++++++++++++-
drivers/net/sfc/sfc_tx.h | 28 +++++
10 files changed, 343 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/sfc/sfc_tso.c
diff --git a/config/common_base b/config/common_base
index 1eb8eea..8bb2a00 100644
--- a/config/common_base
+++ b/config/common_base
@@ -342,6 +342,7 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
#
CONFIG_RTE_LIBRTE_SFC_EFX_PMD=y
CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG=n
+CONFIG_RTE_LIBRTE_SFC_EFX_TSO=n
#
# Compile null PMD
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 07c58d5..3a15baa 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -11,6 +11,7 @@ Queue start/stop = Y
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
+TSO = Y
Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 64489de..f826726 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -60,6 +60,8 @@ SFC EFX PMD has support for:
- Allmulticast mode
+- TCP segmentation offload (TSO)
+
- Multicast MAC filter
- IPv4/IPv6 TCP/UDP receive checksum offload
@@ -166,6 +168,12 @@ Please note that enabling debugging options may affect system performance.
Enable compilation of the extra run-time consistency checks.
+- ``CONFIG_RTE_LIBRTE_SFC_EFX_TSO`` (default **n**)
+
+ Toggle TCP segmentation offload support.
+ Enabling the feature limits the number of available transmit queues
+ significantly due to the limited number of adapter TSO contexts.
+
Per-Device Parameters
~~~~~~~~~~~~~~~~~~~~~
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index dd099b2..14d6536 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -90,6 +90,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_port.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_rx.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_TSO) += sfc_tso.c
+
VPATH += $(SRCDIR)/base
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_bootcfg.c
@@ -139,4 +141,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_ether
DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_mempool
DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_TSO) += lib/librte_net
+
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index e79367d..02a56f7 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -621,6 +621,14 @@ sfc_attach(struct sfc_adapter *sa)
if (rc != 0)
goto fail_set_rss_defaults;
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+ sa->tso = efx_nic_cfg_get(sa->nic)->enc_fw_assisted_tso_v2_enabled;
+ if (!sa->tso)
+ sfc_warn(sa, "TSO support isn't available on this adapter");
+#else /* !RTE_LIBRTE_SFC_EFX_TSO */
+ sa->tso = B_FALSE;
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
+
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 01dbfb6..df9c20b 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -195,6 +195,8 @@ struct sfc_adapter {
unsigned int txq_count;
struct sfc_txq_info *txq_info;
+ boolean_t tso;
+
unsigned int rss_channels;
#if EFSYS_OPT_RX_SCALE
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 09cc46b..1fb763a 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -93,6 +93,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
}
#endif
+ if (sa->tso)
+ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
+
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
/* The RXQ hardware requires that the descriptor count is a power
diff --git a/drivers/net/sfc/sfc_tso.c b/drivers/net/sfc/sfc_tso.c
new file mode 100644
index 0000000..fa8c04d
--- /dev/null
+++ b/drivers/net/sfc/sfc_tso.c
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * 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.
+ */
+
+#include <rte_ip.h>
+#include <rte_tcp.h>
+
+#include "sfc.h"
+#include "sfc_debug.h"
+#include "sfc_tx.h"
+#include "sfc_ev.h"
+
+/** Standard TSO header length */
+#define SFC_TSOH_STD_LEN 256
+
+/** The number of TSO option descriptors that precede the packet descriptors */
+#define SFC_TSO_OPDESCS_IDX_SHIFT 2
+
+int
+sfc_tso_alloc_tsoh_objs(struct sfc_adapter *sa, unsigned int sw_index,
+ struct sfc_txq *txq, unsigned int socket_id)
+{
+ unsigned int i;
+ struct sfc_txq_info *txq_info = &sa->txq_info[sw_index];
+
+ for (i = 0; i < txq_info->entries; ++i) {
+ txq->sw_ring[i].tsoh = rte_malloc_socket("sfc-txq-tsoh-obj",
+ SFC_TSOH_STD_LEN,
+ SFC_TX_SEG_BOUNDARY,
+ socket_id);
+ if (txq->sw_ring[i].tsoh == NULL)
+ goto fail_alloc_tsoh_objs;
+ }
+
+ return 0;
+
+fail_alloc_tsoh_objs:
+ while (i > 0)
+ rte_free(txq->sw_ring[--i].tsoh);
+
+ return ENOMEM;
+}
+
+void
+sfc_tso_free_tsoh_objs(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ unsigned int txds;
+ struct sfc_txq_info *txq_info = &sa->txq_info[sw_index];
+ struct sfc_txq *txq = txq_info->txq;
+
+ for (txds = 0; txds < txq_info->entries; ++txds) {
+ rte_free(txq->sw_ring[txds].tsoh);
+ txq->sw_ring[txds].tsoh = NULL;
+ }
+}
+
+static void
+sfc_tso_prepare_header(struct sfc_txq *txq, struct rte_mbuf **in_seg,
+ size_t *in_off, unsigned int idx, size_t bytes_left)
+{
+ struct rte_mbuf *m = *in_seg;
+ size_t bytes_to_copy = 0;
+ uint8_t *tsoh = txq->sw_ring[idx & txq->ptr_mask].tsoh;
+
+ do {
+ bytes_to_copy = MIN(bytes_left, m->data_len);
+
+ rte_memcpy(tsoh, rte_pktmbuf_mtod(m, uint8_t *),
+ bytes_to_copy);
+
+ bytes_left -= bytes_to_copy;
+ tsoh += bytes_to_copy;
+
+ if (bytes_left > 0) {
+ m = m->next;
+ SFC_ASSERT(m != NULL);
+ }
+ } while (bytes_left > 0);
+
+ if (bytes_to_copy == m->data_len) {
+ *in_seg = m->next;
+ *in_off = 0;
+ } else {
+ *in_seg = m;
+ *in_off = bytes_to_copy;
+ }
+}
+
+int
+sfc_tso_do(struct sfc_txq *txq, unsigned int idx, struct rte_mbuf **in_seg,
+ size_t *in_off, efx_desc_t **pend, unsigned int *pkt_descs,
+ size_t *pkt_len)
+{
+ uint8_t *tsoh;
+ const struct tcp_hdr *th;
+ efsys_dma_addr_t header_paddr;
+ efsys_dma_addr_t paddr_next_frag;
+ uint16_t packet_id;
+ uint32_t sent_seq;
+ struct rte_mbuf *m = *in_seg;
+ size_t nh_off = m->l2_len; /* IP header offset */
+ size_t tcph_off = m->l2_len + m->l3_len; /* TCP header offset */
+ size_t header_len = m->l2_len + m->l3_len + m->l4_len;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(txq->evq->sa->nic);
+
+ idx += SFC_TSO_OPDESCS_IDX_SHIFT;
+
+ /* Packets which have too big headers should be discarded */
+ if (unlikely(header_len > SFC_TSOH_STD_LEN))
+ return EMSGSIZE;
+
+ /*
+ * The TCP header must start at most 208 bytes into the frame.
+ * If it starts later than this then the NIC won't realise
+ * it's a TCP packet and TSO edits won't be applied
+ */
+ if (unlikely(tcph_off > encp->enc_tx_tso_tcp_header_offset_limit))
+ return EMSGSIZE;
+
+ header_paddr = rte_pktmbuf_mtophys(m);
+ paddr_next_frag = P2ROUNDUP(header_paddr + 1, SFC_TX_SEG_BOUNDARY);
+
+ /*
+ * Sometimes headers may be split across multiple mbufs. In such cases
+ * we need to glue those pieces and store them in some temporary place.
+ * Also, packet headers must be contiguous in memory, so that
+ * they can be referred to with a single DMA descriptor. Hence, handle
+ * the case where the original header crosses a 4K memory boundary
+ */
+ if ((m->data_len < header_len) ||
+ ((paddr_next_frag - header_paddr) < header_len)) {
+ sfc_tso_prepare_header(txq, in_seg, in_off, idx, header_len);
+ tsoh = txq->sw_ring[idx & txq->ptr_mask].tsoh;
+
+ header_paddr = rte_malloc_virt2phy((void *)tsoh);
+ } else {
+ if (m->data_len == header_len) {
+ *in_off = 0;
+ *in_seg = m->next;
+ } else {
+ *in_off = header_len;
+ }
+
+ tsoh = rte_pktmbuf_mtod(m, uint8_t *);
+ }
+
+ /* Handle IP header */
+ if (m->ol_flags & PKT_TX_IPV4) {
+ const struct ipv4_hdr *iphe4;
+
+ iphe4 = (const struct ipv4_hdr *)(tsoh + nh_off);
+ rte_memcpy(&packet_id, &iphe4->packet_id, sizeof(uint16_t));
+ packet_id = rte_be_to_cpu_16(packet_id);
+ } else if (m->ol_flags & PKT_TX_IPV6) {
+ packet_id = 0;
+ } else {
+ return EINVAL;
+ }
+
+ /* Handle TCP header */
+ th = (const struct tcp_hdr *)(tsoh + tcph_off);
+
+ rte_memcpy(&sent_seq, &th->sent_seq, sizeof(uint32_t));
+ sent_seq = rte_be_to_cpu_32(sent_seq);
+
+ efx_tx_qdesc_tso2_create(txq->common, packet_id, sent_seq, m->tso_segsz,
+ *pend, EFX_TX_FATSOV2_OPT_NDESCS);
+
+ *pend += EFX_TX_FATSOV2_OPT_NDESCS;
+ *pkt_descs += EFX_TX_FATSOV2_OPT_NDESCS;
+
+ efx_tx_qdesc_dma_create(txq->common, header_paddr, header_len,
+ B_FALSE, (*pend)++);
+ (*pkt_descs)++;
+ *pkt_len -= header_len;
+
+ return 0;
+}
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 86bcfec..cb21f78 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -184,6 +184,12 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
if (txq->sw_ring == NULL)
goto fail_desc_alloc;
+ if (sa->tso) {
+ rc = sfc_tso_alloc_tsoh_objs(sa, sw_index, txq, socket_id);
+ if (rc != 0)
+ goto fail_alloc_tsoh_objs;
+ }
+
txq->state = SFC_TXQ_INITIALIZED;
txq->ptr_mask = txq_info->entries - 1;
txq->free_thresh = (tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
@@ -199,6 +205,9 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
return 0;
+fail_alloc_tsoh_objs:
+ rte_free(txq->sw_ring);
+
fail_desc_alloc:
rte_free(txq->pend_desc);
@@ -234,6 +243,8 @@ sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
SFC_ASSERT(txq != NULL);
SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
+ sfc_tso_free_tsoh_objs(sa, sw_index);
+
txq_info->txq = NULL;
txq_info->entries = 0;
@@ -300,6 +311,11 @@ sfc_tx_init(struct sfc_adapter *sa)
sa->txq_count = sa->eth_dev->data->nb_tx_queues;
+ if (sa->tso)
+ sa->txq_count = MIN(sa->txq_count,
+ efx_nic_cfg_get(sa->nic)->enc_fw_assisted_tso_v2_n_contexts /
+ efx_nic_cfg_get(sa->nic)->enc_hw_pf_count);
+
sa->txq_info = rte_calloc_socket("sfc-txqs", sa->txq_count,
sizeof(sa->txq_info[0]), 0,
sa->socket_id);
@@ -373,17 +389,25 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
* hence, we always enable it here
*/
if ((txq->flags & ETH_TXQ_FLAGS_NOXSUMTCP) ||
- (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP))
+ (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP)) {
flags = EFX_TXQ_CKSUM_IPV4;
- else
+ } else {
flags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;
+ if (sa->tso)
+ flags |= EFX_TXQ_FATSOV2;
+ }
+
rc = efx_tx_qcreate(sa->nic, sw_index, 0, &txq->mem,
txq_info->entries, 0 /* not used on EF10 */,
flags, evq->common,
&txq->common, &desc_index);
- if (rc != 0)
+ if (rc != 0) {
+ if (sa->tso && (rc == ENOSPC))
+ sfc_err(sa, "ran out of TSO contexts");
+
goto fail_tx_qcreate;
+ }
txq->added = txq->pending = txq->completed = desc_index;
txq->hw_vlan_tci = 0;
@@ -494,6 +518,13 @@ sfc_tx_start(struct sfc_adapter *sa)
sfc_log_init(sa, "txq_count = %u", sa->txq_count);
+ if (sa->tso) {
+ if (!efx_nic_cfg_get(sa->nic)->enc_fw_assisted_tso_v2_enabled) {
+ sfc_warn(sa, "TSO support was unable to be restored");
+ sa->tso = B_FALSE;
+ }
+ }
+
rc = efx_tx_init(sa->nic);
if (rc != 0)
goto fail_efx_tx_init;
@@ -607,6 +638,7 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
struct rte_mbuf *m_seg = *pktp;
size_t pkt_len = m_seg->pkt_len;
unsigned int pkt_descs = 0;
+ size_t in_off = 0;
/*
* Here VLAN TCI is expected to be zero in case if no
@@ -617,6 +649,46 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
*/
pkt_descs += sfc_tx_maybe_insert_tag(txq, m_seg, &pend);
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+ if (m_seg->ol_flags & PKT_TX_TCP_SEG) {
+ /*
+ * We expect correct 'pkt->l[2, 3, 4]_len' values
+ * to be set correctly by the caller
+ */
+ if (sfc_tso_do(txq, added, &m_seg, &in_off, &pend,
+ &pkt_descs, &pkt_len) != 0) {
+ /* We may have reached this place for
+ * one of the following reasons:
+ *
+ * 1) Packet header length is greater
+ * than SFC_TSOH_STD_LEN
+ * 2) TCP header starts at more then
+ * 208 bytes into the frame
+ *
+ * We will deceive RTE saying that we have sent
+ * the packet, but we will actually drop it.
+ * Hence, we should revert 'pend' to the
+ * previous state (in case we have added
+ * VLAN descriptor) and start processing
+ * another one packet. But the original
+ * mbuf shouldn't be orphaned
+ */
+ pend -= pkt_descs;
+
+ rte_pktmbuf_free(*pktp);
+
+ continue;
+ }
+
+ /*
+ * We've only added 2 FATSOv2 option descriptors
+ * and 1 descriptor for the linearized packet header.
+ * The outstanding work will be done in the same manner
+ * as for the usual non-TSO path
+ */
+ }
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
+
for (; m_seg != NULL; m_seg = m_seg->next) {
efsys_dma_addr_t next_frag;
size_t seg_len;
@@ -624,6 +696,16 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
seg_len = m_seg->data_len;
next_frag = rte_mbuf_data_dma_addr(m_seg);
+ /*
+ * If we've started TSO transaction few steps earlier,
+ * we'll skip packet header using an offset in the
+ * current segment (which has been set to the
+ * first one containing payload)
+ */
+ seg_len -= in_off;
+ next_frag += in_off;
+ in_off = 0;
+
do {
efsys_dma_addr_t frag_addr = next_frag;
size_t frag_len;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 4d25c6a..d4298e4 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -50,6 +50,9 @@ struct sfc_evq;
struct sfc_tx_sw_desc {
struct rte_mbuf *mbuf;
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+ uint8_t *tsoh; /* Buffer to store TSO header */
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
};
enum sfc_txq_state_bit {
@@ -113,6 +116,31 @@ void sfc_tx_stop(struct sfc_adapter *sa);
uint16_t sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+/* From 'sfc_tso.c' */
+int sfc_tso_alloc_tsoh_objs(struct sfc_adapter *sa, unsigned int sw_index,
+ struct sfc_txq *txq, unsigned int socket_id);
+void sfc_tso_free_tsoh_objs(struct sfc_adapter *sa, unsigned int sw_index);
+int sfc_tso_do(struct sfc_txq *txq, unsigned int idx, struct rte_mbuf **in_seg,
+ size_t *in_off, efx_desc_t **pend, unsigned int *pkt_descs,
+ size_t *pkt_len);
+#else /* !RTE_LIBRTE_SFC_EFX_TSO */
+static inline int
+sfc_tso_alloc_tsoh_objs(__rte_unused struct sfc_adapter *sa,
+ __rte_unused unsigned int sw_index,
+ __rte_unused struct sfc_txq *txq,
+ __rte_unused unsigned int socket_id)
+{
+ return 0;
+}
+
+static inline void
+sfc_tso_free_tsoh_objs(__rte_unused struct sfc_adapter *sa,
+ __rte_unused unsigned int sw_index)
+{
+}
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (30 preceding siblings ...)
2016-12-02 7:44 ` [dpdk-dev] [PATCH 31/31] net/sfc: support firmware-assisted TSOv2 Andrew Rybchenko
@ 2016-12-09 17:34 ` Ferruh Yigit
2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
32 siblings, 1 reply; 70+ messages in thread
From: Ferruh Yigit @ 2016-12-09 17:34 UTC (permalink / raw)
To: Andrew Rybchenko, dev
On 12/2/2016 7:44 AM, Andrew Rybchenko wrote:
> The patch series adds a number of features to Solarflare libefx-based
> PMD. Basically one patch per feature.
>
> The patches are grouped into one series since they touch nearby lines
> in either PMD feature list, or dev_ops structure, or documentation.
> So, patches cannot be applied in arbitrary order.
>
> The patch series should be applied after
> [PATCH v2 00/55] Solarflare libefx-based PMD
> (Message-ID: 1480436367-20749-1-git-send-email-arybchenko@solarflare.com)
>
>
> Andrew Rybchenko (16):
> net/sfc: implement MCDI logging callback
> net/sfc: support parameter to choose performance profile
> net/sfc: implement ethdev hook to get basic statistics
> net/sfc: support extended statistics
> net/sfc: support flow control settings get/set
> net/sfc: support link status change interrupt
> net/sfc: implement device operation to change MTU
> net/sfc: support link speed and duplex settings
> net/sfc: support checksum offloads on receive
> net/sfc: handle received packet type info provided by HW
> net/sfc: support callback to get receive queue information
> net/sfc: support Rx free threshold
> net/sfc: add callback to get RxQ pending descriptors count
> net/sfc: add RxQ descriptor done callback
> net/sfc: support scattered Rx DMA
> net/sfc: support deferred start of receive queues
>
> Artem Andreev (1):
> net/sfc: support link up/down
>
> Ivan Malov (14):
> net/sfc: support promiscuous and all-multicast control
> net/sfc: support main (the first) MAC address change
> net/sfc: support multicast addresses list controls
> net/sfc: add callback to get transmit queue information
> net/sfc: support Tx free threshold
> net/sfc: support deferred start of transmit queues
> net/sfc: support VLAN offload on transmit path
> net/sfc: add basic stubs for RSS support on driver attach
> net/sfc: support RSS hash offload
> net/sfc: add callback to query RSS key and hash types config
> net/sfc: add callback to set RSS key and hash types config
> net/sfc: add callback to query RSS redirection table
> net/sfc: add callback to update RSS redirection table
> net/sfc: support firmware-assisted TSOv2
Hi Andrew,
I am getting following build errors for clang [1] and ICC [2]. I have
not investigated the root cause, just copy-pasting here.
For ICC, since you explicitly noted it is not supported, and reported
warning is known, I believe it is safe the ignore this warning via
"-wd188" CFLAGS option in the Makefile.
Thanks,
ferruh
[1] clang
.../drivers/net/sfc/sfc_ethdev.c:1143:4: error: format specifies type
'unsigned short' but the argument has type 'int' [-Werror,-Wformat]
EFX_RSS_TBL_SIZE);
^~~~~~~~~~~~~~~~
.../drivers/net/sfc/base/efx.h:1866:26: note: expanded from macro
'EFX_RSS_TBL_SIZE'
#define EFX_RSS_TBL_SIZE 128 /* Rows in RX indirection table */
^~~
.../drivers/net/sfc/sfc_log.h:51:19: note: expanded from macro 'sfc_err'
SFC_LOG(sa, ERR, __VA_ARGS__)
^~~~~~~~~~~
.../drivers/net/sfc/sfc_log.h:47:18: note: expanded from macro 'SFC_LOG'
RTE_FMT_TAIL(__VA_ARGS__,))); \
^~~~~~~~~~~
.../x86_64-native-linuxapp-clang/include/rte_common.h:345:32: note:
expanded from macro 'RTE_FMT_TAIL'
#define RTE_FMT_TAIL(fmt, ...) __VA_ARGS__
^~~~~~~~~~~
.../x86_64-native-linuxapp-clang/include/rte_common.h:343:39: note:
expanded from macro 'RTE_FMT'
#define RTE_FMT(fmt, ...) fmt "%.0s", __VA_ARGS__ ""
^~~~~~~~~~~
.../x86_64-native-linuxapp-clang/include/rte_log.h:258:32: note:
expanded from macro 'RTE_LOG'
RTE_LOGTYPE_ ## t, # t ": " __VA_ARGS__)
^~~~~~~~~~~
[2] ICC
.../drivers/net/sfc/sfc_ethdev.c(1063): error #188: enumerated type
mixed with another type
efx_hash_types, B_TRUE);
^
.../drivers/net/sfc/sfc_ethdev.c(1086): error #188: enumerated type
mixed with another type
sa->rss_hash_types, B_TRUE) != 0)
^
compilation aborted for .../drivers/net/sfc/sfc_ethdev.c (code 2)
make[7]: *** [sfc_ethdev.o] Error 2
make[7]: *** Waiting for unfinished jobs....
.../drivers/net/sfc/sfc_rx.c(820): error #188: enumerated type mixed
with another type
sa->rss_hash_types, B_TRUE);
^
compilation aborted for .../drivers/net/sfc/sfc_rx.c (code 2)
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD
2016-12-09 17:34 ` [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Ferruh Yigit
@ 2016-12-15 12:50 ` Andrew Rybchenko
0 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: Ferruh Yigit, dev
On 12/09/2016 08:34 PM, Ferruh Yigit wrote:
> On 12/2/2016 7:44 AM, Andrew Rybchenko wrote:
>> The patch series adds a number of features to Solarflare libefx-based
>> PMD. Basically one patch per feature.
>>
>> The patches are grouped into one series since they touch nearby lines
>> in either PMD feature list, or dev_ops structure, or documentation.
>> So, patches cannot be applied in arbitrary order.
>>
>> The patch series should be applied after
>> [PATCH v2 00/55] Solarflare libefx-based PMD
>> (Message-ID: 1480436367-20749-1-git-send-email-arybchenko@solarflare.com)
>>
>>
>> Andrew Rybchenko (16):
>> net/sfc: implement MCDI logging callback
>> net/sfc: support parameter to choose performance profile
>> net/sfc: implement ethdev hook to get basic statistics
>> net/sfc: support extended statistics
>> net/sfc: support flow control settings get/set
>> net/sfc: support link status change interrupt
>> net/sfc: implement device operation to change MTU
>> net/sfc: support link speed and duplex settings
>> net/sfc: support checksum offloads on receive
>> net/sfc: handle received packet type info provided by HW
>> net/sfc: support callback to get receive queue information
>> net/sfc: support Rx free threshold
>> net/sfc: add callback to get RxQ pending descriptors count
>> net/sfc: add RxQ descriptor done callback
>> net/sfc: support scattered Rx DMA
>> net/sfc: support deferred start of receive queues
>>
>> Artem Andreev (1):
>> net/sfc: support link up/down
>>
>> Ivan Malov (14):
>> net/sfc: support promiscuous and all-multicast control
>> net/sfc: support main (the first) MAC address change
>> net/sfc: support multicast addresses list controls
>> net/sfc: add callback to get transmit queue information
>> net/sfc: support Tx free threshold
>> net/sfc: support deferred start of transmit queues
>> net/sfc: support VLAN offload on transmit path
>> net/sfc: add basic stubs for RSS support on driver attach
>> net/sfc: support RSS hash offload
>> net/sfc: add callback to query RSS key and hash types config
>> net/sfc: add callback to set RSS key and hash types config
>> net/sfc: add callback to query RSS redirection table
>> net/sfc: add callback to update RSS redirection table
>> net/sfc: support firmware-assisted TSOv2
> Hi Andrew,
>
> I am getting following build errors for clang [1] and ICC [2]. I have
> not investigated the root cause, just copy-pasting here.
>
> For ICC, since you explicitly noted it is not supported, and reported
> warning is known, I believe it is safe the ignore this warning via
> "-wd188" CFLAGS option in the Makefile.
Hi Ferruh,
I think I prefer to fix these warnings in v2. May be other compilers
will become more pedantic in the future.
Thanks,
Andrew.
>
> Thanks,
> ferruh
>
>
>
> [1] clang
> .../drivers/net/sfc/sfc_ethdev.c:1143:4: error: format specifies type
> 'unsigned short' but the argument has type 'int' [-Werror,-Wformat]
> EFX_RSS_TBL_SIZE);
> ^~~~~~~~~~~~~~~~
> .../drivers/net/sfc/base/efx.h:1866:26: note: expanded from macro
> 'EFX_RSS_TBL_SIZE'
> #define EFX_RSS_TBL_SIZE 128 /* Rows in RX indirection table */
> ^~~
> .../drivers/net/sfc/sfc_log.h:51:19: note: expanded from macro 'sfc_err'
> SFC_LOG(sa, ERR, __VA_ARGS__)
> ^~~~~~~~~~~
> .../drivers/net/sfc/sfc_log.h:47:18: note: expanded from macro 'SFC_LOG'
> RTE_FMT_TAIL(__VA_ARGS__,))); \
> ^~~~~~~~~~~
> .../x86_64-native-linuxapp-clang/include/rte_common.h:345:32: note:
> expanded from macro 'RTE_FMT_TAIL'
> #define RTE_FMT_TAIL(fmt, ...) __VA_ARGS__
> ^~~~~~~~~~~
> .../x86_64-native-linuxapp-clang/include/rte_common.h:343:39: note:
> expanded from macro 'RTE_FMT'
> #define RTE_FMT(fmt, ...) fmt "%.0s", __VA_ARGS__ ""
> ^~~~~~~~~~~
> .../x86_64-native-linuxapp-clang/include/rte_log.h:258:32: note:
> expanded from macro 'RTE_LOG'
> RTE_LOGTYPE_ ## t, # t ": " __VA_ARGS__)
> ^~~~~~~~~~~
>
>
>
> [2] ICC
> .../drivers/net/sfc/sfc_ethdev.c(1063): error #188: enumerated type
> mixed with another type
> efx_hash_types, B_TRUE);
> ^
>
> .../drivers/net/sfc/sfc_ethdev.c(1086): error #188: enumerated type
> mixed with another type
> sa->rss_hash_types, B_TRUE) != 0)
> ^
>
> compilation aborted for .../drivers/net/sfc/sfc_ethdev.c (code 2)
> make[7]: *** [sfc_ethdev.o] Error 2
> make[7]: *** Waiting for unfinished jobs....
> .../drivers/net/sfc/sfc_rx.c(820): error #188: enumerated type mixed
> with another type
> sa->rss_hash_types, B_TRUE);
> ^
>
> compilation aborted for .../drivers/net/sfc/sfc_rx.c (code 2)
>
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 00/32] Support more features in Solarflare PMD
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
` (31 preceding siblings ...)
2016-12-09 17:34 ` [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Ferruh Yigit
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 01/32] net/sfc: implement MCDI logging callback Andrew Rybchenko
` (32 more replies)
32 siblings, 33 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
The patch series adds a number of features to Solarflare libefx-based
PMD. Basically one patch per feature.
The patches are grouped into one series since they touch nearby lines
in either PMD feature list, or dev_ops structure, or documentation.
So, patches cannot be applied in arbitrary order.
---
v2:
* Fix ICC and clang warnings
* Slightly change sfc_tso_{alloc,free}_tsoh_objs() prototypes
Andrew Rybchenko (17):
net/sfc: implement MCDI logging callback
net/sfc: support parameter to choose performance profile
net/sfc: implement ethdev hook to get basic statistics
net/sfc: support extended statistics
net/sfc: support flow control settings get/set
net/sfc: support link status change interrupt
net/sfc: implement device operation to change MTU
net/sfc: support link speed and duplex settings
net/sfc: support checksum offloads on receive
net/sfc: handle received packet type info provided by HW
net/sfc: support callback to get receive queue information
net/sfc: support Rx free threshold
net/sfc: add callback to get RxQ pending descriptors count
net/sfc: add RxQ descriptor done callback
net/sfc: support scattered Rx DMA
net/sfc: support deferred start of receive queues
net/sfc/base: do not use enum type when values are bitmask
Artem Andreev (1):
net/sfc: support link up/down
Ivan Malov (14):
net/sfc: support promiscuous and all-multicast control
net/sfc: support main (the first) MAC address change
net/sfc: support multicast addresses list controls
net/sfc: add callback to get transmit queue information
net/sfc: support Tx free threshold
net/sfc: support deferred start of transmit queues
net/sfc: support VLAN offload on transmit path
net/sfc: add basic stubs for RSS support on driver attach
net/sfc: support RSS hash offload
net/sfc: add callback to query RSS key and hash types config
net/sfc: add callback to set RSS key and hash types config
net/sfc: add callback to query RSS redirection table
net/sfc: add callback to update RSS redirection table
net/sfc: support firmware-assisted TSOv2
config/common_base | 1 +
doc/guides/nics/features/sfc_efx.ini | 22 +-
doc/guides/nics/sfc_efx.rst | 58 ++-
drivers/net/sfc/Makefile | 4 +
drivers/net/sfc/base/ef10_rx.c | 8 +-
drivers/net/sfc/base/efx.h | 12 +-
drivers/net/sfc/base/efx_rx.c | 8 +-
drivers/net/sfc/efsys.h | 8 +-
drivers/net/sfc/sfc.c | 126 ++++-
drivers/net/sfc/sfc.h | 46 ++
drivers/net/sfc/sfc_ethdev.c | 893 ++++++++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_ev.c | 64 ++-
drivers/net/sfc/sfc_ev.h | 2 +
drivers/net/sfc/sfc_intr.c | 204 ++++++++
drivers/net/sfc/sfc_kvargs.c | 2 +
drivers/net/sfc/sfc_kvargs.h | 12 +
drivers/net/sfc/sfc_mcdi.c | 69 +++
drivers/net/sfc/sfc_port.c | 107 ++++-
drivers/net/sfc/sfc_rx.c | 288 ++++++++++-
drivers/net/sfc/sfc_rx.h | 16 +
drivers/net/sfc/sfc_tso.c | 200 ++++++++
drivers/net/sfc/sfc_tweak.h | 3 +
drivers/net/sfc/sfc_tx.c | 166 ++++++-
drivers/net/sfc/sfc_tx.h | 41 +-
24 files changed, 2274 insertions(+), 86 deletions(-)
create mode 100644 drivers/net/sfc/sfc_tso.c
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 01/32] net/sfc: implement MCDI logging callback
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 02/32] net/sfc: support parameter to choose performance profile Andrew Rybchenko
` (31 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/sfc_efx.rst | 6 ++++
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc.h | 1 +
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_kvargs.c | 1 +
drivers/net/sfc/sfc_kvargs.h | 2 ++
drivers/net/sfc/sfc_mcdi.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index aadd775..2cca287 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -155,3 +155,9 @@ boolean parameters value.
- ``debug_init`` [bool] (default **n**)
Enable extra logging during device intialization and startup.
+
+- ``mcdi_logging`` [bool] (default **n**)
+
+ Enable extra logging of the communication with the NIC's management CPU.
+ The logging is done using RTE_LOG() with INFO level and PMD type.
+ The format is consumed by the Solarflare netlogdecode cross-platform tool.
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index e4d5035..d48eb4c 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -175,7 +175,7 @@ prefetch_read_once(const volatile void *addr)
/* MCDI is required for SFN7xxx and SFN8xx */
#define EFSYS_OPT_MCDI 1
-#define EFSYS_OPT_MCDI_LOGGING 0
+#define EFSYS_OPT_MCDI_LOGGING 1
#define EFSYS_OPT_MCDI_PROXY_AUTH 0
#define EFSYS_OPT_MAC_STATS 0
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 995dfe6..46c6fb6 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -107,6 +107,7 @@ struct sfc_mcdi {
efsys_mem_t mem;
enum sfc_mcdi_state state;
efx_mcdi_transport_t transport;
+ bool logging;
};
struct sfc_intr {
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c28082c..12309ee 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -464,4 +464,5 @@ static struct eth_driver sfc_efx_pmd = {
RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
+ SFC_KVARG_MCDI_LOGGING "=" SFC_KVARG_VALUES_BOOL " "
SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);
diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c
index f1bab28..bbbd026 100644
--- a/drivers/net/sfc/sfc_kvargs.c
+++ b/drivers/net/sfc/sfc_kvargs.c
@@ -42,6 +42,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa)
struct rte_devargs *devargs = sa->eth_dev->pci_dev->device.devargs;
const char **params = (const char *[]){
SFC_KVARG_DEBUG_INIT,
+ SFC_KVARG_MCDI_LOGGING,
NULL,
};
diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h
index 0b53963..ffce851 100644
--- a/drivers/net/sfc/sfc_kvargs.h
+++ b/drivers/net/sfc/sfc_kvargs.h
@@ -40,6 +40,8 @@ extern "C" {
#define SFC_KVARG_DEBUG_INIT "debug_init"
+#define SFC_KVARG_MCDI_LOGGING "mcdi_logging"
+
struct sfc_adapter;
int sfc_kvargs_parse(struct sfc_adapter *sa);
diff --git a/drivers/net/sfc/sfc_mcdi.c b/drivers/net/sfc/sfc_mcdi.c
index 9ba28e1..3bed2e0 100644
--- a/drivers/net/sfc/sfc_mcdi.c
+++ b/drivers/net/sfc/sfc_mcdi.c
@@ -35,6 +35,7 @@
#include "sfc.h"
#include "sfc_log.h"
+#include "sfc_kvargs.h"
#define SFC_MCDI_POLL_INTERVAL_MIN_US 10 /* 10us in 1us units */
#define SFC_MCDI_POLL_INTERVAL_MAX_US (US_PER_S / 10) /* 100ms in 1us units */
@@ -125,6 +126,65 @@ sfc_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
sfc_panic(sa, "MCDI exceptions handling is not implemented\n");
}
+#define SFC_MCDI_LOG_BUF_SIZE 128
+
+static size_t
+sfc_mcdi_do_log(const struct sfc_adapter *sa,
+ char *buffer, void *data, size_t data_size,
+ size_t pfxsize, size_t position)
+{
+ uint32_t *words = data;
+ /* Space separator plus 2 characters per byte */
+ const size_t word_str_space = 1 + 2 * sizeof(*words);
+ size_t i;
+
+ for (i = 0; i < data_size; i += sizeof(*words)) {
+ if (position + word_str_space >=
+ SFC_MCDI_LOG_BUF_SIZE) {
+ /* Flush at SFC_MCDI_LOG_BUF_SIZE with backslash
+ * at the end which is required by netlogdecode.
+ */
+ buffer[position] = '\0';
+ sfc_info(sa, "%s \\", buffer);
+ /* Preserve prefix for the next log message */
+ position = pfxsize;
+ }
+ position += snprintf(buffer + position,
+ SFC_MCDI_LOG_BUF_SIZE - position,
+ " %08x", *words);
+ words++;
+ }
+ return position;
+}
+
+static void
+sfc_mcdi_logger(void *arg, efx_log_msg_t type,
+ void *header, size_t header_size,
+ void *data, size_t data_size)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)arg;
+ char buffer[SFC_MCDI_LOG_BUF_SIZE];
+ size_t pfxsize;
+ size_t start;
+
+ if (!sa->mcdi.logging)
+ return;
+
+ /* The format including prefix added by sfc_info() is the format
+ * consumed by the Solarflare netlogdecode tool.
+ */
+ pfxsize = snprintf(buffer, sizeof(buffer), "MCDI RPC %s:",
+ type == EFX_LOG_MCDI_REQUEST ? "REQ" :
+ type == EFX_LOG_MCDI_RESPONSE ? "RESP" : "???");
+ start = sfc_mcdi_do_log(sa, buffer, header, header_size,
+ pfxsize, pfxsize);
+ start = sfc_mcdi_do_log(sa, buffer, data, data_size, pfxsize, start);
+ if (start != pfxsize) {
+ buffer[start] = '\0';
+ sfc_info(sa, "%s", buffer);
+ }
+}
+
int
sfc_mcdi_init(struct sfc_adapter *sa)
{
@@ -149,12 +209,19 @@ sfc_mcdi_init(struct sfc_adapter *sa)
if (rc != 0)
goto fail_dma_alloc;
+ /* Convert negative error to positive used in the driver */
+ rc = sfc_kvargs_process(sa, SFC_KVARG_MCDI_LOGGING,
+ sfc_kvarg_bool_handler, &mcdi->logging);
+ if (rc != 0)
+ goto fail_kvargs_process;
+
emtp = &mcdi->transport;
emtp->emt_context = sa;
emtp->emt_dma_mem = &mcdi->mem;
emtp->emt_execute = sfc_mcdi_execute;
emtp->emt_ev_cpl = sfc_mcdi_ev_cpl;
emtp->emt_exception = sfc_mcdi_exception;
+ emtp->emt_logger = sfc_mcdi_logger;
sfc_log_init(sa, "init MCDI");
rc = efx_mcdi_init(sa->nic, emtp);
@@ -165,6 +232,8 @@ sfc_mcdi_init(struct sfc_adapter *sa)
fail_mcdi_init:
memset(emtp, 0, sizeof(*emtp));
+
+fail_kvargs_process:
sfc_dma_free(sa, &mcdi->mem);
fail_dma_alloc:
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 02/32] net/sfc: support parameter to choose performance profile
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 01/32] net/sfc: implement MCDI logging callback Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 03/32] net/sfc: implement ethdev hook to get basic statistics Andrew Rybchenko
` (30 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Supported options are auto (based on NIC firmware variant and
installed licences), throughput, low-latency.
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/sfc_efx.rst | 7 +++++++
drivers/net/sfc/sfc.h | 1 +
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_ev.c | 36 +++++++++++++++++++++++++++++++++---
drivers/net/sfc/sfc_ev.h | 2 ++
drivers/net/sfc/sfc_kvargs.c | 1 +
drivers/net/sfc/sfc_kvargs.h | 10 ++++++++++
7 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 2cca287..36d0974 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -152,6 +152,13 @@ whitelist option like "-w 02:00.0,arg1=value1,...".
Case-insensitive 1/y/yes/on or 0/n/no/off may be used to specify
boolean parameters value.
+- ``perf_profile`` [auto|throughput|low-latency] (default **throughput**)
+
+ Choose hardware tunning to be optimized for either throughput or
+ low-latency.
+ **auto** allows NIC firmware to make a choice based on
+ installed licences and firmware variant configured using **sfboot**.
+
- ``debug_init`` [bool] (default **n**)
Enable extra logging during device intialization and startup.
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 46c6fb6..00b186f 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -152,6 +152,7 @@ struct sfc_adapter {
unsigned int txq_max_entries;
+ uint32_t evq_flags;
unsigned int evq_count;
struct sfc_evq_info *evq_info;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 12309ee..1df227e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -464,5 +464,6 @@ static struct eth_driver sfc_efx_pmd = {
RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
+ SFC_KVARG_PERF_PROFILE "=" SFC_KVARG_VALUES_PERF_PROFILE " "
SFC_KVARG_MCDI_LOGGING "=" SFC_KVARG_VALUES_BOOL " "
SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index af3c7b2..de42845 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -40,6 +40,7 @@
#include "sfc_ev.h"
#include "sfc_rx.h"
#include "sfc_tx.h"
+#include "sfc_kvargs.h"
/* Initial delay when waiting for event queue init complete event */
@@ -405,9 +406,7 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
/* Create the common code event queue */
rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq_info->entries,
- 0 /* unused on EF10 */, 0,
- EFX_EVQ_FLAGS_TYPE_THROUGHPUT |
- EFX_EVQ_FLAGS_NOTIFY_DISABLED,
+ 0 /* unused on EF10 */, 0, evq_info->flags,
&evq->common);
if (rc != 0)
goto fail_ev_qcreate;
@@ -640,6 +639,25 @@ sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
SFC_ASSERT(rte_is_power_of_2(max_entries));
evq_info->max_entries = max_entries;
+ evq_info->flags = sa->evq_flags | EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+
+ return 0;
+}
+
+static int
+sfc_kvarg_perf_profile_handler(__rte_unused const char *key,
+ const char *value_str, void *opaque)
+{
+ uint64_t *value = opaque;
+
+ if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_THROUGHPUT) == 0)
+ *value = EFX_EVQ_FLAGS_TYPE_THROUGHPUT;
+ else if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_LOW_LATENCY) == 0)
+ *value = EFX_EVQ_FLAGS_TYPE_LOW_LATENCY;
+ else if (strcasecmp(value_str, SFC_KVARG_PERF_PROFILE_AUTO) == 0)
+ *value = EFX_EVQ_FLAGS_TYPE_AUTO;
+ else
+ return -EINVAL;
return 0;
}
@@ -660,6 +678,16 @@ sfc_ev_init(struct sfc_adapter *sa)
sfc_log_init(sa, "entry");
+ sa->evq_flags = EFX_EVQ_FLAGS_TYPE_THROUGHPUT;
+ rc = sfc_kvargs_process(sa, SFC_KVARG_PERF_PROFILE,
+ sfc_kvarg_perf_profile_handler,
+ &sa->evq_flags);
+ if (rc != 0) {
+ sfc_err(sa, "invalid %s parameter value",
+ SFC_KVARG_PERF_PROFILE);
+ goto fail_kvarg_perf_profile;
+ }
+
sa->evq_count = sfc_ev_qcount(sa);
sa->mgmt_evq_index = 0;
rte_spinlock_init(&sa->mgmt_evq_lock);
@@ -700,6 +728,8 @@ sfc_ev_init(struct sfc_adapter *sa)
fail_evqs_alloc:
sa->evq_count = 0;
+
+fail_kvarg_perf_profile:
sfc_log_init(sa, "failed %d", rc);
return rc;
}
diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h
index 110f3b6..346e3ec 100644
--- a/drivers/net/sfc/sfc_ev.h
+++ b/drivers/net/sfc/sfc_ev.h
@@ -74,6 +74,8 @@ struct sfc_evq_info {
unsigned int max_entries;
/* Real number of EVQ entries, less or equal to max_entries */
unsigned int entries;
+ /* Event queue creation flags */
+ uint32_t flags;
/* NUMA-aware EVQ data structure used on datapath */
struct sfc_evq *evq;
};
diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c
index bbbd026..2ced47c 100644
--- a/drivers/net/sfc/sfc_kvargs.c
+++ b/drivers/net/sfc/sfc_kvargs.c
@@ -43,6 +43,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa)
const char **params = (const char *[]){
SFC_KVARG_DEBUG_INIT,
SFC_KVARG_MCDI_LOGGING,
+ SFC_KVARG_PERF_PROFILE,
NULL,
};
diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h
index ffce851..2fea9c7 100644
--- a/drivers/net/sfc/sfc_kvargs.h
+++ b/drivers/net/sfc/sfc_kvargs.h
@@ -42,6 +42,16 @@ extern "C" {
#define SFC_KVARG_MCDI_LOGGING "mcdi_logging"
+#define SFC_KVARG_PERF_PROFILE "perf_profile"
+
+#define SFC_KVARG_PERF_PROFILE_AUTO "auto"
+#define SFC_KVARG_PERF_PROFILE_THROUGHPUT "throughput"
+#define SFC_KVARG_PERF_PROFILE_LOW_LATENCY "low-latency"
+#define SFC_KVARG_VALUES_PERF_PROFILE \
+ "[" SFC_KVARG_PERF_PROFILE_AUTO "|" \
+ SFC_KVARG_PERF_PROFILE_THROUGHPUT "|" \
+ SFC_KVARG_PERF_PROFILE_LOW_LATENCY "]"
+
struct sfc_adapter;
int sfc_kvargs_parse(struct sfc_adapter *sa);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 03/32] net/sfc: implement ethdev hook to get basic statistics
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 01/32] net/sfc: implement MCDI logging callback Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 02/32] net/sfc: support parameter to choose performance profile Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 04/32] net/sfc: support extended statistics Andrew Rybchenko
` (29 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Does not implement any deprecated statistics.
No per-queue statistics yet.
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 +
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc.h | 7 ++++
drivers/net/sfc/sfc_ethdev.c | 69 +++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 75 ++++++++++++++++++++++++++++++++++++
6 files changed, 155 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 67df1c6..f55a988 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,6 +7,7 @@
Link status = Y
L3 checksum offload = P
L4 checksum offload = P
+Basic stats = Y
BSD nic_uio = Y
Linux UIO = Y
Linux VFIO = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 36d0974..cbb51de 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
+- Port hardware statistics
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index d48eb4c..fe8615f 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -178,7 +178,7 @@ prefetch_read_once(const volatile void *addr)
#define EFSYS_OPT_MCDI_LOGGING 1
#define EFSYS_OPT_MCDI_PROXY_AUTH 0
-#define EFSYS_OPT_MAC_STATS 0
+#define EFSYS_OPT_MAC_STATS 1
#define EFSYS_OPT_LOOPBACK 0
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 00b186f..e9f5183 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -122,6 +122,12 @@ struct sfc_port {
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
+
+ rte_spinlock_t mac_stats_lock;
+ uint64_t *mac_stats_buf;
+ efsys_mem_t mac_stats_dma_mem;
+
+ uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES];
};
/* Adapter private data */
@@ -235,6 +241,7 @@ int sfc_port_start(struct sfc_adapter *sa);
void sfc_port_stop(struct sfc_adapter *sa);
void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info);
+int sfc_port_update_mac_stats(struct sfc_adapter *sa);
#ifdef __cplusplus
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1df227e..f31330c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -324,12 +324,81 @@ sfc_tx_queue_release(void *queue)
sfc_adapter_unlock(sa);
}
+static void
+sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ uint64_t *mac_stats;
+
+ rte_spinlock_lock(&port->mac_stats_lock);
+
+ if (sfc_port_update_mac_stats(sa) != 0)
+ goto unlock;
+
+ mac_stats = port->mac_stats_buf;
+
+ if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask,
+ EFX_MAC_VADAPTER_RX_UNICAST_PACKETS)) {
+ stats->ipackets =
+ mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS];
+ stats->opackets =
+ mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS] +
+ mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS];
+ stats->ibytes =
+ mac_stats[EFX_MAC_VADAPTER_RX_UNICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES];
+ stats->obytes =
+ mac_stats[EFX_MAC_VADAPTER_TX_UNICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES] +
+ mac_stats[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES];
+ stats->imissed = mac_stats[EFX_MAC_VADAPTER_RX_OVERFLOW];
+ stats->ierrors = mac_stats[EFX_MAC_VADAPTER_RX_BAD_PACKETS];
+ stats->oerrors = mac_stats[EFX_MAC_VADAPTER_TX_BAD_PACKETS];
+ } else {
+ stats->ipackets = mac_stats[EFX_MAC_RX_PKTS];
+ stats->opackets = mac_stats[EFX_MAC_TX_PKTS];
+ stats->ibytes = mac_stats[EFX_MAC_RX_OCTETS];
+ stats->obytes = mac_stats[EFX_MAC_TX_OCTETS];
+ /*
+ * Take into account stats which are whenever supported
+ * on EF10. If some stat is not supported by current
+ * firmware variant or HW revision, it is guaranteed
+ * to be zero in mac_stats.
+ */
+ stats->imissed =
+ mac_stats[EFX_MAC_RX_NODESC_DROP_CNT] +
+ mac_stats[EFX_MAC_PM_TRUNC_BB_OVERFLOW] +
+ mac_stats[EFX_MAC_PM_DISCARD_BB_OVERFLOW] +
+ mac_stats[EFX_MAC_PM_TRUNC_VFIFO_FULL] +
+ mac_stats[EFX_MAC_PM_DISCARD_VFIFO_FULL] +
+ mac_stats[EFX_MAC_PM_TRUNC_QBB] +
+ mac_stats[EFX_MAC_PM_DISCARD_QBB] +
+ mac_stats[EFX_MAC_PM_DISCARD_MAPPING] +
+ mac_stats[EFX_MAC_RXDP_Q_DISABLED_PKTS] +
+ mac_stats[EFX_MAC_RXDP_DI_DROPPED_PKTS];
+ stats->ierrors =
+ mac_stats[EFX_MAC_RX_FCS_ERRORS] +
+ mac_stats[EFX_MAC_RX_ALIGN_ERRORS] +
+ mac_stats[EFX_MAC_RX_JABBER_PKTS];
+ /* no oerrors counters supported on EF10 */
+ }
+
+unlock:
+ rte_spinlock_unlock(&port->mac_stats_lock);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
.dev_stop = sfc_dev_stop,
.dev_close = sfc_dev_close,
.link_update = sfc_dev_link_update,
+ .stats_get = sfc_stats_get,
.dev_infos_get = sfc_dev_infos_get,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index c124181..d8ff097 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -32,6 +32,34 @@
#include "sfc.h"
#include "sfc_log.h"
+/**
+ * Update MAC statistics in the buffer.
+ *
+ * @param sa Adapter
+ *
+ * @return Status code
+ * @retval 0 Success
+ * @retval EAGAIN Try again
+ * @retval ENOMEM Memory allocation failure
+ */
+int
+sfc_port_update_mac_stats(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ int rc;
+
+ SFC_ASSERT(rte_spinlock_is_locked(&port->mac_stats_lock));
+
+ if (sa->state != SFC_ADAPTER_STARTED)
+ return EINVAL;
+
+ rc = efx_mac_stats_update(sa->nic, &port->mac_stats_dma_mem,
+ port->mac_stats_buf, NULL);
+ if (rc != 0)
+ return rc;
+
+ return 0;
+}
int
sfc_port_start(struct sfc_adapter *sa)
@@ -67,6 +95,19 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mac_filter_set;
+ efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
+ sizeof(port->mac_stats_mask));
+
+ /* Update MAC stats using periodic DMA.
+ * Common code always uses 1000ms update period, so period_ms
+ * parameter only needs to be non-zero to start updates.
+ */
+ sfc_log_init(sa, "request MAC stats DMA'ing");
+ rc = efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
+ 1000, B_FALSE);
+ if (rc != 0)
+ goto fail_mac_stats_periodic;
+
sfc_log_init(sa, "disable MAC drain");
rc = efx_mac_drain(sa->nic, B_FALSE);
if (rc != 0)
@@ -76,6 +117,10 @@ sfc_port_start(struct sfc_adapter *sa)
return 0;
fail_mac_drain:
+ (void)efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
+ 0, B_FALSE);
+
+fail_mac_stats_periodic:
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
@@ -95,6 +140,10 @@ sfc_port_stop(struct sfc_adapter *sa)
sfc_log_init(sa, "entry");
efx_mac_drain(sa->nic, B_TRUE);
+
+ (void)efx_mac_stats_periodic(sa->nic, &sa->port.mac_stats_dma_mem,
+ 0, B_FALSE);
+
efx_port_fini(sa->nic);
efx_filter_fini(sa->nic);
@@ -106,6 +155,7 @@ sfc_port_init(struct sfc_adapter *sa)
{
const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
struct sfc_port *port = &sa->port;
+ int rc;
sfc_log_init(sa, "entry");
@@ -118,15 +168,40 @@ sfc_port_init(struct sfc_adapter *sa)
else
port->pdu = EFX_MAC_PDU(dev_data->mtu);
+ rte_spinlock_init(&port->mac_stats_lock);
+
+ rc = ENOMEM;
+ port->mac_stats_buf = rte_calloc_socket("mac_stats_buf", EFX_MAC_NSTATS,
+ sizeof(uint64_t), 0,
+ sa->socket_id);
+ if (port->mac_stats_buf == NULL)
+ goto fail_mac_stats_buf_alloc;
+
+ rc = sfc_dma_alloc(sa, "mac_stats", 0, EFX_MAC_STATS_SIZE,
+ sa->socket_id, &port->mac_stats_dma_mem);
+ if (rc != 0)
+ goto fail_mac_stats_dma_alloc;
+
sfc_log_init(sa, "done");
return 0;
+
+fail_mac_stats_dma_alloc:
+ rte_free(port->mac_stats_buf);
+fail_mac_stats_buf_alloc:
+ sfc_log_init(sa, "failed %d", rc);
+ return rc;
}
void
sfc_port_fini(struct sfc_adapter *sa)
{
+ struct sfc_port *port = &sa->port;
+
sfc_log_init(sa, "entry");
+ sfc_dma_free(sa, &port->mac_stats_dma_mem);
+ rte_free(port->mac_stats_buf);
+
sfc_log_init(sa, "done");
}
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 04/32] net/sfc: support extended statistics
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (2 preceding siblings ...)
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 03/32] net/sfc: implement ethdev hook to get basic statistics Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 05/32] net/sfc: support flow control settings get/set Andrew Rybchenko
` (28 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 3 ++
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc_ethdev.c | 63 ++++++++++++++++++++++++++++++++++++
4 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index f55a988..698553c 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -8,6 +8,7 @@ Link status = Y
L3 checksum offload = P
L4 checksum offload = P
Basic stats = Y
+Extended stats = Y
BSD nic_uio = Y
Linux UIO = Y
Linux VFIO = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index cbb51de..eb9d26d 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -50,6 +50,9 @@ SFC EFX PMD has support for:
- Port hardware statistics
+- Extended statistics (see Solarflare Server Adapter User's Guide for
+ the statistics description)
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index fe8615f..0f941e6 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -159,7 +159,7 @@ prefetch_read_once(const volatile void *addr)
/* Code inclusion options */
-#define EFSYS_OPT_NAMES 0
+#define EFSYS_OPT_NAMES 1
/* Disable SFN5xxx/SFN6xxx since it requires specific support in the PMD */
#define EFSYS_OPT_SIENA 0
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f31330c..d5ae1a0 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -392,6 +392,67 @@ sfc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
rte_spinlock_unlock(&port->mac_stats_lock);
}
+static int
+sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+ unsigned int xstats_count)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ uint64_t *mac_stats;
+ int rc;
+ unsigned int i;
+ int nstats = 0;
+
+ rte_spinlock_lock(&port->mac_stats_lock);
+
+ rc = sfc_port_update_mac_stats(sa);
+ if (rc != 0) {
+ SFC_ASSERT(rc > 0);
+ nstats = -rc;
+ goto unlock;
+ }
+
+ mac_stats = port->mac_stats_buf;
+
+ for (i = 0; i < EFX_MAC_NSTATS; ++i) {
+ if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
+ if (xstats != NULL && nstats < (int)xstats_count) {
+ xstats[nstats].id = nstats;
+ xstats[nstats].value = mac_stats[i];
+ }
+ nstats++;
+ }
+ }
+
+unlock:
+ rte_spinlock_unlock(&port->mac_stats_lock);
+
+ return nstats;
+}
+
+static int
+sfc_xstats_get_names(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int xstats_count)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ unsigned int i;
+ unsigned int nstats = 0;
+
+ for (i = 0; i < EFX_MAC_NSTATS; ++i) {
+ if (EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, i)) {
+ if (xstats_names != NULL && nstats < xstats_count)
+ strncpy(xstats_names[nstats].name,
+ efx_mac_stat_name(sa->nic, i),
+ sizeof(xstats_names[0].name));
+ nstats++;
+ }
+ }
+
+ return nstats;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -399,6 +460,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_close = sfc_dev_close,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
+ .xstats_get = sfc_xstats_get,
+ .xstats_get_names = sfc_xstats_get_names,
.dev_infos_get = sfc_dev_infos_get,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 05/32] net/sfc: support flow control settings get/set
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (3 preceding siblings ...)
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 04/32] net/sfc: support extended statistics Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 06/32] net/sfc: support link status change interrupt Andrew Rybchenko
` (27 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 +
drivers/net/sfc/sfc_ethdev.c | 98 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 8 +++
4 files changed, 109 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 698553c..25472f8 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -5,6 +5,7 @@
;
[Features]
Link status = Y
+Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
Basic stats = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index eb9d26d..06b0c14 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -53,6 +53,8 @@ SFC EFX PMD has support for:
- Extended statistics (see Solarflare Server Adapter User's Guide for
the statistics description)
+- Basic flow control
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index d5ae1a0..eff648b 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -453,6 +453,102 @@ sfc_xstats_get_names(struct rte_eth_dev *dev,
return nstats;
}
+static int
+sfc_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ unsigned int wanted_fc, link_fc;
+
+ memset(fc_conf, 0, sizeof(*fc_conf));
+
+ sfc_adapter_lock(sa);
+
+ if (sa->state == SFC_ADAPTER_STARTED)
+ efx_mac_fcntl_get(sa->nic, &wanted_fc, &link_fc);
+ else
+ link_fc = sa->port.flow_ctrl;
+
+ switch (link_fc) {
+ case 0:
+ fc_conf->mode = RTE_FC_NONE;
+ break;
+ case EFX_FCNTL_RESPOND:
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ break;
+ case EFX_FCNTL_GENERATE:
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ break;
+ case (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE):
+ fc_conf->mode = RTE_FC_FULL;
+ break;
+ default:
+ sfc_err(sa, "%s: unexpected flow control value %#x",
+ __func__, link_fc);
+ }
+
+ fc_conf->autoneg = sa->port.flow_ctrl_autoneg;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+
+static int
+sfc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_port *port = &sa->port;
+ unsigned int fcntl;
+ int rc;
+
+ if (fc_conf->high_water != 0 || fc_conf->low_water != 0 ||
+ fc_conf->pause_time != 0 || fc_conf->send_xon != 0 ||
+ fc_conf->mac_ctrl_frame_fwd != 0) {
+ sfc_err(sa, "unsupported flow control settings specified");
+ rc = EINVAL;
+ goto fail_inval;
+ }
+
+ switch (fc_conf->mode) {
+ case RTE_FC_NONE:
+ fcntl = 0;
+ break;
+ case RTE_FC_RX_PAUSE:
+ fcntl = EFX_FCNTL_RESPOND;
+ break;
+ case RTE_FC_TX_PAUSE:
+ fcntl = EFX_FCNTL_GENERATE;
+ break;
+ case RTE_FC_FULL:
+ fcntl = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+ break;
+ default:
+ rc = EINVAL;
+ goto fail_inval;
+ }
+
+ sfc_adapter_lock(sa);
+
+ if (sa->state == SFC_ADAPTER_STARTED) {
+ rc = efx_mac_fcntl_set(sa->nic, fcntl, fc_conf->autoneg);
+ if (rc != 0)
+ goto fail_mac_fcntl_set;
+ }
+
+ port->flow_ctrl = fcntl;
+ port->flow_ctrl_autoneg = fc_conf->autoneg;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+
+fail_mac_fcntl_set:
+ sfc_adapter_unlock(sa);
+fail_inval:
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -467,6 +563,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.rx_queue_release = sfc_rx_queue_release,
.tx_queue_setup = sfc_tx_queue_setup,
.tx_queue_release = sfc_tx_queue_release,
+ .flow_ctrl_get = sfc_flow_ctrl_get,
+ .flow_ctrl_set = sfc_flow_ctrl_set,
};
static int
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index d8ff097..ccc0854 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -79,6 +79,13 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_port_init;
+ sfc_log_init(sa, "set flow control to %#x autoneg=%u",
+ port->flow_ctrl, port->flow_ctrl_autoneg);
+ rc = efx_mac_fcntl_set(sa->nic, port->flow_ctrl,
+ port->flow_ctrl_autoneg);
+ if (rc != 0)
+ goto fail_mac_fcntl_set;
+
sfc_log_init(sa, "set MAC PDU %u", (unsigned int)port->pdu);
rc = efx_mac_pdu_set(sa->nic, port->pdu);
if (rc != 0)
@@ -124,6 +131,7 @@ sfc_port_start(struct sfc_adapter *sa)
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
+fail_mac_fcntl_set:
efx_port_fini(sa->nic);
fail_port_init:
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 06/32] net/sfc: support link status change interrupt
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (4 preceding siblings ...)
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 05/32] net/sfc: support flow control settings get/set Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 07/32] net/sfc: implement device operation to change MTU Andrew Rybchenko
` (26 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 4 +-
drivers/net/sfc/sfc.c | 4 +-
drivers/net/sfc/sfc.h | 4 +
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_ev.c | 30 +++++-
drivers/net/sfc/sfc_intr.c | 204 +++++++++++++++++++++++++++++++++++
7 files changed, 242 insertions(+), 6 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 25472f8..693d35e 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -5,6 +5,7 @@
;
[Features]
Link status = Y
+Link status event = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 06b0c14..58f8242 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -44,7 +44,7 @@ SFC EFX PMD has support for:
- Multiple transmit and receive queues
-- Link state information
+- Link state information including link status change interrupt
- IPv4/IPv6 TCP/UDP transmit checksum offload
@@ -61,8 +61,6 @@ Non-supported Features
The features not yet supported include:
-- Link status change interrupt
-
- Receive queue interupts
- Priority-based flow control
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index ef9e0d4..36044a0 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -116,7 +116,9 @@ sfc_check_conf(struct sfc_adapter *sa)
rc = EINVAL;
}
- if (conf->intr_conf.lsc != 0) {
+ if ((conf->intr_conf.lsc != 0) &&
+ (sa->intr.type != EFX_INTR_LINE) &&
+ (sa->intr.type != EFX_INTR_MESSAGE)) {
sfc_err(sa, "Link status change interrupt not supported");
rc = EINVAL;
}
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index e9f5183..be33464 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -112,6 +112,8 @@ struct sfc_mcdi {
struct sfc_intr {
efx_intr_type_t type;
+ rte_intr_callback_fn handler;
+ boolean_t lsc_intr;
};
struct sfc_evq_info;
@@ -119,6 +121,8 @@ struct sfc_rxq_info;
struct sfc_txq_info;
struct sfc_port {
+ unsigned int lsc_seq;
+
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index eff648b..8c46500 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -682,6 +682,7 @@ static struct eth_driver sfc_efx_pmd = {
.pci_drv = {
.id_table = pci_id_sfc_efx_map,
.drv_flags =
+ RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index de42845..c788986 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -287,11 +287,25 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
struct sfc_adapter *sa = evq->sa;
struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
struct rte_eth_link new_link;
+ uint64_t new_link_u64;
+ uint64_t old_link_u64;
EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
sfc_port_link_mode_to_info(link_mode, &new_link);
- rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link);
+
+ new_link_u64 = *(uint64_t *)&new_link;
+ do {
+ old_link_u64 = rte_atomic64_read((rte_atomic64_t *)dev_link);
+ if (old_link_u64 == new_link_u64)
+ break;
+
+ if (rte_atomic64_cmpset((volatile uint64_t *)dev_link,
+ old_link_u64, new_link_u64)) {
+ evq->sa->port.lsc_seq++;
+ break;
+ }
+ } while (B_TRUE);
return B_FALSE;
}
@@ -521,6 +535,12 @@ sfc_ev_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mgmt_evq_start;
+ if (sa->intr.lsc_intr) {
+ rc = sfc_ev_qprime(sa->evq_info[sa->mgmt_evq_index].evq);
+ if (rc != 0)
+ goto fail_evq0_prime;
+ }
+
rte_spinlock_unlock(&sa->mgmt_evq_lock);
/*
@@ -538,6 +558,9 @@ sfc_ev_start(struct sfc_adapter *sa)
return 0;
+fail_evq0_prime:
+ sfc_ev_qstop(sa, 0);
+
fail_mgmt_evq_start:
rte_spinlock_unlock(&sa->mgmt_evq_lock);
efx_ev_fini(sa->nic);
@@ -639,7 +662,10 @@ sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
SFC_ASSERT(rte_is_power_of_2(max_entries));
evq_info->max_entries = max_entries;
- evq_info->flags = sa->evq_flags | EFX_EVQ_FLAGS_NOTIFY_DISABLED;
+ evq_info->flags = sa->evq_flags |
+ ((sa->intr.lsc_intr && sw_index == sa->mgmt_evq_index) ?
+ EFX_EVQ_FLAGS_NOTIFY_INTERRUPT :
+ EFX_EVQ_FLAGS_NOTIFY_DISABLED);
return 0;
}
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
index 1b7dcdd..e0b1693 100644
--- a/drivers/net/sfc/sfc_intr.c
+++ b/drivers/net/sfc/sfc_intr.c
@@ -27,10 +27,130 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * At the momemt of writing DPDK v16.07 has notion of two types of
+ * interrupts: LSC (link status change) and RXQ (receive indication).
+ * It allows to register interrupt callback for entire device which is
+ * not intended to be used for receive indication (i.e. link status
+ * change indication only). The handler has no information which HW
+ * interrupt has triggered it, so we don't know which event queue should
+ * be polled/reprimed (except qmask in the case of legacy line interrupt).
+ */
+
+#include <rte_common.h>
+#include <rte_interrupts.h>
+
#include "efx.h"
#include "sfc.h"
#include "sfc_log.h"
+#include "sfc_ev.h"
+
+static void
+sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa)
+{
+ struct sfc_evq *evq;
+
+ rte_spinlock_lock(&sa->mgmt_evq_lock);
+
+ evq = sa->evq_info[sa->mgmt_evq_index].evq;
+
+ if (evq->init_state != SFC_EVQ_STARTED) {
+ sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index);
+ } else {
+ sfc_ev_qpoll(evq);
+
+ if (sfc_ev_qprime(evq) != 0)
+ sfc_err(sa, "cannot prime EVQ %u", evq->evq_index);
+ }
+
+ rte_spinlock_unlock(&sa->mgmt_evq_lock);
+}
+
+static void
+sfc_intr_line_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg;
+ efx_nic_t *enp = sa->nic;
+ boolean_t fatal;
+ uint32_t qmask;
+ unsigned int lsc_seq = sa->port.lsc_seq;
+
+ sfc_log_init(sa, "entry");
+
+ if (sa->state != SFC_ADAPTER_STARTED &&
+ sa->state != SFC_ADAPTER_STARTING &&
+ sa->state != SFC_ADAPTER_STOPPING) {
+ sfc_log_init(sa,
+ "interrupt on stopped adapter, don't reenable");
+ goto exit;
+ }
+
+ efx_intr_status_line(enp, &fatal, &qmask);
+ if (fatal) {
+ (void)efx_intr_disable(enp);
+ (void)efx_intr_fatal(enp);
+ sfc_err(sa, "fatal, interrupts disabled");
+ goto exit;
+ }
+
+ if (qmask & (1 << sa->mgmt_evq_index))
+ sfc_intr_handle_mgmt_evq(sa);
+
+ if (rte_intr_enable(intr_handle) != 0)
+ sfc_err(sa, "cannot reenable interrupts");
+
+ sfc_log_init(sa, "done");
+
+exit:
+ if (lsc_seq != sa->port.lsc_seq) {
+ sfc_info(sa, "link status change event: link %s",
+ sa->eth_dev->data->dev_link.link_status ?
+ "UP" : "DOWN");
+ _rte_eth_dev_callback_process(sa->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC, NULL);
+ }
+}
+
+static void
+sfc_intr_message_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg;
+ efx_nic_t *enp = sa->nic;
+ boolean_t fatal;
+ unsigned int lsc_seq = sa->port.lsc_seq;
+
+ sfc_log_init(sa, "entry");
+
+ if (sa->state != SFC_ADAPTER_STARTED &&
+ sa->state != SFC_ADAPTER_STARTING &&
+ sa->state != SFC_ADAPTER_STOPPING) {
+ sfc_log_init(sa, "adapter not-started, don't reenable");
+ goto exit;
+ }
+
+ efx_intr_status_message(enp, sa->mgmt_evq_index, &fatal);
+ if (fatal) {
+ (void)efx_intr_disable(enp);
+ (void)efx_intr_fatal(enp);
+ sfc_err(sa, "fatal, interrupts disabled");
+ goto exit;
+ }
+
+ sfc_intr_handle_mgmt_evq(sa);
+
+ if (rte_intr_enable(intr_handle) != 0)
+ sfc_err(sa, "cannot reenable interrupts");
+
+ sfc_log_init(sa, "done");
+
+exit:
+ if (lsc_seq != sa->port.lsc_seq) {
+ sfc_info(sa, "link status change event");
+ _rte_eth_dev_callback_process(sa->eth_dev,
+ RTE_ETH_EVENT_INTR_LSC, NULL);
+ }
+}
int
sfc_intr_start(struct sfc_adapter *sa)
@@ -54,11 +174,49 @@ sfc_intr_start(struct sfc_adapter *sa)
intr_handle = &sa->eth_dev->pci_dev->intr_handle;
+ if (intr->handler != NULL) {
+ sfc_log_init(sa, "rte_intr_callback_register");
+ rc = rte_intr_callback_register(intr_handle, intr->handler,
+ (void *)sa);
+ if (rc != 0) {
+ sfc_err(sa,
+ "cannot register interrupt handler (rc=%d)",
+ rc);
+ /*
+ * Convert error code from negative returned by RTE API
+ * to positive used in the driver.
+ */
+ rc = -rc;
+ goto fail_rte_intr_cb_reg;
+ }
+
+ sfc_log_init(sa, "rte_intr_enable");
+ rc = rte_intr_enable(intr_handle);
+ if (rc != 0) {
+ sfc_err(sa, "cannot enable interrupts (rc=%d)", rc);
+ /*
+ * Convert error code from negative returned by RTE API
+ * to positive used in the driver.
+ */
+ rc = -rc;
+ goto fail_rte_intr_enable;
+ }
+
+ sfc_log_init(sa, "efx_intr_enable");
+ efx_intr_enable(sa->nic);
+ }
+
sfc_log_init(sa, "done type=%u max_intr=%d nb_efd=%u vec=%p",
intr_handle->type, intr_handle->max_intr,
intr_handle->nb_efd, intr_handle->intr_vec);
return 0;
+fail_rte_intr_enable:
+ rte_intr_callback_unregister(intr_handle, intr->handler, (void *)sa);
+
+fail_rte_intr_cb_reg:
+ efx_intr_fini(sa->nic);
+
fail_intr_init:
sfc_log_init(sa, "failed %d", rc);
return rc;
@@ -67,8 +225,29 @@ sfc_intr_start(struct sfc_adapter *sa)
void
sfc_intr_stop(struct sfc_adapter *sa)
{
+ struct sfc_intr *intr = &sa->intr;
+
sfc_log_init(sa, "entry");
+ if (intr->handler != NULL) {
+ struct rte_intr_handle *intr_handle;
+ int rc;
+
+ efx_intr_disable(sa->nic);
+
+ intr_handle = &sa->eth_dev->pci_dev->intr_handle;
+ if (rte_intr_disable(intr_handle) != 0)
+ sfc_err(sa, "cannot disable interrupts");
+
+ while ((rc = rte_intr_callback_unregister(intr_handle,
+ intr->handler, (void *)sa)) == -EAGAIN)
+ ;
+ if (rc != 1)
+ sfc_err(sa,
+ "cannot unregister interrupt handler %d",
+ rc);
+ }
+
efx_intr_fini(sa->nic);
sfc_log_init(sa, "done");
@@ -77,8 +256,33 @@ sfc_intr_stop(struct sfc_adapter *sa)
int
sfc_intr_init(struct sfc_adapter *sa)
{
+ struct sfc_intr *intr = &sa->intr;
+
sfc_log_init(sa, "entry");
+ intr->handler = NULL;
+ intr->lsc_intr = (sa->eth_dev->data->dev_conf.intr_conf.lsc != 0);
+ if (!intr->lsc_intr) {
+ sfc_info(sa, "LSC tracking using interrupts is disabled");
+ goto done;
+ }
+
+ switch (intr->type) {
+ case EFX_INTR_MESSAGE:
+ intr->handler = sfc_intr_message_handler;
+ break;
+ case EFX_INTR_LINE:
+ intr->handler = sfc_intr_line_handler;
+ break;
+ case EFX_INTR_INVALID:
+ sfc_warn(sa, "interrupts are not supported");
+ break;
+ default:
+ sfc_panic(sa, "unexpected EFX interrupt type %u\n", intr->type);
+ break;
+ }
+
+done:
sfc_log_init(sa, "done");
return 0;
}
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 07/32] net/sfc: implement device operation to change MTU
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (5 preceding siblings ...)
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 06/32] net/sfc: support link status change interrupt Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 08/32] net/sfc: support link speed and duplex settings Andrew Rybchenko
` (25 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 ++
doc/guides/nics/sfc_efx.rst | 4 +++
drivers/net/sfc/sfc_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 693d35e..a845bfc 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -6,6 +6,8 @@
[Features]
Link status = Y
Link status event = Y
+MTU update = Y
+Jumbo frame = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 58f8242..c482d77 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -55,6 +55,10 @@ SFC EFX PMD has support for:
- Basic flow control
+- MTU update
+
+- Jumbo frames up to 9K
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 8c46500..6690755 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -549,6 +549,72 @@ sfc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
return -rc;
}
+static int
+sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ size_t pdu = EFX_MAC_PDU(mtu);
+ size_t old_pdu;
+ int rc;
+
+ sfc_log_init(sa, "mtu=%u", mtu);
+
+ rc = EINVAL;
+ if (pdu < EFX_MAC_PDU_MIN) {
+ sfc_err(sa, "too small MTU %u (PDU size %u less than min %u)",
+ (unsigned int)mtu, (unsigned int)pdu,
+ EFX_MAC_PDU_MIN);
+ goto fail_inval;
+ }
+ if (pdu > EFX_MAC_PDU_MAX) {
+ sfc_err(sa, "too big MTU %u (PDU size %u greater than max %u)",
+ (unsigned int)mtu, (unsigned int)pdu,
+ EFX_MAC_PDU_MAX);
+ goto fail_inval;
+ }
+
+ sfc_adapter_lock(sa);
+
+ if (pdu != sa->port.pdu) {
+ if (sa->state == SFC_ADAPTER_STARTED) {
+ sfc_stop(sa);
+
+ old_pdu = sa->port.pdu;
+ sa->port.pdu = pdu;
+ rc = sfc_start(sa);
+ if (rc != 0)
+ goto fail_start;
+ } else {
+ sa->port.pdu = pdu;
+ }
+ }
+
+ /*
+ * The driver does not use it, but other PMDs update jumbo_frame
+ * flag and max_rx_pkt_len when MTU is set.
+ */
+ dev->data->dev_conf.rxmode.jumbo_frame = (mtu > ETHER_MAX_LEN);
+ dev->data->dev_conf.rxmode.max_rx_pkt_len = sa->port.pdu;
+
+ sfc_adapter_unlock(sa);
+
+ sfc_log_init(sa, "done");
+ return 0;
+
+fail_start:
+ sa->port.pdu = old_pdu;
+ if (sfc_start(sa) != 0)
+ sfc_err(sa, "cannot start with neither new (%u) nor old (%u) "
+ "PDU max size - port is stopped",
+ (unsigned int)pdu, (unsigned int)old_pdu);
+ sfc_adapter_unlock(sa);
+
+fail_inval:
+ sfc_log_init(sa, "failed %d", rc);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -559,6 +625,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.xstats_get = sfc_xstats_get,
.xstats_get_names = sfc_xstats_get_names,
.dev_infos_get = sfc_dev_infos_get,
+ .mtu_set = sfc_dev_set_mtu,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.tx_queue_setup = sfc_tx_queue_setup,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 08/32] net/sfc: support link speed and duplex settings
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (6 preceding siblings ...)
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 07/32] net/sfc: implement device operation to change MTU Andrew Rybchenko
@ 2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 09/32] net/sfc: support link up/down Andrew Rybchenko
` (24 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:50 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/sfc.c | 38 ++++++++++++++++++++++++++++++++++--
drivers/net/sfc/sfc.h | 3 +++
drivers/net/sfc/sfc_ethdev.c | 9 +++++++++
drivers/net/sfc/sfc_port.c | 6 ++++++
5 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index a845bfc..60ecca0 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Speed capabilities = Y
Link status = Y
Link status event = Y
MTU update = Y
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 36044a0..e2e6c9e 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -85,6 +85,33 @@ sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp)
memset(esmp, 0, sizeof(*esmp));
}
+static uint32_t
+sfc_phy_cap_from_link_speeds(uint32_t speeds)
+{
+ uint32_t phy_caps = 0;
+
+ if (~speeds & ETH_LINK_SPEED_FIXED) {
+ phy_caps |= (1 << EFX_PHY_CAP_AN);
+ /*
+ * If no speeds are specified in the mask, any supported
+ * may be negotiated
+ */
+ if (speeds == ETH_LINK_SPEED_AUTONEG)
+ phy_caps |=
+ (1 << EFX_PHY_CAP_1000FDX) |
+ (1 << EFX_PHY_CAP_10000FDX) |
+ (1 << EFX_PHY_CAP_40000FDX);
+ }
+ if (speeds & ETH_LINK_SPEED_1G)
+ phy_caps |= (1 << EFX_PHY_CAP_1000FDX);
+ if (speeds & ETH_LINK_SPEED_10G)
+ phy_caps |= (1 << EFX_PHY_CAP_10000FDX);
+ if (speeds & ETH_LINK_SPEED_40G)
+ phy_caps |= (1 << EFX_PHY_CAP_40000FDX);
+
+ return phy_caps;
+}
+
/*
* Check requested device level configuration.
* Receive and transmit configuration is checked in corresponding
@@ -96,8 +123,12 @@ sfc_check_conf(struct sfc_adapter *sa)
const struct rte_eth_conf *conf = &sa->eth_dev->data->dev_conf;
int rc = 0;
- if (conf->link_speeds != ETH_LINK_SPEED_AUTONEG) {
- sfc_err(sa, "Manual link speed/duplex choice not supported");
+ sa->port.phy_adv_cap =
+ sfc_phy_cap_from_link_speeds(conf->link_speeds) &
+ sa->port.phy_adv_cap_mask;
+ if ((sa->port.phy_adv_cap & ~(1 << EFX_PHY_CAP_AN)) == 0) {
+ sfc_err(sa, "No link speeds from mask %#x are supported",
+ conf->link_speeds);
rc = EINVAL;
}
@@ -516,6 +547,9 @@ sfc_attach(struct sfc_adapter *sa)
if (rc != 0)
goto fail_intr_attach;
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
+ &sa->port.phy_adv_cap_mask);
+
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index be33464..ff0bc3c 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -123,6 +123,9 @@ struct sfc_txq_info;
struct sfc_port {
unsigned int lsc_seq;
+ uint32_t phy_adv_cap_mask;
+ uint32_t phy_adv_cap;
+
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6690755..42c488e 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -53,6 +53,15 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
+ /* Autonegotiation may be disabled */
+ dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
+ if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_1000FDX)
+ dev_info->speed_capa |= ETH_LINK_SPEED_1G;
+ if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_10000FDX)
+ dev_info->speed_capa |= ETH_LINK_SPEED_10G;
+ if (sa->port.phy_adv_cap_mask & EFX_PHY_CAP_40000FDX)
+ dev_info->speed_capa |= ETH_LINK_SPEED_40G;
+
dev_info->max_rx_queues = sa->rxq_max;
dev_info->max_tx_queues = sa->txq_max;
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index ccc0854..1241af7 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -86,6 +86,11 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mac_fcntl_set;
+ sfc_log_init(sa, "set phy adv caps to %#x", port->phy_adv_cap);
+ rc = efx_phy_adv_cap_set(sa->nic, port->phy_adv_cap);
+ if (rc != 0)
+ goto fail_phy_adv_cap_set;
+
sfc_log_init(sa, "set MAC PDU %u", (unsigned int)port->pdu);
rc = efx_mac_pdu_set(sa->nic, port->pdu);
if (rc != 0)
@@ -131,6 +136,7 @@ sfc_port_start(struct sfc_adapter *sa)
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
+fail_phy_adv_cap_set:
fail_mac_fcntl_set:
efx_port_fini(sa->nic);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 09/32] net/sfc: support link up/down
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (7 preceding siblings ...)
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 08/32] net/sfc: support link speed and duplex settings Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 10/32] net/sfc: support promiscuous and all-multicast control Andrew Rybchenko
` (23 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Artem Andreev
From: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 42c488e..1716d78 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -195,6 +195,36 @@ sfc_dev_stop(struct rte_eth_dev *dev)
sfc_log_init(sa, "done");
}
+static int
+sfc_dev_set_link_up(struct rte_eth_dev *dev)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "entry");
+
+ sfc_adapter_lock(sa);
+ rc = sfc_start(sa);
+ sfc_adapter_unlock(sa);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
+}
+
+static int
+sfc_dev_set_link_down(struct rte_eth_dev *dev)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "entry");
+
+ sfc_adapter_lock(sa);
+ sfc_stop(sa);
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+
static void
sfc_dev_close(struct rte_eth_dev *dev)
{
@@ -628,6 +658,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
.dev_stop = sfc_dev_stop,
+ .dev_set_link_up = sfc_dev_set_link_up,
+ .dev_set_link_down = sfc_dev_set_link_down,
.dev_close = sfc_dev_close,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 10/32] net/sfc: support promiscuous and all-multicast control
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (8 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 09/32] net/sfc: support link up/down Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 11/32] net/sfc: support main (the first) MAC address change Andrew Rybchenko
` (22 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 ++
doc/guides/nics/sfc_efx.rst | 4 +++
drivers/net/sfc/sfc.h | 11 +++++++
drivers/net/sfc/sfc_ethdev.c | 57 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 18 +++++++++++-
5 files changed, 91 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 60ecca0..aaea993 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -9,6 +9,8 @@ Link status = Y
Link status event = Y
MTU update = Y
Jumbo frame = Y
+Promiscuous mode = Y
+Allmulticast mode = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index c482d77..984da9c 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -59,6 +59,10 @@ SFC EFX PMD has support for:
- Jumbo frames up to 9K
+- Promiscuous mode
+
+- Allmulticast mode
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index ff0bc3c..7b135e1 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -93,6 +93,13 @@ enum sfc_adapter_state {
SFC_ADAPTER_NSTATES
};
+enum sfc_dev_filter_mode {
+ SFC_DEV_FILTER_MODE_PROMISC = 0,
+ SFC_DEV_FILTER_MODE_ALLMULTI,
+
+ SFC_DEV_FILTER_NMODES
+};
+
enum sfc_mcdi_state {
SFC_MCDI_UNINITIALIZED = 0,
SFC_MCDI_INITIALIZED,
@@ -130,6 +137,9 @@ struct sfc_port {
boolean_t flow_ctrl_autoneg;
size_t pdu;
+ boolean_t promisc;
+ boolean_t allmulti;
+
rte_spinlock_t mac_stats_lock;
uint64_t *mac_stats_buf;
efsys_mem_t mac_stats_dma_mem;
@@ -249,6 +259,7 @@ void sfc_port_stop(struct sfc_adapter *sa);
void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info);
int sfc_port_update_mac_stats(struct sfc_adapter *sa);
+int sfc_set_rx_mode(struct sfc_adapter *sa);
#ifdef __cplusplus
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1716d78..c6095ad 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -253,6 +253,59 @@ sfc_dev_close(struct rte_eth_dev *dev)
sfc_log_init(sa, "done");
}
+static void
+sfc_dev_filter_set(struct rte_eth_dev *dev, enum sfc_dev_filter_mode mode,
+ boolean_t enabled)
+{
+ struct sfc_port *port;
+ boolean_t *toggle;
+ struct sfc_adapter *sa = dev->data->dev_private;
+ boolean_t allmulti = (mode == SFC_DEV_FILTER_MODE_ALLMULTI);
+ const char *desc = (allmulti) ? "all-multi" : "promiscuous";
+
+ sfc_adapter_lock(sa);
+
+ port = &sa->port;
+ toggle = (allmulti) ? (&port->allmulti) : (&port->promisc);
+
+ if (*toggle != enabled) {
+ *toggle = enabled;
+
+ if ((sa->state == SFC_ADAPTER_STARTED) &&
+ (sfc_set_rx_mode(sa) != 0)) {
+ *toggle = !(enabled);
+ sfc_warn(sa, "Failed to %s %s mode",
+ ((enabled) ? "enable" : "disable"), desc);
+ }
+ }
+
+ sfc_adapter_unlock(sa);
+}
+
+static void
+sfc_dev_promisc_enable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_TRUE);
+}
+
+static void
+sfc_dev_promisc_disable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_PROMISC, B_FALSE);
+}
+
+static void
+sfc_dev_allmulti_enable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_TRUE);
+}
+
+static void
+sfc_dev_allmulti_disable(struct rte_eth_dev *dev)
+{
+ sfc_dev_filter_set(dev, SFC_DEV_FILTER_MODE_ALLMULTI, B_FALSE);
+}
+
static int
sfc_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
uint16_t nb_rx_desc, unsigned int socket_id,
@@ -661,6 +714,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_set_link_up = sfc_dev_set_link_up,
.dev_set_link_down = sfc_dev_set_link_down,
.dev_close = sfc_dev_close,
+ .promiscuous_enable = sfc_dev_promisc_enable,
+ .promiscuous_disable = sfc_dev_promisc_disable,
+ .allmulticast_enable = sfc_dev_allmulti_enable,
+ .allmulticast_disable = sfc_dev_allmulti_disable,
.link_update = sfc_dev_link_update,
.stats_get = sfc_stats_get,
.xstats_get = sfc_xstats_get,
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 1241af7..dc6ecdf 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -103,7 +103,11 @@ sfc_port_start(struct sfc_adapter *sa)
goto fail_mac_addr_set;
sfc_log_init(sa, "set MAC filters");
- rc = efx_mac_filter_set(sa->nic, B_TRUE, B_TRUE, B_TRUE, B_TRUE);
+ port->promisc = (sa->eth_dev->data->promiscuous != 0) ?
+ B_TRUE : B_FALSE;
+ port->allmulti = (sa->eth_dev->data->all_multicast != 0) ?
+ B_TRUE : B_FALSE;
+ rc = sfc_set_rx_mode(sa);
if (rc != 0)
goto fail_mac_filter_set;
@@ -219,6 +223,18 @@ sfc_port_fini(struct sfc_adapter *sa)
sfc_log_init(sa, "done");
}
+int
+sfc_set_rx_mode(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ int rc;
+
+ rc = efx_mac_filter_set(sa->nic, port->promisc, B_TRUE,
+ port->promisc || port->allmulti, B_TRUE);
+
+ return rc;
+}
+
void
sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
struct rte_eth_link *link_info)
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 11/32] net/sfc: support main (the first) MAC address change
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (9 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 10/32] net/sfc: support promiscuous and all-multicast control Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 12/32] net/sfc: support multicast addresses list controls Andrew Rybchenko
` (21 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c6095ad..79e2761 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -706,6 +706,58 @@ sfc_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
SFC_ASSERT(rc > 0);
return -rc;
}
+static void
+sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+ int rc;
+
+ sfc_adapter_lock(sa);
+
+ if (sa->state != SFC_ADAPTER_STARTED) {
+ sfc_info(sa, "the port is not started");
+ sfc_info(sa, "the new MAC address will be set on port start");
+
+ goto unlock;
+ }
+
+ if (encp->enc_allow_set_mac_with_installed_filters) {
+ rc = efx_mac_addr_set(sa->nic, mac_addr->addr_bytes);
+ if (rc != 0) {
+ sfc_err(sa, "cannot set MAC address (rc = %u)", rc);
+ goto unlock;
+ }
+
+ /*
+ * Changing the MAC address by means of MCDI request
+ * has no effect on received traffic, therefore
+ * we also need to update unicast filters
+ */
+ rc = sfc_set_rx_mode(sa);
+ if (rc != 0)
+ sfc_err(sa, "cannot set filter (rc = %u)", rc);
+ } else {
+ sfc_warn(sa, "cannot set MAC address with filters installed");
+ sfc_warn(sa, "adapter will be restarted to pick the new MAC");
+ sfc_warn(sa, "(some traffic may be dropped)");
+
+ /*
+ * Since setting MAC address with filters installed is not
+ * allowed on the adapter, one needs to simply restart adapter
+ * so that the new MAC address will be taken from an outer
+ * storage and set flawlessly by means of sfc_start() call
+ */
+ sfc_stop(sa);
+ rc = sfc_start(sa);
+ if (rc != 0)
+ sfc_err(sa, "cannot restart adapter (rc = %u)", rc);
+ }
+
+unlock:
+ sfc_adapter_unlock(sa);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
@@ -730,6 +782,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.tx_queue_release = sfc_tx_queue_release,
.flow_ctrl_get = sfc_flow_ctrl_get,
.flow_ctrl_set = sfc_flow_ctrl_set,
+ .mac_addr_set = sfc_mac_addr_set,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 12/32] net/sfc: support multicast addresses list controls
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (10 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 11/32] net/sfc: support main (the first) MAC address change Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 13/32] net/sfc: support checksum offloads on receive Andrew Rybchenko
` (20 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 40 ++++++++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index aaea993..35633cb 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -11,6 +11,7 @@ MTU update = Y
Jumbo frame = Y
Promiscuous mode = Y
Allmulticast mode = Y
+Multicast MAC filter = Y
Flow control = Y
L3 checksum offload = P
L4 checksum offload = P
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 984da9c..43dd4cf 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -63,6 +63,8 @@ SFC EFX PMD has support for:
- Allmulticast mode
+- Multicast MAC filter
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 79e2761..268b76a 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -759,6 +759,45 @@ sfc_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
}
+static int
+sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
+ uint32_t nb_mc_addr)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ uint8_t *mc_addrs_p;
+ uint8_t *mc_addrs;
+ int rc;
+ unsigned int i;
+
+ if (nb_mc_addr > EFX_MAC_MULTICAST_LIST_MAX) {
+ sfc_err(sa, "too many multicast addresses: %u > %u",
+ nb_mc_addr, EFX_MAC_MULTICAST_LIST_MAX);
+ return -EINVAL;
+ }
+
+ mc_addrs_p = rte_calloc("mc-addrs", nb_mc_addr, EFX_MAC_ADDR_LEN, 0);
+ if (mc_addrs_p == NULL)
+ return -ENOMEM;
+
+ mc_addrs = mc_addrs_p;
+
+ for (i = 0; i < nb_mc_addr; ++i) {
+ (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes,
+ EFX_MAC_ADDR_LEN);
+ mc_addrs += EFX_MAC_ADDR_LEN;
+ }
+
+ rc = efx_mac_multicast_list_set(sa->nic, mc_addrs_p, nb_mc_addr);
+
+ rte_free(mc_addrs_p);
+
+ if (rc != 0)
+ sfc_err(sa, "cannot set multicast address list (rc = %u)", rc);
+
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -783,6 +822,7 @@ 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,
+ .set_mc_addr_list = sfc_set_mc_addr_list,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 13/32] net/sfc: support checksum offloads on receive
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (11 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 12/32] net/sfc: support multicast addresses list controls Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 14/32] net/sfc: handle received packet type info provided by HW Andrew Rybchenko
` (19 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
IPv4 header and TCP/UDP checksums for both IPv4 and IPv6 are supported.
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 4 ++--
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 5 +++++
drivers/net/sfc/sfc_rx.c | 40 ++++++++++++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 35633cb..ec1d1db 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -13,8 +13,8 @@ Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
Flow control = Y
-L3 checksum offload = P
-L4 checksum offload = P
+L3 checksum offload = Y
+L4 checksum offload = Y
Basic stats = Y
Extended stats = Y
BSD nic_uio = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 43dd4cf..8724eae 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -65,6 +65,8 @@ SFC EFX PMD has support for:
- Multicast MAC filter
+- IPv4/IPv6 TCP/UDP receive checksum offload
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 268b76a..235582d 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -68,6 +68,11 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
/* By default packets are dropped if no descriptors are available */
dev_info->default_rxconf.rx_drop_en = 1;
+ dev_info->rx_offload_capa =
+ DEV_RX_OFFLOAD_IPV4_CKSUM |
+ DEV_RX_OFFLOAD_UDP_CKSUM |
+ DEV_RX_OFFLOAD_TCP_CKSUM;
+
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_IPV4_CKSUM |
DEV_TX_OFFLOAD_UDP_CKSUM |
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index bd41131..4df4132 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -130,6 +130,45 @@ sfc_rx_qrefill(struct sfc_rxq *rxq)
}
}
+static uint64_t
+sfc_rx_desc_flags_to_offload_flags(const unsigned int desc_flags)
+{
+ uint64_t mbuf_flags = 0;
+
+ switch (desc_flags & (EFX_PKT_IPV4 | EFX_CKSUM_IPV4)) {
+ case (EFX_PKT_IPV4 | EFX_CKSUM_IPV4):
+ mbuf_flags |= PKT_RX_IP_CKSUM_GOOD;
+ break;
+ case EFX_PKT_IPV4:
+ mbuf_flags |= PKT_RX_IP_CKSUM_BAD;
+ break;
+ default:
+ RTE_BUILD_BUG_ON(PKT_RX_IP_CKSUM_UNKNOWN != 0);
+ SFC_ASSERT((mbuf_flags & PKT_RX_IP_CKSUM_MASK) ==
+ PKT_RX_IP_CKSUM_UNKNOWN);
+ break;
+ }
+
+ switch ((desc_flags &
+ (EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP))) {
+ case (EFX_PKT_TCP | EFX_CKSUM_TCPUDP):
+ case (EFX_PKT_UDP | EFX_CKSUM_TCPUDP):
+ mbuf_flags |= PKT_RX_L4_CKSUM_GOOD;
+ break;
+ case EFX_PKT_TCP:
+ case EFX_PKT_UDP:
+ mbuf_flags |= PKT_RX_L4_CKSUM_BAD;
+ break;
+ default:
+ RTE_BUILD_BUG_ON(PKT_RX_L4_CKSUM_UNKNOWN != 0);
+ SFC_ASSERT((mbuf_flags & PKT_RX_L4_CKSUM_MASK) ==
+ PKT_RX_L4_CKSUM_UNKNOWN);
+ break;
+ }
+
+ return mbuf_flags;
+}
+
uint16_t
sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
@@ -182,6 +221,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_data_len(m) = seg_len;
rte_pktmbuf_pkt_len(m) = seg_len;
+ m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
m->packet_type = RTE_PTYPE_L2_ETHER;
*rx_pkts++ = m;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 14/32] net/sfc: handle received packet type info provided by HW
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (12 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 13/32] net/sfc: support checksum offloads on receive Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 15/32] net/sfc: support callback to get receive queue information Andrew Rybchenko
` (18 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 19 +++++++++++++++++++
drivers/net/sfc/sfc_rx.c | 14 +++++++++++++-
4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index ec1d1db..b5887d5 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -15,6 +15,7 @@ Multicast MAC filter = Y
Flow control = Y
L3 checksum offload = Y
L4 checksum offload = Y
+Packet type parsing = Y
Basic stats = Y
Extended stats = Y
BSD nic_uio = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 8724eae..1333f8b 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -67,6 +67,8 @@ SFC EFX PMD has support for:
- IPv4/IPv6 TCP/UDP receive checksum offload
+- Received packet type information
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 235582d..03c9a01 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -97,6 +97,24 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
}
+static const uint32_t *
+sfc_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+ static const uint32_t ptypes[] = {
+ RTE_PTYPE_L2_ETHER,
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+ RTE_PTYPE_L4_TCP,
+ RTE_PTYPE_L4_UDP,
+ RTE_PTYPE_UNKNOWN
+ };
+
+ if (dev->rx_pkt_burst == sfc_recv_pkts)
+ return ptypes;
+
+ return NULL;
+}
+
static int
sfc_dev_configure(struct rte_eth_dev *dev)
{
@@ -819,6 +837,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.xstats_get = sfc_xstats_get,
.xstats_get_names = sfc_xstats_get_names,
.dev_infos_get = sfc_dev_infos_get,
+ .dev_supported_ptypes_get = sfc_dev_supported_ptypes_get,
.mtu_set = sfc_dev_set_mtu,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 4df4132..be8fa23 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -169,6 +169,18 @@ sfc_rx_desc_flags_to_offload_flags(const unsigned int desc_flags)
return mbuf_flags;
}
+static uint32_t
+sfc_rx_desc_flags_to_packet_type(const unsigned int desc_flags)
+{
+ return RTE_PTYPE_L2_ETHER |
+ ((desc_flags & EFX_PKT_IPV4) ?
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN : 0) |
+ ((desc_flags & EFX_PKT_IPV6) ?
+ RTE_PTYPE_L3_IPV6_EXT_UNKNOWN : 0) |
+ ((desc_flags & EFX_PKT_TCP) ? RTE_PTYPE_L4_TCP : 0) |
+ ((desc_flags & EFX_PKT_UDP) ? RTE_PTYPE_L4_UDP : 0);
+}
+
uint16_t
sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
@@ -222,7 +234,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_pkt_len(m) = seg_len;
m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
- m->packet_type = RTE_PTYPE_L2_ETHER;
+ m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
*rx_pkts++ = m;
done_pkts++;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 15/32] net/sfc: support callback to get receive queue information
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (13 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 14/32] net/sfc: handle received packet type info provided by HW Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 16/32] net/sfc: support Rx free threshold Andrew Rybchenko
` (17 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 03c9a01..e67ca61 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -821,6 +821,29 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
return -rc;
}
+static void
+sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
+ struct rte_eth_rxq_info *qinfo)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_rxq_info *rxq_info;
+ struct sfc_rxq *rxq;
+
+ sfc_adapter_lock(sa);
+
+ SFC_ASSERT(rx_queue_id < sa->rxq_count);
+
+ rxq_info = &sa->rxq_info[rx_queue_id];
+ rxq = rxq_info->rxq;
+ SFC_ASSERT(rxq != NULL);
+
+ qinfo->mp = rxq->refill_mb_pool;
+ qinfo->conf.rx_drop_en = 1;
+ qinfo->nb_desc = rxq_info->entries;
+
+ sfc_adapter_unlock(sa);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -847,6 +870,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
.set_mc_addr_list = sfc_set_mc_addr_list,
+ .rxq_info_get = sfc_rx_queue_info_get,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 16/32] net/sfc: support Rx free threshold
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (14 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 15/32] net/sfc: support callback to get receive queue information Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 17/32] net/sfc: add callback to get RxQ pending descriptors count Andrew Rybchenko
` (16 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Rx free threshold defines minimum number of free Rx descriptors
when Rx ring refill should be done.
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_rx.c | 16 ++++++++++++----
drivers/net/sfc/sfc_rx.h | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index e67ca61..1d7993f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -838,6 +838,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
SFC_ASSERT(rxq != NULL);
qinfo->mp = rxq->refill_mb_pool;
+ qinfo->conf.rx_free_thresh = rxq->refill_threshold;
qinfo->conf.rx_drop_en = 1;
qinfo->nb_desc = rxq_info->entries;
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index be8fa23..278d583 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -87,6 +87,10 @@ sfc_rx_qrefill(struct sfc_rxq *rxq)
free_space = EFX_RXQ_LIMIT(rxq->ptr_mask + 1) -
(added - rxq->completed);
+
+ if (free_space < rxq->refill_threshold)
+ return;
+
bulks = free_space / RTE_DIM(objs);
id = added & rxq->ptr_mask;
@@ -410,9 +414,10 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
}
static int
-sfc_rx_qcheck_conf(struct sfc_adapter *sa,
+sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
const struct rte_eth_rxconf *rx_conf)
{
+ const uint16_t rx_free_thresh_max = EFX_RXQ_LIMIT(nb_rx_desc);
int rc = 0;
if (rx_conf->rx_thresh.pthresh != 0 ||
@@ -423,8 +428,10 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa,
rc = EINVAL;
}
- if (rx_conf->rx_free_thresh != 0) {
- sfc_err(sa, "RxQ free threshold is not supported");
+ if (rx_conf->rx_free_thresh > rx_free_thresh_max) {
+ sfc_err(sa,
+ "RxQ free threshold too large: %u vs maximum %u",
+ rx_conf->rx_free_thresh, rx_free_thresh_max);
rc = EINVAL;
}
@@ -555,7 +562,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
struct sfc_evq *evq;
struct sfc_rxq *rxq;
- rc = sfc_rx_qcheck_conf(sa, rx_conf);
+ rc = sfc_rx_qcheck_conf(sa, nb_rx_desc, rx_conf);
if (rc != 0)
goto fail_bad_conf;
@@ -615,6 +622,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
evq->rxq = rxq;
rxq->evq = evq;
rxq->ptr_mask = rxq_info->entries - 1;
+ rxq->refill_threshold = rx_conf->rx_free_thresh;
rxq->refill_mb_pool = mb_pool;
rxq->buf_size = buf_size;
rxq->hw_index = sw_index;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index e4385b9..69318ab 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -87,6 +87,7 @@ struct sfc_rxq {
/* Used on refill */
unsigned int added;
unsigned int pushed;
+ unsigned int refill_threshold;
uint8_t port_id;
uint16_t buf_size;
struct rte_mempool *refill_mb_pool;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 17/32] net/sfc: add callback to get RxQ pending descriptors count
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (15 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 16/32] net/sfc: support Rx free threshold Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 18/32] net/sfc: add RxQ descriptor done callback Andrew Rybchenko
` (15 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 11 +++++++++++
drivers/net/sfc/sfc_rx.c | 16 ++++++++++++++++
drivers/net/sfc/sfc_rx.h | 3 +++
3 files changed, 30 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 1d7993f..163f9ed 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -845,6 +845,16 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
sfc_adapter_unlock(sa);
}
+static uint32_t
+sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+ return sfc_rx_qdesc_npending(sa, rx_queue_id);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -865,6 +875,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.mtu_set = sfc_dev_set_mtu,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
+ .rx_queue_count = sfc_rx_queue_count,
.tx_queue_setup = sfc_tx_queue_setup,
.tx_queue_release = sfc_tx_queue_release,
.flow_ctrl_get = sfc_flow_ctrl_get,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 278d583..ff9d799 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -257,6 +257,22 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
return done_pkts;
}
+unsigned int
+sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ struct sfc_rxq *rxq;
+
+ SFC_ASSERT(sw_index < sa->rxq_count);
+ rxq = sa->rxq_info[sw_index].rxq;
+
+ if (rxq == NULL || (rxq->state & SFC_RXQ_RUNNING) == 0)
+ return 0;
+
+ sfc_ev_qpoll(rxq->evq);
+
+ return rxq->pending - rxq->completed;
+}
+
static void
sfc_rx_qpurge(struct sfc_rxq *rxq)
{
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 69318ab..8064af6 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -140,6 +140,9 @@ void sfc_rx_qflush_failed(struct sfc_rxq *rxq);
uint16_t sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
uint16_t nb_pkts);
+unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa,
+ unsigned int sw_index);
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 18/32] net/sfc: add RxQ descriptor done callback
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (16 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 17/32] net/sfc: add callback to get RxQ pending descriptors count Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 19/32] net/sfc: support scattered Rx DMA Andrew Rybchenko
` (14 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 9 +++++++++
drivers/net/sfc/sfc_rx.c | 11 +++++++++++
drivers/net/sfc/sfc_rx.h | 1 +
3 files changed, 21 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 163f9ed..59dcdb4 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -855,6 +855,14 @@ sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
return sfc_rx_qdesc_npending(sa, rx_queue_id);
}
+static int
+sfc_rx_descriptor_done(void *queue, uint16_t offset)
+{
+ struct sfc_rxq *rxq = queue;
+
+ return sfc_rx_qdesc_done(rxq, offset);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -876,6 +884,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.rx_queue_count = sfc_rx_queue_count,
+ .rx_descriptor_done = sfc_rx_descriptor_done,
.tx_queue_setup = sfc_tx_queue_setup,
.tx_queue_release = sfc_tx_queue_release,
.flow_ctrl_get = sfc_flow_ctrl_get,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index ff9d799..802beb2 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -273,6 +273,17 @@ sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index)
return rxq->pending - rxq->completed;
}
+int
+sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset)
+{
+ if ((rxq->state & SFC_RXQ_RUNNING) == 0)
+ return 0;
+
+ sfc_ev_qpoll(rxq->evq);
+
+ return offset < (rxq->pending - rxq->completed);
+}
+
static void
sfc_rx_qpurge(struct sfc_rxq *rxq)
{
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 8064af6..8d8e709 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -142,6 +142,7 @@ uint16_t sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa,
unsigned int sw_index);
+int sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset);
#ifdef __cplusplus
}
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 19/32] net/sfc: support scattered Rx DMA
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (17 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 18/32] net/sfc: add RxQ descriptor done callback Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 20/32] net/sfc: support deferred start of receive queues Andrew Rybchenko
` (13 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 4 ++--
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_rx.c | 39 +++++++++++++++++++++++++++---------
4 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index b5887d5..74cc942 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -9,6 +9,7 @@ Link status = Y
Link status event = Y
MTU update = Y
Jumbo frame = Y
+Scattered Rx = Y
Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 1333f8b..2e30dfe 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:
- Received packet type information
+- Scattered Rx DMA for packet that are larger that a single Rx descriptor
+
Non-supported Features
----------------------
@@ -89,8 +91,6 @@ The features not yet supported include:
- VLAN stripping
-- Scattered receive
-
- LRO
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 59dcdb4..f1b655b 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -840,6 +840,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
qinfo->mp = rxq->refill_mb_pool;
qinfo->conf.rx_free_thresh = rxq->refill_threshold;
qinfo->conf.rx_drop_en = 1;
+ qinfo->scattered_rx = (rxq_info->type == EFX_RXQ_TYPE_SCATTER);
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 802beb2..2909ec0 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -193,6 +193,7 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
unsigned int prefix_size = rxq->prefix_size;
unsigned int done_pkts = 0;
boolean_t discard_next = B_FALSE;
+ struct rte_mbuf *scatter_pkt = NULL;
if (unlikely((rxq->state & SFC_RXQ_RUNNING) == 0))
return 0;
@@ -218,9 +219,6 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
if (desc_flags & (EFX_ADDR_MISMATCH | EFX_DISCARD))
goto discard;
- if (desc_flags & EFX_PKT_CONT)
- goto discard;
-
if (desc_flags & EFX_PKT_PREFIX_LEN) {
uint16_t tmp_size;
int rc __rte_unused;
@@ -237,6 +235,29 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rte_pktmbuf_data_len(m) = seg_len;
rte_pktmbuf_pkt_len(m) = seg_len;
+ if (scatter_pkt != NULL) {
+ if (rte_pktmbuf_chain(scatter_pkt, m) != 0) {
+ rte_mempool_put(rxq->refill_mb_pool,
+ scatter_pkt);
+ goto discard;
+ }
+ /* The packet to deliver */
+ m = scatter_pkt;
+ }
+
+ if (desc_flags & EFX_PKT_CONT) {
+ /* The packet is scattered, more fragments to come */
+ scatter_pkt = m;
+ /* Futher fragments have no prefix */
+ prefix_size = 0;
+ continue;
+ }
+
+ /* Scattered packet is done */
+ scatter_pkt = NULL;
+ /* The first fragment of the packet has prefix */
+ prefix_size = rxq->prefix_size;
+
m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
@@ -250,6 +271,9 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
rxd->mbuf = NULL;
}
+ /* pending is only moved when entire packet is received */
+ SFC_ASSERT(scatter_pkt == NULL);
+
rxq->completed = completed;
sfc_rx_qrefill(rxq);
@@ -618,7 +642,9 @@ 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 = EFX_RXQ_TYPE_DEFAULT;
+ rxq_info->type =
+ sa->eth_dev->data->dev_conf.rxmode.enable_scatter ?
+ EFX_RXQ_TYPE_SCATTER : EFX_RXQ_TYPE_DEFAULT;
evq_index = sfc_evq_index_by_rxq_sw_index(sa, sw_index);
@@ -806,11 +832,6 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
rxmode->hw_strip_crc = 1;
}
- if (rxmode->enable_scatter) {
- sfc_err(sa, "Scatter on Rx not supported");
- rc = EINVAL;
- }
-
if (rxmode->enable_lro) {
sfc_err(sa, "LRO not supported");
rc = EINVAL;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 20/32] net/sfc: support deferred start of receive queues
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (18 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 19/32] net/sfc: support scattered Rx DMA Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 21/32] net/sfc: add callback to get transmit queue information Andrew Rybchenko
` (12 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_rx.c | 18 +++++++------
drivers/net/sfc/sfc_rx.h | 2 ++
5 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 74cc942..4a887f0 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,6 +7,7 @@
Speed capabilities = Y
Link status = Y
Link status event = Y
+Queue start/stop = P
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 2e30dfe..b0beaf1 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -71,6 +71,8 @@ SFC EFX PMD has support for:
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
+- Deferred receive queue start
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f1b655b..c531fdb 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -840,6 +840,7 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
qinfo->mp = rxq->refill_mb_pool;
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->nb_desc = rxq_info->entries;
@@ -864,6 +865,54 @@ sfc_rx_descriptor_done(void *queue, uint16_t offset)
return sfc_rx_qdesc_done(rxq, offset);
}
+static int
+sfc_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+ sfc_adapter_lock(sa);
+
+ rc = EINVAL;
+ if (sa->state != SFC_ADAPTER_STARTED)
+ goto fail_not_started;
+
+ rc = sfc_rx_qstart(sa, rx_queue_id);
+ if (rc != 0)
+ goto fail_rx_qstart;
+
+ sa->rxq_info[rx_queue_id].deferred_started = B_TRUE;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+
+fail_rx_qstart:
+fail_not_started:
+ sfc_adapter_unlock(sa);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
+static int
+sfc_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "RxQ=%u", rx_queue_id);
+
+ sfc_adapter_lock(sa);
+ sfc_rx_qstop(sa, rx_queue_id);
+
+ sa->rxq_info[rx_queue_id].deferred_started = B_FALSE;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -882,6 +931,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_infos_get = sfc_dev_infos_get,
.dev_supported_ptypes_get = sfc_dev_supported_ptypes_get,
.mtu_set = sfc_dev_set_mtu,
+ .rx_queue_start = sfc_rx_queue_start,
+ .rx_queue_stop = sfc_rx_queue_stop,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.rx_queue_count = sfc_rx_queue_count,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 2909ec0..3bfce1c 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -444,6 +444,9 @@ sfc_rx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
rxq_info = &sa->rxq_info[sw_index];
rxq = rxq_info->rxq;
+
+ if (rxq->state == SFC_RXQ_INITIALIZED)
+ return;
SFC_ASSERT(rxq->state & SFC_RXQ_STARTED);
/* It seems to be used by DPDK for debug purposes only ('rte_ether') */
@@ -491,11 +494,6 @@ sfc_rx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_rx_desc,
rc = EINVAL;
}
- if (rx_conf->rx_deferred_start != 0) {
- sfc_err(sa, "RxQ deferred start is not supported");
- rc = EINVAL;
- }
-
return rc;
}
@@ -688,6 +686,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
rxq->state = SFC_RXQ_INITIALIZED;
rxq_info->rxq = rxq;
+ rxq_info->deferred_start = (rx_conf->rx_deferred_start != 0);
return 0;
@@ -742,9 +741,12 @@ sfc_rx_start(struct sfc_adapter *sa)
goto fail_rx_init;
for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
- rc = sfc_rx_qstart(sa, sw_index);
- if (rc != 0)
- goto fail_rx_qstart;
+ if ((!sa->rxq_info[sw_index].deferred_start ||
+ sa->rxq_info[sw_index].deferred_started)) {
+ rc = sfc_rx_qstart(sa, sw_index);
+ if (rc != 0)
+ goto fail_rx_qstart;
+ }
}
return 0;
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 8d8e709..4aa6aea 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -119,6 +119,8 @@ struct sfc_rxq_info {
unsigned int entries;
efx_rxq_type_t type;
struct sfc_rxq *rxq;
+ boolean_t deferred_start;
+ boolean_t deferred_started;
};
int sfc_rx_init(struct sfc_adapter *sa);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 21/32] net/sfc: add callback to get transmit queue information
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (19 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 20/32] net/sfc: support deferred start of receive queues Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 22/32] net/sfc: support Tx free threshold Andrew Rybchenko
` (11 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c531fdb..73e8fe2 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -847,6 +847,28 @@ sfc_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id,
sfc_adapter_unlock(sa);
}
+static void
+sfc_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+ struct rte_eth_txq_info *qinfo)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct sfc_txq_info *txq_info;
+
+ sfc_adapter_lock(sa);
+
+ SFC_ASSERT(tx_queue_id < sa->txq_count);
+
+ txq_info = &sa->txq_info[tx_queue_id];
+ SFC_ASSERT(txq_info->txq != NULL);
+
+ memset(qinfo, 0, sizeof(*qinfo));
+
+ qinfo->conf.txq_flags = txq_info->txq->flags;
+ qinfo->nb_desc = txq_info->entries;
+
+ sfc_adapter_unlock(sa);
+}
+
static uint32_t
sfc_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
{
@@ -944,6 +966,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.mac_addr_set = sfc_mac_addr_set,
.set_mc_addr_list = sfc_set_mc_addr_list,
.rxq_info_get = sfc_rx_queue_info_get,
+ .txq_info_get = sfc_tx_queue_info_get,
};
static int
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 22/32] net/sfc: support Tx free threshold
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (20 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 21/32] net/sfc: add callback to get transmit queue information Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 23/32] net/sfc: support deferred start of transmit queues Andrew Rybchenko
` (10 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 1 +
drivers/net/sfc/sfc_tweak.h | 3 +++
drivers/net/sfc/sfc_tx.c | 14 ++++++++------
drivers/net/sfc/sfc_tx.h | 10 +---------
4 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 73e8fe2..5d0d774 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -864,6 +864,7 @@ sfc_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
memset(qinfo, 0, sizeof(*qinfo));
qinfo->conf.txq_flags = txq_info->txq->flags;
+ qinfo->conf.tx_free_thresh = txq_info->txq->free_thresh;
qinfo->nb_desc = txq_info->entries;
sfc_adapter_unlock(sa);
diff --git a/drivers/net/sfc/sfc_tweak.h b/drivers/net/sfc/sfc_tweak.h
index 8a60f35..be39a5e 100644
--- a/drivers/net/sfc/sfc_tweak.h
+++ b/drivers/net/sfc/sfc_tweak.h
@@ -48,4 +48,7 @@
*/
#define SFC_TX_XMIT_PKTS_REAP_AT_LEAST_ONCE 0
+/** Default free threshold follows recommendations from DPDK documentation */
+#define SFC_TX_DEFAULT_FREE_THRESH 32
+
#endif /* _SFC_TWEAK_H_ */
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index a240610..13b24f7 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -54,7 +54,7 @@
#define SFC_TX_QFLUSH_POLL_ATTEMPTS (2000)
static int
-sfc_tx_qcheck_conf(struct sfc_adapter *sa,
+sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
const struct rte_eth_txconf *tx_conf)
{
unsigned int flags = tx_conf->txq_flags;
@@ -65,9 +65,10 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa,
rc = EINVAL;
}
- if (tx_conf->tx_free_thresh != 0) {
+ if (tx_conf->tx_free_thresh > EFX_TXQ_LIMIT(nb_tx_desc)) {
sfc_err(sa,
- "setting explicit TX free threshold is not supported");
+ "TxQ free threshold too large: %u vs maximum %u",
+ tx_conf->tx_free_thresh, EFX_TXQ_LIMIT(nb_tx_desc));
rc = EINVAL;
}
@@ -147,7 +148,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
sfc_log_init(sa, "TxQ = %u", sw_index);
- rc = sfc_tx_qcheck_conf(sa, tx_conf);
+ rc = sfc_tx_qcheck_conf(sa, nb_tx_desc, tx_conf);
if (rc != 0)
goto fail_bad_conf;
@@ -188,6 +189,8 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
txq->state = SFC_TXQ_INITIALIZED;
txq->ptr_mask = txq_info->entries - 1;
+ txq->free_thresh = (tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
+ SFC_TX_DEFAULT_FREE_THRESH;
txq->hw_index = sw_index;
txq->flags = tx_conf->txq_flags;
txq->evq = evq;
@@ -537,8 +540,7 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
unsigned int pkts_sent = 0;
efx_desc_t *pend = &txq->pend_desc[0];
const unsigned int hard_max_fill = EFX_TXQ_LIMIT(txq->ptr_mask + 1);
- const unsigned int soft_max_fill = hard_max_fill -
- SFC_TX_MAX_PKT_DESC;
+ const unsigned int soft_max_fill = hard_max_fill - txq->free_thresh;
unsigned int fill_level = added - txq->completed;
boolean_t reap_done;
int rc __rte_unused;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index fe2736b..f9eecc0 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -40,15 +40,6 @@ extern "C" {
#endif
/**
- * Estimated maximum number of segments that transmit packet consists of;
- * it is determined with respect to the expectation of a packet to consist
- * of a header plus a couple of data segments one of those crossing 4K page;
- * it is used by transmit path to avoid redundant reaping and, thus,
- * to avoid increase of latency
- */
-#define SFC_TX_MAX_PKT_DESC 4
-
-/**
* A segment must not cross 4K boundary
* (this is a requirement of NIC TX descriptors)
*/
@@ -85,6 +76,7 @@ struct sfc_txq {
unsigned int added;
unsigned int pending;
unsigned int completed;
+ unsigned int free_thresh;
unsigned int hw_index;
unsigned int flags;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 23/32] net/sfc: support deferred start of transmit queues
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (21 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 22/32] net/sfc: support Tx free threshold Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 24/32] net/sfc: support VLAN offload on transmit path Andrew Rybchenko
` (9 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 +-
doc/guides/nics/sfc_efx.rst | 2 +-
drivers/net/sfc/sfc_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_tx.c | 18 +++++++------
drivers/net/sfc/sfc_tx.h | 2 ++
5 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 4a887f0..38bf9d2 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -7,7 +7,7 @@
Speed capabilities = Y
Link status = Y
Link status event = Y
-Queue start/stop = P
+Queue start/stop = Y
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index b0beaf1..304dc95 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -71,7 +71,7 @@ SFC EFX PMD has support for:
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
-- Deferred receive queue start
+- Deferred receive and transmit queue start
Non-supported Features
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 5d0d774..ba3c838 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -865,6 +865,7 @@ sfc_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id,
qinfo->conf.txq_flags = txq_info->txq->flags;
qinfo->conf.tx_free_thresh = txq_info->txq->free_thresh;
+ qinfo->conf.tx_deferred_start = txq_info->deferred_start;
qinfo->nb_desc = txq_info->entries;
sfc_adapter_unlock(sa);
@@ -936,6 +937,54 @@ sfc_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
return 0;
}
+static int
+sfc_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "TxQ = %u", tx_queue_id);
+
+ sfc_adapter_lock(sa);
+
+ rc = EINVAL;
+ if (sa->state != SFC_ADAPTER_STARTED)
+ goto fail_not_started;
+
+ rc = sfc_tx_qstart(sa, tx_queue_id);
+ if (rc != 0)
+ goto fail_tx_qstart;
+
+ sa->txq_info[tx_queue_id].deferred_started = B_TRUE;
+
+ sfc_adapter_unlock(sa);
+ return 0;
+
+fail_tx_qstart:
+
+fail_not_started:
+ sfc_adapter_unlock(sa);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
+static int
+sfc_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ sfc_log_init(sa, "TxQ = %u", tx_queue_id);
+
+ sfc_adapter_lock(sa);
+
+ sfc_tx_qstop(sa, tx_queue_id);
+
+ sa->txq_info[tx_queue_id].deferred_started = B_FALSE;
+
+ sfc_adapter_unlock(sa);
+ return 0;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -956,6 +1005,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.mtu_set = sfc_dev_set_mtu,
.rx_queue_start = sfc_rx_queue_start,
.rx_queue_stop = sfc_rx_queue_stop,
+ .tx_queue_start = sfc_tx_queue_start,
+ .tx_queue_stop = sfc_tx_queue_stop,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
.rx_queue_count = sfc_rx_queue_count,
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 13b24f7..15a6f9f 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -72,11 +72,6 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
rc = EINVAL;
}
- if (tx_conf->tx_deferred_start != 0) {
- sfc_err(sa, "TX queue deferred start is not supported (yet)");
- rc = EINVAL;
- }
-
if (tx_conf->tx_thresh.pthresh != 0 ||
tx_conf->tx_thresh.hthresh != 0 ||
tx_conf->tx_thresh.wthresh != 0) {
@@ -198,6 +193,7 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
evq->txq = txq;
txq_info->txq = txq;
+ txq_info->deferred_start = (tx_conf->tx_deferred_start != 0);
return 0;
@@ -425,6 +421,9 @@ sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
txq = txq_info->txq;
+ if (txq->state == SFC_TXQ_INITIALIZED)
+ return;
+
SFC_ASSERT(txq->state & SFC_TXQ_STARTED);
txq->state &= ~SFC_TXQ_RUNNING;
@@ -497,9 +496,12 @@ sfc_tx_start(struct sfc_adapter *sa)
goto fail_efx_tx_init;
for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
- rc = sfc_tx_qstart(sa, sw_index);
- if (rc != 0)
- goto fail_tx_qstart;
+ if (!(sa->txq_info[sw_index].deferred_start) ||
+ sa->txq_info[sw_index].deferred_started) {
+ rc = sfc_tx_qstart(sa, sw_index);
+ if (rc != 0)
+ goto fail_tx_qstart;
+ }
}
return 0;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index f9eecc0..632e3be 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -91,6 +91,8 @@ sfc_txq_sw_index(const struct sfc_txq *txq)
struct sfc_txq_info {
unsigned int entries;
struct sfc_txq *txq;
+ boolean_t deferred_start;
+ boolean_t deferred_started;
};
int sfc_tx_init(struct sfc_adapter *sa);
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 24/32] net/sfc: support VLAN offload on transmit path
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (22 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 23/32] net/sfc: support deferred start of transmit queues Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask Andrew Rybchenko
` (8 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_ethdev.c | 8 +++++--
drivers/net/sfc/sfc_tx.c | 45 +++++++++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_tx.h | 1 +
5 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 38bf9d2..e7a1143 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -15,6 +15,7 @@ Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
Flow control = Y
+VLAN offload = P
L3 checksum offload = Y
L4 checksum offload = Y
Packet type parsing = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 304dc95..2244e7a 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -73,6 +73,8 @@ SFC EFX PMD has support for:
- Deferred receive and transmit queue start
+- Transmit VLAN insertion (if running firmware variant supports it)
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index ba3c838..0de17ca 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -46,6 +46,7 @@ static void
sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct sfc_adapter *sa = dev->data->dev_private;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
RTE_SET_USED(dev_info);
@@ -78,8 +79,11 @@ 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;
- dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOVLANOFFL |
- ETH_TXQ_FLAGS_NOXSUMSCTP;
+ dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOXSUMSCTP;
+ if (!encp->enc_hw_tx_insert_vlan_enabled)
+ dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOVLANOFFL;
+ else
+ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_VLAN_INSERT;
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 15a6f9f..86bcfec 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -58,6 +58,7 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
const struct rte_eth_txconf *tx_conf)
{
unsigned int flags = tx_conf->txq_flags;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
int rc = 0;
if (tx_conf->tx_rs_thresh != 0) {
@@ -80,7 +81,8 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa, uint16_t nb_tx_desc,
rc = EINVAL;
}
- if ((flags & ETH_TXQ_FLAGS_NOVLANOFFL) == 0) {
+ if (!encp->enc_hw_tx_insert_vlan_enabled &&
+ (flags & ETH_TXQ_FLAGS_NOVLANOFFL) == 0) {
sfc_err(sa, "VLAN offload is not supported");
rc = EINVAL;
}
@@ -384,6 +386,7 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
goto fail_tx_qcreate;
txq->added = txq->pending = txq->completed = desc_index;
+ txq->hw_vlan_tci = 0;
efx_tx_qenable(txq->common);
@@ -533,6 +536,37 @@ sfc_tx_stop(struct sfc_adapter *sa)
efx_tx_fini(sa->nic);
}
+/*
+ * The function is used to insert or update VLAN tag;
+ * the firmware has state of the firmware tag to insert per TxQ
+ * (controlled by option descriptors), hence, if the tag of the
+ * packet to be sent is different from one remembered by the firmware,
+ * the function will update it
+ */
+static unsigned int
+sfc_tx_maybe_insert_tag(struct sfc_txq *txq, struct rte_mbuf *m,
+ efx_desc_t **pend)
+{
+ uint16_t this_tag = ((m->ol_flags & PKT_TX_VLAN_PKT) ?
+ m->vlan_tci : 0);
+
+ if (this_tag == txq->hw_vlan_tci)
+ return 0;
+
+ /*
+ * The expression inside SFC_ASSERT() is not desired to be checked in
+ * a non-debug build because it might be too expensive on the data path
+ */
+ SFC_ASSERT(efx_nic_cfg_get(txq->evq->sa->nic)->enc_hw_tx_insert_vlan_enabled);
+
+ efx_tx_qdesc_vlantci_create(txq->common, rte_cpu_to_be_16(this_tag),
+ *pend);
+ (*pend)++;
+ txq->hw_vlan_tci = this_tag;
+
+ return 1;
+}
+
uint16_t
sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
{
@@ -574,6 +608,15 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
size_t pkt_len = m_seg->pkt_len;
unsigned int pkt_descs = 0;
+ /*
+ * Here VLAN TCI is expected to be zero in case if no
+ * DEV_TX_VLAN_OFFLOAD capability is advertised;
+ * if the calling app ignores the absence of
+ * DEV_TX_VLAN_OFFLOAD and pushes VLAN TCI, then
+ * TX_ERROR will occur
+ */
+ pkt_descs += sfc_tx_maybe_insert_tag(txq, m_seg, &pend);
+
for (; m_seg != NULL; m_seg = m_seg->next) {
efsys_dma_addr_t next_frag;
size_t seg_len;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 632e3be..4d25c6a 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -77,6 +77,7 @@ struct sfc_txq {
unsigned int pending;
unsigned int completed;
unsigned int free_thresh;
+ uint16_t hw_vlan_tci;
unsigned int hw_index;
unsigned int flags;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (23 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 24/32] net/sfc: support VLAN offload on transmit path Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2017-01-18 11:30 ` Ferruh Yigit
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 26/32] net/sfc: add basic stubs for RSS support on driver attach Andrew Rybchenko
` (7 subsequent siblings)
32 siblings, 1 reply; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Andrew Rybchenko
From: Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
ICC complains that enumerated type mixed with another type.
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/base/ef10_rx.c | 8 ++++----
drivers/net/sfc/base/efx.h | 12 ++++++------
drivers/net/sfc/base/efx_rx.c | 8 ++++----
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c
index 2bcd823..b65faed 100644
--- a/drivers/net/sfc/base/ef10_rx.c
+++ b/drivers/net/sfc/base/ef10_rx.c
@@ -304,13 +304,13 @@ efx_mcdi_rss_context_set_flags(
MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
- (type & (1U << EFX_RX_HASH_IPV4)) ? 1 : 0,
+ (type & EFX_RX_HASH_IPV4) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
- (type & (1U << EFX_RX_HASH_TCPIPV4)) ? 1 : 0,
+ (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
- (type & (1U << EFX_RX_HASH_IPV6)) ? 1 : 0,
+ (type & EFX_RX_HASH_IPV6) ? 1 : 0,
RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
- (type & (1U << EFX_RX_HASH_TCPIPV6)) ? 1 : 0);
+ (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0);
efx_mcdi_execute(enp, &req);
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index 025721f..0815d7a 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1851,12 +1851,12 @@ typedef enum efx_rx_hash_alg_e {
EFX_RX_HASHALG_TOEPLITZ
} efx_rx_hash_alg_t;
-typedef enum efx_rx_hash_type_e {
- EFX_RX_HASH_IPV4 = 0,
- EFX_RX_HASH_TCPIPV4,
- EFX_RX_HASH_IPV6,
- EFX_RX_HASH_TCPIPV6,
-} efx_rx_hash_type_t;
+#define EFX_RX_HASH_IPV4 (1U << 0)
+#define EFX_RX_HASH_TCPIPV4 (1U << 1)
+#define EFX_RX_HASH_IPV6 (1U << 2)
+#define EFX_RX_HASH_TCPIPV6 (1U << 3)
+
+typedef unsigned int efx_rx_hash_type_t;
typedef enum efx_rx_hash_support_e {
EFX_RX_HASH_UNAVAILABLE = 0, /* Hardware hash not inserted */
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
index 330d2aa..c815634 100644
--- a/drivers/net/sfc/base/efx_rx.c
+++ b/drivers/net/sfc/base/efx_rx.c
@@ -786,12 +786,12 @@ siena_rx_scale_mode_set(
case EFX_RX_HASHALG_TOEPLITZ:
EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
- type & (1 << EFX_RX_HASH_IPV4),
- type & (1 << EFX_RX_HASH_TCPIPV4));
+ type & EFX_RX_HASH_IPV4,
+ type & EFX_RX_HASH_TCPIPV4);
EFX_RX_TOEPLITZ_IPV6_HASH(enp,
- type & (1 << EFX_RX_HASH_IPV6),
- type & (1 << EFX_RX_HASH_TCPIPV6),
+ type & EFX_RX_HASH_IPV6,
+ type & EFX_RX_HASH_TCPIPV6,
rc);
if (rc != 0)
goto fail1;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 26/32] net/sfc: add basic stubs for RSS support on driver attach
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (24 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 27/32] net/sfc: support RSS hash offload Andrew Rybchenko
` (6 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/efsys.h | 2 +-
drivers/net/sfc/sfc.c | 76 +++++++++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc.h | 17 ++++++++++
drivers/net/sfc/sfc_ethdev.c | 8 +++++
drivers/net/sfc/sfc_rx.c | 81 +++++++++++++++++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_rx.h | 8 +++++
7 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 2244e7a..17e81dd 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:
- Received packet type information
+- Receive side scaling (RSS)
+
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
- Deferred receive and transmit queue start
diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h
index 0f941e6..fb2f3b5 100644
--- a/drivers/net/sfc/efsys.h
+++ b/drivers/net/sfc/efsys.h
@@ -195,7 +195,7 @@ prefetch_read_once(const volatile void *addr)
#define EFSYS_OPT_BOOTCFG 0
#define EFSYS_OPT_DIAG 0
-#define EFSYS_OPT_RX_SCALE 0
+#define EFSYS_OPT_RX_SCALE 1
#define EFSYS_OPT_QSTATS 0
/* Filters support is required for SFN7xxx and SFN8xx */
#define EFSYS_OPT_FILTER 1
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index e2e6c9e..e79367d 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -484,6 +484,73 @@ sfc_mem_bar_fini(struct sfc_adapter *sa)
memset(ebp, 0, sizeof(*ebp));
}
+#if EFSYS_OPT_RX_SCALE
+/*
+ * A fixed RSS key which has a property of being symmetric
+ * (symmetrical flows are distributed to the same CPU)
+ * and also known to give a uniform distribution
+ * (a good distribution of traffic between different CPUs)
+ */
+static const uint8_t default_rss_key[SFC_RSS_KEY_SIZE] = {
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+ 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
+};
+#endif
+
+static int
+sfc_set_rss_defaults(struct sfc_adapter *sa)
+{
+#if EFSYS_OPT_RX_SCALE
+ int rc;
+
+ rc = efx_intr_init(sa->nic, sa->intr.type, NULL);
+ if (rc != 0)
+ goto fail_intr_init;
+
+ rc = efx_ev_init(sa->nic);
+ if (rc != 0)
+ goto fail_ev_init;
+
+ rc = efx_rx_init(sa->nic);
+ if (rc != 0)
+ goto fail_rx_init;
+
+ rc = efx_rx_scale_support_get(sa->nic, &sa->rss_support);
+ if (rc != 0)
+ goto fail_scale_support_get;
+
+ rc = efx_rx_hash_support_get(sa->nic, &sa->hash_support);
+ if (rc != 0)
+ goto fail_hash_support_get;
+
+ efx_rx_fini(sa->nic);
+ efx_ev_fini(sa->nic);
+ efx_intr_fini(sa->nic);
+
+ sa->rss_hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS);
+
+ rte_memcpy(sa->rss_key, default_rss_key, sizeof(sa->rss_key));
+
+ return 0;
+
+fail_hash_support_get:
+fail_scale_support_get:
+fail_rx_init:
+ efx_ev_fini(sa->nic);
+
+fail_ev_init:
+ efx_intr_fini(sa->nic);
+
+fail_intr_init:
+ return rc;
+#else
+ return 0;
+#endif
+}
+
int
sfc_attach(struct sfc_adapter *sa)
{
@@ -550,6 +617,10 @@ sfc_attach(struct sfc_adapter *sa)
efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
&sa->port.phy_adv_cap_mask);
+ rc = sfc_set_rss_defaults(sa);
+ if (rc != 0)
+ goto fail_set_rss_defaults;
+
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
@@ -558,7 +629,12 @@ sfc_attach(struct sfc_adapter *sa)
sfc_log_init(sa, "done");
return 0;
+fail_set_rss_defaults:
+ sfc_intr_detach(sa);
+
fail_intr_attach:
+ efx_nic_fini(sa->nic);
+
fail_estimate_rsrc_limits:
fail_nic_reset:
sfc_log_init(sa, "unprobe nic");
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 7b135e1..d02d1c0 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -42,6 +42,13 @@
extern "C" {
#endif
+#if EFSYS_OPT_RX_SCALE
+/** RSS key length (bytes) */
+#define SFC_RSS_KEY_SIZE 40
+/** RSS hash offloads mask */
+#define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP)
+#endif
+
/*
* +---------------+
* | UNINITIALIZED |<-----------+
@@ -187,6 +194,16 @@ struct sfc_adapter {
unsigned int txq_count;
struct sfc_txq_info *txq_info;
+
+ unsigned int rss_channels;
+
+#if EFSYS_OPT_RX_SCALE
+ efx_rx_scale_support_t rss_support;
+ efx_rx_hash_support_t hash_support;
+ efx_rx_hash_type_t rss_hash_types;
+ unsigned int rss_tbl[EFX_RSS_TBL_SIZE];
+ uint8_t rss_key[SFC_RSS_KEY_SIZE];
+#endif
};
/*
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 0de17ca..b17607f 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -85,6 +85,14 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
else
dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_VLAN_INSERT;
+#if EFSYS_OPT_RX_SCALE
+ if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) {
+ dev_info->reta_size = EFX_RSS_TBL_SIZE;
+ dev_info->hash_key_size = SFC_RSS_KEY_SIZE;
+ dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS;
+ }
+#endif
+
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
/* The RXQ hardware requires that the descriptor count is a power
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 3bfce1c..36a7d71 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -411,7 +411,8 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
if (sw_index == 0) {
rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common,
- B_FALSE);
+ (sa->rss_channels > 1) ?
+ B_TRUE : B_FALSE);
if (rc != 0)
goto fail_mac_filter_default_rxq_set;
}
@@ -683,6 +684,11 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
rxq->batch_max = encp->enc_rx_batch_max;
rxq->prefix_size = encp->enc_rx_prefix_size;
+#if EFSYS_OPT_RX_SCALE
+ if (sa->hash_support == EFX_RX_HASH_AVAILABLE)
+ rxq->flags |= SFC_RXQ_RSS_HASH;
+#endif
+
rxq->state = SFC_RXQ_INITIALIZED;
rxq_info->rxq = rxq;
@@ -728,6 +734,56 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
rte_free(rxq);
}
+#if EFSYS_OPT_RX_SCALE
+efx_rx_hash_type_t
+sfc_rte_to_efx_hash_type(uint64_t rss_hf)
+{
+ efx_rx_hash_type_t efx_hash_types = 0;
+
+ if ((rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 |
+ ETH_RSS_NONFRAG_IPV4_OTHER)) != 0)
+ efx_hash_types |= EFX_RX_HASH_IPV4;
+
+ if ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != 0)
+ efx_hash_types |= EFX_RX_HASH_TCPIPV4;
+
+ if ((rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
+ ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX)) != 0)
+ efx_hash_types |= EFX_RX_HASH_IPV6;
+
+ if ((rss_hf & (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX)) != 0)
+ efx_hash_types |= EFX_RX_HASH_TCPIPV6;
+
+ return efx_hash_types;
+}
+#endif
+
+static int
+sfc_rx_rss_config(struct sfc_adapter *sa)
+{
+ int rc = 0;
+
+#if EFSYS_OPT_RX_SCALE
+ if (sa->rss_channels > 1) {
+ rc = efx_rx_scale_mode_set(sa->nic, EFX_RX_HASHALG_TOEPLITZ,
+ sa->rss_hash_types, B_TRUE);
+ if (rc != 0)
+ goto finish;
+
+ rc = efx_rx_scale_key_set(sa->nic, sa->rss_key,
+ sizeof(sa->rss_key));
+ if (rc != 0)
+ goto finish;
+
+ rc = efx_rx_scale_tbl_set(sa->nic, sa->rss_tbl,
+ sizeof(sa->rss_tbl));
+ }
+
+finish:
+#endif
+ return rc;
+}
+
int
sfc_rx_start(struct sfc_adapter *sa)
{
@@ -740,6 +796,10 @@ sfc_rx_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_rx_init;
+ rc = sfc_rx_rss_config(sa);
+ if (rc != 0)
+ goto fail_rss_config;
+
for (sw_index = 0; sw_index < sa->rxq_count; ++sw_index) {
if ((!sa->rxq_info[sw_index].deferred_start ||
sa->rxq_info[sw_index].deferred_started)) {
@@ -755,6 +815,7 @@ sfc_rx_start(struct sfc_adapter *sa)
while (sw_index-- > 0)
sfc_rx_qstop(sa, sw_index);
+fail_rss_config:
efx_rx_fini(sa->nic);
fail_rx_init:
@@ -801,6 +862,14 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
case ETH_MQ_RX_NONE:
/* No special checks are required */
break;
+#if EFSYS_OPT_RX_SCALE
+ case ETH_MQ_RX_RSS:
+ if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ sfc_err(sa, "RSS is not available");
+ rc = EINVAL;
+ }
+ break;
+#endif
default:
sfc_err(sa, "Rx multi-queue mode %u not supported",
rxmode->mq_mode);
@@ -876,6 +945,16 @@ sfc_rx_init(struct sfc_adapter *sa)
goto fail_rx_qinit_info;
}
+#if EFSYS_OPT_RX_SCALE
+ sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ?
+ MIN(sa->rxq_count, EFX_MAXRSS) : 1;
+
+ if (sa->rss_channels > 1) {
+ for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index)
+ sa->rss_tbl[sw_index] = sw_index % sa->rss_channels;
+ }
+#endif
+
return 0;
fail_rx_qinit_info:
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index 4aa6aea..c0cb17a 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -83,6 +83,10 @@ struct sfc_rxq {
unsigned int completed;
uint16_t batch_max;
uint16_t prefix_size;
+#if EFSYS_OPT_RX_SCALE
+ unsigned int flags;
+#define SFC_RXQ_RSS_HASH 0x1
+#endif
/* Used on refill */
unsigned int added;
@@ -146,6 +150,10 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa,
unsigned int sw_index);
int sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset);
+#if EFSYS_OPT_RX_SCALE
+efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf);
+#endif
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 27/32] net/sfc: support RSS hash offload
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (25 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 26/32] net/sfc: add basic stubs for RSS support on driver attach Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 28/32] net/sfc: add callback to query RSS key and hash types config Andrew Rybchenko
` (5 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Extract RSS hash provided by the HW in the prefix and put it to mbuf.
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/sfc_rx.c | 31 ++++++++++++++++++++++++++++++-
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index e7a1143..debea27 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -14,6 +14,7 @@ Scattered Rx = Y
Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
+RSS hash = Y
Flow control = Y
VLAN offload = P
L3 checksum offload = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 17e81dd..bc45b17 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -71,6 +71,8 @@ SFC EFX PMD has support for:
- Receive side scaling (RSS)
+- RSS hash
+
- Scattered Rx DMA for packet that are larger that a single Rx descriptor
- Deferred receive and transmit queue start
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 36a7d71..9b507c3 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -185,6 +185,28 @@ sfc_rx_desc_flags_to_packet_type(const unsigned int desc_flags)
((desc_flags & EFX_PKT_UDP) ? RTE_PTYPE_L4_UDP : 0);
}
+static void
+sfc_rx_set_rss_hash(struct sfc_rxq *rxq, unsigned int flags, struct rte_mbuf *m)
+{
+#if EFSYS_OPT_RX_SCALE
+ uint8_t *mbuf_data;
+
+
+ if ((rxq->flags & SFC_RXQ_RSS_HASH) == 0)
+ return;
+
+ mbuf_data = rte_pktmbuf_mtod(m, uint8_t *);
+
+ if (flags & (EFX_PKT_IPV4 | EFX_PKT_IPV6)) {
+ m->hash.rss = efx_pseudo_hdr_hash_get(rxq->common,
+ EFX_RX_HASHALG_TOEPLITZ,
+ mbuf_data);
+
+ m->ol_flags |= PKT_RX_RSS_HASH;
+ }
+#endif
+}
+
uint16_t
sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
@@ -231,7 +253,6 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
seg_len = rxd->size - prefix_size;
}
- m->data_off += prefix_size;
rte_pktmbuf_data_len(m) = seg_len;
rte_pktmbuf_pkt_len(m) = seg_len;
@@ -261,6 +282,14 @@ sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
m->ol_flags = sfc_rx_desc_flags_to_offload_flags(desc_flags);
m->packet_type = sfc_rx_desc_flags_to_packet_type(desc_flags);
+ /*
+ * Extract RSS hash from the packet prefix and
+ * set the corresponding field (if needed and possible)
+ */
+ sfc_rx_set_rss_hash(rxq, desc_flags, m);
+
+ m->data_off += prefix_size;
+
*rx_pkts++ = m;
done_pkts++;
continue;
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 28/32] net/sfc: add callback to query RSS key and hash types config
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (26 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 27/32] net/sfc: support RSS hash offload Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 29/32] net/sfc: add callback to set " Andrew Rybchenko
` (4 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 33 +++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_rx.c | 22 ++++++++++++++++++++++
drivers/net/sfc/sfc_rx.h | 1 +
3 files changed, 56 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index b17607f..c78d798 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -997,6 +997,36 @@ sfc_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
return 0;
}
+#if EFSYS_OPT_RX_SCALE
+static int
+sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE))
+ return -ENOTSUP;
+
+ sfc_adapter_lock(sa);
+
+ /*
+ * Mapping of hash configuration between RTE and EFX is not one-to-one,
+ * hence, conversion is done here to derive a correct set of ETH_RSS
+ * flags which corresponds to the active EFX configuration stored
+ * locally in 'sfc_adapter' and kept up-to-date
+ */
+ rss_conf->rss_hf = sfc_efx_to_rte_hash_type(sa->rss_hash_types);
+ rss_conf->rss_key_len = SFC_RSS_KEY_SIZE;
+ if (rss_conf->rss_key != NULL)
+ rte_memcpy(rss_conf->rss_key, sa->rss_key, SFC_RSS_KEY_SIZE);
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
+#endif
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -1028,6 +1058,9 @@ 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,
+#if EFSYS_OPT_RX_SCALE
+ .rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
+#endif
.set_mc_addr_list = sfc_set_mc_addr_list,
.rxq_info_get = sfc_rx_queue_info_get,
.txq_info_get = sfc_tx_queue_info_get,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 9b507c3..906536e 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -785,6 +785,28 @@ sfc_rte_to_efx_hash_type(uint64_t rss_hf)
return efx_hash_types;
}
+
+uint64_t
+sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types)
+{
+ uint64_t rss_hf = 0;
+
+ if ((efx_hash_types & EFX_RX_HASH_IPV4) != 0)
+ rss_hf |= (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 |
+ ETH_RSS_NONFRAG_IPV4_OTHER);
+
+ if ((efx_hash_types & EFX_RX_HASH_TCPIPV4) != 0)
+ rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+
+ if ((efx_hash_types & EFX_RX_HASH_IPV6) != 0)
+ rss_hf |= (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
+ ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX);
+
+ if ((efx_hash_types & EFX_RX_HASH_TCPIPV6) != 0)
+ rss_hf |= (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX);
+
+ return rss_hf;
+}
#endif
static int
diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h
index c0cb17a..45b1d77 100644
--- a/drivers/net/sfc/sfc_rx.h
+++ b/drivers/net/sfc/sfc_rx.h
@@ -152,6 +152,7 @@ int sfc_rx_qdesc_done(struct sfc_rxq *rxq, unsigned int offset);
#if EFSYS_OPT_RX_SCALE
efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf);
+uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types);
#endif
#ifdef __cplusplus
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 29/32] net/sfc: add callback to set RSS key and hash types config
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (27 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 28/32] net/sfc: add callback to query RSS key and hash types config Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 30/32] net/sfc: add callback to query RSS redirection table Andrew Rybchenko
` (3 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/sfc_ethdev.c | 63 ++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index debea27..4f6f117 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -15,6 +15,7 @@ Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
RSS hash = Y
+RSS key update = Y
Flow control = Y
VLAN offload = P
L3 checksum offload = Y
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index c78d798..f9a766c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1025,6 +1025,68 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
return 0;
}
+
+static int
+sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ unsigned int efx_hash_types;
+ int rc = 0;
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)) {
+ sfc_err(sa, "RSS is not available");
+ return -ENOTSUP;
+ }
+
+ if ((rss_conf->rss_key != NULL) &&
+ (rss_conf->rss_key_len != sizeof(sa->rss_key))) {
+ sfc_err(sa, "RSS key size is wrong (should be %lu)",
+ sizeof(sa->rss_key));
+ return -EINVAL;
+ }
+
+ if ((rss_conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) {
+ sfc_err(sa, "unsupported hash functions requested");
+ return -EINVAL;
+ }
+
+ sfc_adapter_lock(sa);
+
+ efx_hash_types = sfc_rte_to_efx_hash_type(rss_conf->rss_hf);
+
+ rc = efx_rx_scale_mode_set(sa->nic, EFX_RX_HASHALG_TOEPLITZ,
+ efx_hash_types, B_TRUE);
+ if (rc != 0)
+ goto fail_scale_mode_set;
+
+ if (rss_conf->rss_key != NULL) {
+ if (sa->state == SFC_ADAPTER_STARTED) {
+ rc = efx_rx_scale_key_set(sa->nic, rss_conf->rss_key,
+ sizeof(sa->rss_key));
+ if (rc != 0)
+ goto fail_scale_key_set;
+ }
+
+ rte_memcpy(sa->rss_key, rss_conf->rss_key, sizeof(sa->rss_key));
+ }
+
+ sa->rss_hash_types = efx_hash_types;
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+
+fail_scale_key_set:
+ if (efx_rx_scale_mode_set(sa->nic, EFX_RX_HASHALG_TOEPLITZ,
+ sa->rss_hash_types, B_TRUE) != 0)
+ sfc_err(sa, "failed to restore RSS mode");
+
+fail_scale_mode_set:
+ sfc_adapter_unlock(sa);
+ return -rc;
+}
#endif
static const struct eth_dev_ops sfc_eth_dev_ops = {
@@ -1059,6 +1121,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
#if EFSYS_OPT_RX_SCALE
+ .rss_hash_update = sfc_dev_rss_hash_update,
.rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
#endif
.set_mc_addr_list = sfc_set_mc_addr_list,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 30/32] net/sfc: add callback to query RSS redirection table
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (28 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 29/32] net/sfc: add callback to set " Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 31/32] net/sfc: add callback to update " Andrew Rybchenko
` (2 subsequent siblings)
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
drivers/net/sfc/sfc_ethdev.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f9a766c..0cd96ac 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1087,6 +1087,36 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev,
sfc_adapter_unlock(sa);
return -rc;
}
+
+static int
+sfc_dev_rss_reta_query(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int entry;
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE))
+ return -ENOTSUP;
+
+ if (reta_size != EFX_RSS_TBL_SIZE)
+ return -EINVAL;
+
+ sfc_adapter_lock(sa);
+
+ for (entry = 0; entry < reta_size; entry++) {
+ int grp = entry / RTE_RETA_GROUP_SIZE;
+ int grp_idx = entry % RTE_RETA_GROUP_SIZE;
+
+ if ((reta_conf[grp].mask >> grp_idx) & 1)
+ reta_conf[grp].reta[grp_idx] = sa->rss_tbl[entry];
+ }
+
+ sfc_adapter_unlock(sa);
+
+ return 0;
+}
#endif
static const struct eth_dev_ops sfc_eth_dev_ops = {
@@ -1121,6 +1151,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
#if EFSYS_OPT_RX_SCALE
+ .reta_query = sfc_dev_rss_reta_query,
.rss_hash_update = sfc_dev_rss_hash_update,
.rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 31/32] net/sfc: add callback to update RSS redirection table
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (29 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 30/32] net/sfc: add callback to query RSS redirection table Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 32/32] net/sfc: support firmware-assisted TSOv2 Andrew Rybchenko
2016-12-16 9:57 ` [dpdk-dev] [PATCH v2 00/32] Support more features in Solarflare PMD Ferruh Yigit
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
drivers/net/sfc/sfc_ethdev.c | 60 ++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 4f6f117..07c58d5 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -16,6 +16,7 @@ Allmulticast mode = Y
Multicast MAC filter = Y
RSS hash = Y
RSS key update = Y
+RSS reta update = Y
Flow control = Y
VLAN offload = P
L3 checksum offload = Y
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 0cd96ac..f45072c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1117,6 +1117,65 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev,
return 0;
}
+
+static int
+sfc_dev_rss_reta_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ unsigned int *rss_tbl_new;
+ uint16_t entry;
+ int rc;
+
+
+ if ((sa->rss_channels == 1) ||
+ (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)) {
+ sfc_err(sa, "RSS is not available");
+ return -ENOTSUP;
+ }
+
+ if (reta_size != EFX_RSS_TBL_SIZE) {
+ sfc_err(sa, "RETA size is wrong (should be %u)",
+ EFX_RSS_TBL_SIZE);
+ return -EINVAL;
+ }
+
+ rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(sa->rss_tbl), 0);
+ if (rss_tbl_new == NULL)
+ return -ENOMEM;
+
+ sfc_adapter_lock(sa);
+
+ rte_memcpy(rss_tbl_new, sa->rss_tbl, sizeof(sa->rss_tbl));
+
+ for (entry = 0; entry < reta_size; entry++) {
+ int grp_idx = entry % RTE_RETA_GROUP_SIZE;
+ struct rte_eth_rss_reta_entry64 *grp;
+
+ grp = &reta_conf[entry / RTE_RETA_GROUP_SIZE];
+
+ if (grp->mask & (1ull << grp_idx)) {
+ if (grp->reta[grp_idx] >= sa->rss_channels) {
+ rc = EINVAL;
+ goto bad_reta_entry;
+ }
+ rss_tbl_new[entry] = grp->reta[grp_idx];
+ }
+ }
+
+ rc = efx_rx_scale_tbl_set(sa->nic, rss_tbl_new, EFX_RSS_TBL_SIZE);
+ if (rc == 0)
+ rte_memcpy(sa->rss_tbl, rss_tbl_new, sizeof(sa->rss_tbl));
+
+bad_reta_entry:
+ sfc_adapter_unlock(sa);
+
+ rte_free(rss_tbl_new);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
+}
#endif
static const struct eth_dev_ops sfc_eth_dev_ops = {
@@ -1151,6 +1210,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.flow_ctrl_set = sfc_flow_ctrl_set,
.mac_addr_set = sfc_mac_addr_set,
#if EFSYS_OPT_RX_SCALE
+ .reta_update = sfc_dev_rss_reta_update,
.reta_query = sfc_dev_rss_reta_query,
.rss_hash_update = sfc_dev_rss_hash_update,
.rss_hash_conf_get = sfc_dev_rss_hash_conf_get,
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* [dpdk-dev] [PATCH v2 32/32] net/sfc: support firmware-assisted TSOv2
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (30 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 31/32] net/sfc: add callback to update " Andrew Rybchenko
@ 2016-12-15 12:51 ` Andrew Rybchenko
2016-12-16 9:57 ` [dpdk-dev] [PATCH v2 00/32] Support more features in Solarflare PMD Ferruh Yigit
32 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2016-12-15 12:51 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Ivan Malov
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Mark Spender <mspender@solarflare.com>
Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
---
config/common_base | 1 +
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 8 ++
drivers/net/sfc/Makefile | 4 +
drivers/net/sfc/sfc.c | 8 ++
drivers/net/sfc/sfc.h | 2 +
drivers/net/sfc/sfc_ethdev.c | 3 +
drivers/net/sfc/sfc_tso.c | 200 +++++++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_tx.c | 89 +++++++++++++++-
drivers/net/sfc/sfc_tx.h | 28 +++++
10 files changed, 341 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/sfc/sfc_tso.c
diff --git a/config/common_base b/config/common_base
index 59cb830..faee944 100644
--- a/config/common_base
+++ b/config/common_base
@@ -343,6 +343,7 @@ CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
#
CONFIG_RTE_LIBRTE_SFC_EFX_PMD=y
CONFIG_RTE_LIBRTE_SFC_EFX_DEBUG=n
+CONFIG_RTE_LIBRTE_SFC_EFX_TSO=n
#
# Compile null PMD
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 07c58d5..3a15baa 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -11,6 +11,7 @@ Queue start/stop = Y
MTU update = Y
Jumbo frame = Y
Scattered Rx = Y
+TSO = Y
Promiscuous mode = Y
Allmulticast mode = Y
Multicast MAC filter = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index bc45b17..6be4fba 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -63,6 +63,8 @@ SFC EFX PMD has support for:
- Allmulticast mode
+- TCP segmentation offload (TSO)
+
- Multicast MAC filter
- IPv4/IPv6 TCP/UDP receive checksum offload
@@ -169,6 +171,12 @@ Please note that enabling debugging options may affect system performance.
Enable compilation of the extra run-time consistency checks.
+- ``CONFIG_RTE_LIBRTE_SFC_EFX_TSO`` (default **n**)
+
+ Toggle TCP segmentation offload support.
+ Enabling the feature limits the number of available transmit queues
+ significantly due to the limited number of adapter TSO contexts.
+
Per-Device Parameters
~~~~~~~~~~~~~~~~~~~~~
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index dd099b2..14d6536 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -90,6 +90,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_port.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_rx.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_TSO) += sfc_tso.c
+
VPATH += $(SRCDIR)/base
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_bootcfg.c
@@ -139,4 +141,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_ether
DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_mempool
DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_TSO) += lib/librte_net
+
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index e79367d..02a56f7 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -621,6 +621,14 @@ sfc_attach(struct sfc_adapter *sa)
if (rc != 0)
goto fail_set_rss_defaults;
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+ sa->tso = efx_nic_cfg_get(sa->nic)->enc_fw_assisted_tso_v2_enabled;
+ if (!sa->tso)
+ sfc_warn(sa, "TSO support isn't available on this adapter");
+#else /* !RTE_LIBRTE_SFC_EFX_TSO */
+ sa->tso = B_FALSE;
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
+
sfc_log_init(sa, "fini nic");
efx_nic_fini(enp);
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index d02d1c0..6716acd 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -195,6 +195,8 @@ struct sfc_adapter {
unsigned int txq_count;
struct sfc_txq_info *txq_info;
+ boolean_t tso;
+
unsigned int rss_channels;
#if EFSYS_OPT_RX_SCALE
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index f45072c..dd5ca5c 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -93,6 +93,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
}
#endif
+ if (sa->tso)
+ dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
+
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
/* The RXQ hardware requires that the descriptor count is a power
diff --git a/drivers/net/sfc/sfc_tso.c b/drivers/net/sfc/sfc_tso.c
new file mode 100644
index 0000000..68d84c9
--- /dev/null
+++ b/drivers/net/sfc/sfc_tso.c
@@ -0,0 +1,200 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * 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.
+ */
+
+#include <rte_ip.h>
+#include <rte_tcp.h>
+
+#include "sfc.h"
+#include "sfc_debug.h"
+#include "sfc_tx.h"
+#include "sfc_ev.h"
+
+/** Standard TSO header length */
+#define SFC_TSOH_STD_LEN 256
+
+/** The number of TSO option descriptors that precede the packet descriptors */
+#define SFC_TSO_OPDESCS_IDX_SHIFT 2
+
+int
+sfc_tso_alloc_tsoh_objs(struct sfc_tx_sw_desc *sw_ring,
+ unsigned int txq_entries, unsigned int socket_id)
+{
+ unsigned int i;
+
+ for (i = 0; i < txq_entries; ++i) {
+ sw_ring[i].tsoh = rte_malloc_socket("sfc-txq-tsoh-obj",
+ SFC_TSOH_STD_LEN,
+ SFC_TX_SEG_BOUNDARY,
+ socket_id);
+ if (sw_ring[i].tsoh == NULL)
+ goto fail_alloc_tsoh_objs;
+ }
+
+ return 0;
+
+fail_alloc_tsoh_objs:
+ while (i > 0)
+ rte_free(sw_ring[--i].tsoh);
+
+ return ENOMEM;
+}
+
+void
+sfc_tso_free_tsoh_objs(struct sfc_tx_sw_desc *sw_ring, unsigned int txq_entries)
+{
+ unsigned int i;
+
+ for (i = 0; i < txq_entries; ++i) {
+ rte_free(sw_ring[i].tsoh);
+ sw_ring[i].tsoh = NULL;
+ }
+}
+
+static void
+sfc_tso_prepare_header(struct sfc_txq *txq, struct rte_mbuf **in_seg,
+ size_t *in_off, unsigned int idx, size_t bytes_left)
+{
+ struct rte_mbuf *m = *in_seg;
+ size_t bytes_to_copy = 0;
+ uint8_t *tsoh = txq->sw_ring[idx & txq->ptr_mask].tsoh;
+
+ do {
+ bytes_to_copy = MIN(bytes_left, m->data_len);
+
+ rte_memcpy(tsoh, rte_pktmbuf_mtod(m, uint8_t *),
+ bytes_to_copy);
+
+ bytes_left -= bytes_to_copy;
+ tsoh += bytes_to_copy;
+
+ if (bytes_left > 0) {
+ m = m->next;
+ SFC_ASSERT(m != NULL);
+ }
+ } while (bytes_left > 0);
+
+ if (bytes_to_copy == m->data_len) {
+ *in_seg = m->next;
+ *in_off = 0;
+ } else {
+ *in_seg = m;
+ *in_off = bytes_to_copy;
+ }
+}
+
+int
+sfc_tso_do(struct sfc_txq *txq, unsigned int idx, struct rte_mbuf **in_seg,
+ size_t *in_off, efx_desc_t **pend, unsigned int *pkt_descs,
+ size_t *pkt_len)
+{
+ uint8_t *tsoh;
+ const struct tcp_hdr *th;
+ efsys_dma_addr_t header_paddr;
+ efsys_dma_addr_t paddr_next_frag;
+ uint16_t packet_id;
+ uint32_t sent_seq;
+ struct rte_mbuf *m = *in_seg;
+ size_t nh_off = m->l2_len; /* IP header offset */
+ size_t tcph_off = m->l2_len + m->l3_len; /* TCP header offset */
+ size_t header_len = m->l2_len + m->l3_len + m->l4_len;
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(txq->evq->sa->nic);
+
+ idx += SFC_TSO_OPDESCS_IDX_SHIFT;
+
+ /* Packets which have too big headers should be discarded */
+ if (unlikely(header_len > SFC_TSOH_STD_LEN))
+ return EMSGSIZE;
+
+ /*
+ * The TCP header must start at most 208 bytes into the frame.
+ * If it starts later than this then the NIC won't realise
+ * it's a TCP packet and TSO edits won't be applied
+ */
+ if (unlikely(tcph_off > encp->enc_tx_tso_tcp_header_offset_limit))
+ return EMSGSIZE;
+
+ header_paddr = rte_pktmbuf_mtophys(m);
+ paddr_next_frag = P2ROUNDUP(header_paddr + 1, SFC_TX_SEG_BOUNDARY);
+
+ /*
+ * Sometimes headers may be split across multiple mbufs. In such cases
+ * we need to glue those pieces and store them in some temporary place.
+ * Also, packet headers must be contiguous in memory, so that
+ * they can be referred to with a single DMA descriptor. Hence, handle
+ * the case where the original header crosses a 4K memory boundary
+ */
+ if ((m->data_len < header_len) ||
+ ((paddr_next_frag - header_paddr) < header_len)) {
+ sfc_tso_prepare_header(txq, in_seg, in_off, idx, header_len);
+ tsoh = txq->sw_ring[idx & txq->ptr_mask].tsoh;
+
+ header_paddr = rte_malloc_virt2phy((void *)tsoh);
+ } else {
+ if (m->data_len == header_len) {
+ *in_off = 0;
+ *in_seg = m->next;
+ } else {
+ *in_off = header_len;
+ }
+
+ tsoh = rte_pktmbuf_mtod(m, uint8_t *);
+ }
+
+ /* Handle IP header */
+ if (m->ol_flags & PKT_TX_IPV4) {
+ const struct ipv4_hdr *iphe4;
+
+ iphe4 = (const struct ipv4_hdr *)(tsoh + nh_off);
+ rte_memcpy(&packet_id, &iphe4->packet_id, sizeof(uint16_t));
+ packet_id = rte_be_to_cpu_16(packet_id);
+ } else if (m->ol_flags & PKT_TX_IPV6) {
+ packet_id = 0;
+ } else {
+ return EINVAL;
+ }
+
+ /* Handle TCP header */
+ th = (const struct tcp_hdr *)(tsoh + tcph_off);
+
+ rte_memcpy(&sent_seq, &th->sent_seq, sizeof(uint32_t));
+ sent_seq = rte_be_to_cpu_32(sent_seq);
+
+ efx_tx_qdesc_tso2_create(txq->common, packet_id, sent_seq, m->tso_segsz,
+ *pend, EFX_TX_FATSOV2_OPT_NDESCS);
+
+ *pend += EFX_TX_FATSOV2_OPT_NDESCS;
+ *pkt_descs += EFX_TX_FATSOV2_OPT_NDESCS;
+
+ efx_tx_qdesc_dma_create(txq->common, header_paddr, header_len,
+ B_FALSE, (*pend)++);
+ (*pkt_descs)++;
+ *pkt_len -= header_len;
+
+ return 0;
+}
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 86bcfec..3e64c0f 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -184,6 +184,13 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
if (txq->sw_ring == NULL)
goto fail_desc_alloc;
+ if (sa->tso) {
+ rc = sfc_tso_alloc_tsoh_objs(txq->sw_ring, txq_info->entries,
+ socket_id);
+ if (rc != 0)
+ goto fail_alloc_tsoh_objs;
+ }
+
txq->state = SFC_TXQ_INITIALIZED;
txq->ptr_mask = txq_info->entries - 1;
txq->free_thresh = (tx_conf->tx_free_thresh) ? tx_conf->tx_free_thresh :
@@ -199,6 +206,9 @@ sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
return 0;
+fail_alloc_tsoh_objs:
+ rte_free(txq->sw_ring);
+
fail_desc_alloc:
rte_free(txq->pend_desc);
@@ -234,6 +244,8 @@ sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
SFC_ASSERT(txq != NULL);
SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
+ sfc_tso_free_tsoh_objs(txq->sw_ring, txq_info->entries);
+
txq_info->txq = NULL;
txq_info->entries = 0;
@@ -300,6 +312,11 @@ sfc_tx_init(struct sfc_adapter *sa)
sa->txq_count = sa->eth_dev->data->nb_tx_queues;
+ if (sa->tso)
+ sa->txq_count = MIN(sa->txq_count,
+ efx_nic_cfg_get(sa->nic)->enc_fw_assisted_tso_v2_n_contexts /
+ efx_nic_cfg_get(sa->nic)->enc_hw_pf_count);
+
sa->txq_info = rte_calloc_socket("sfc-txqs", sa->txq_count,
sizeof(sa->txq_info[0]), 0,
sa->socket_id);
@@ -373,17 +390,25 @@ sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
* hence, we always enable it here
*/
if ((txq->flags & ETH_TXQ_FLAGS_NOXSUMTCP) ||
- (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP))
+ (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP)) {
flags = EFX_TXQ_CKSUM_IPV4;
- else
+ } else {
flags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;
+ if (sa->tso)
+ flags |= EFX_TXQ_FATSOV2;
+ }
+
rc = efx_tx_qcreate(sa->nic, sw_index, 0, &txq->mem,
txq_info->entries, 0 /* not used on EF10 */,
flags, evq->common,
&txq->common, &desc_index);
- if (rc != 0)
+ if (rc != 0) {
+ if (sa->tso && (rc == ENOSPC))
+ sfc_err(sa, "ran out of TSO contexts");
+
goto fail_tx_qcreate;
+ }
txq->added = txq->pending = txq->completed = desc_index;
txq->hw_vlan_tci = 0;
@@ -494,6 +519,13 @@ sfc_tx_start(struct sfc_adapter *sa)
sfc_log_init(sa, "txq_count = %u", sa->txq_count);
+ if (sa->tso) {
+ if (!efx_nic_cfg_get(sa->nic)->enc_fw_assisted_tso_v2_enabled) {
+ sfc_warn(sa, "TSO support was unable to be restored");
+ sa->tso = B_FALSE;
+ }
+ }
+
rc = efx_tx_init(sa->nic);
if (rc != 0)
goto fail_efx_tx_init;
@@ -607,6 +639,7 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
struct rte_mbuf *m_seg = *pktp;
size_t pkt_len = m_seg->pkt_len;
unsigned int pkt_descs = 0;
+ size_t in_off = 0;
/*
* Here VLAN TCI is expected to be zero in case if no
@@ -617,6 +650,46 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
*/
pkt_descs += sfc_tx_maybe_insert_tag(txq, m_seg, &pend);
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+ if (m_seg->ol_flags & PKT_TX_TCP_SEG) {
+ /*
+ * We expect correct 'pkt->l[2, 3, 4]_len' values
+ * to be set correctly by the caller
+ */
+ if (sfc_tso_do(txq, added, &m_seg, &in_off, &pend,
+ &pkt_descs, &pkt_len) != 0) {
+ /* We may have reached this place for
+ * one of the following reasons:
+ *
+ * 1) Packet header length is greater
+ * than SFC_TSOH_STD_LEN
+ * 2) TCP header starts at more then
+ * 208 bytes into the frame
+ *
+ * We will deceive RTE saying that we have sent
+ * the packet, but we will actually drop it.
+ * Hence, we should revert 'pend' to the
+ * previous state (in case we have added
+ * VLAN descriptor) and start processing
+ * another one packet. But the original
+ * mbuf shouldn't be orphaned
+ */
+ pend -= pkt_descs;
+
+ rte_pktmbuf_free(*pktp);
+
+ continue;
+ }
+
+ /*
+ * We've only added 2 FATSOv2 option descriptors
+ * and 1 descriptor for the linearized packet header.
+ * The outstanding work will be done in the same manner
+ * as for the usual non-TSO path
+ */
+ }
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
+
for (; m_seg != NULL; m_seg = m_seg->next) {
efsys_dma_addr_t next_frag;
size_t seg_len;
@@ -624,6 +697,16 @@ sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
seg_len = m_seg->data_len;
next_frag = rte_mbuf_data_dma_addr(m_seg);
+ /*
+ * If we've started TSO transaction few steps earlier,
+ * we'll skip packet header using an offset in the
+ * current segment (which has been set to the
+ * first one containing payload)
+ */
+ seg_len -= in_off;
+ next_frag += in_off;
+ in_off = 0;
+
do {
efsys_dma_addr_t frag_addr = next_frag;
size_t frag_len;
diff --git a/drivers/net/sfc/sfc_tx.h b/drivers/net/sfc/sfc_tx.h
index 4d25c6a..581e2aa 100644
--- a/drivers/net/sfc/sfc_tx.h
+++ b/drivers/net/sfc/sfc_tx.h
@@ -50,6 +50,9 @@ struct sfc_evq;
struct sfc_tx_sw_desc {
struct rte_mbuf *mbuf;
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+ uint8_t *tsoh; /* Buffer to store TSO header */
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
};
enum sfc_txq_state_bit {
@@ -113,6 +116,31 @@ void sfc_tx_stop(struct sfc_adapter *sa);
uint16_t sfc_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts);
+#ifdef RTE_LIBRTE_SFC_EFX_TSO
+/* From 'sfc_tso.c' */
+int sfc_tso_alloc_tsoh_objs(struct sfc_tx_sw_desc *sw_ring,
+ unsigned int txq_entries, unsigned int socket_id);
+void sfc_tso_free_tsoh_objs(struct sfc_tx_sw_desc *sw_ring,
+ unsigned int txq_entries);
+int sfc_tso_do(struct sfc_txq *txq, unsigned int idx, struct rte_mbuf **in_seg,
+ size_t *in_off, efx_desc_t **pend, unsigned int *pkt_descs,
+ size_t *pkt_len);
+#else /* !RTE_LIBRTE_SFC_EFX_TSO */
+static inline int
+sfc_tso_alloc_tsoh_objs(__rte_unused struct sfc_tx_sw_desc *sw_ring,
+ __rte_unused unsigned int txq_entries,
+ __rte_unused unsigned int socket_id)
+{
+ return 0;
+}
+
+static inline void
+sfc_tso_free_tsoh_objs(__rte_unused struct sfc_tx_sw_desc *sw_ring,
+ __rte_unused unsigned int txq_entries)
+{
+}
+#endif /* RTE_LIBRTE_SFC_EFX_TSO */
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [dpdk-dev] [PATCH v2 00/32] Support more features in Solarflare PMD
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
` (31 preceding siblings ...)
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 32/32] net/sfc: support firmware-assisted TSOv2 Andrew Rybchenko
@ 2016-12-16 9:57 ` Ferruh Yigit
32 siblings, 0 replies; 70+ messages in thread
From: Ferruh Yigit @ 2016-12-16 9:57 UTC (permalink / raw)
To: Andrew Rybchenko, dev
On 12/15/2016 12:50 PM, Andrew Rybchenko wrote:
> The patch series adds a number of features to Solarflare libefx-based
> PMD. Basically one patch per feature.
>
> The patches are grouped into one series since they touch nearby lines
> in either PMD feature list, or dev_ops structure, or documentation.
> So, patches cannot be applied in arbitrary order.
>
> ---
>
> v2:
> * Fix ICC and clang warnings
> * Slightly change sfc_tso_{alloc,free}_tsoh_objs() prototypes
>
>
> Andrew Rybchenko (17):
> net/sfc: implement MCDI logging callback
> net/sfc: support parameter to choose performance profile
> net/sfc: implement ethdev hook to get basic statistics
> net/sfc: support extended statistics
> net/sfc: support flow control settings get/set
> net/sfc: support link status change interrupt
> net/sfc: implement device operation to change MTU
> net/sfc: support link speed and duplex settings
> net/sfc: support checksum offloads on receive
> net/sfc: handle received packet type info provided by HW
> net/sfc: support callback to get receive queue information
> net/sfc: support Rx free threshold
> net/sfc: add callback to get RxQ pending descriptors count
> net/sfc: add RxQ descriptor done callback
> net/sfc: support scattered Rx DMA
> net/sfc: support deferred start of receive queues
> net/sfc/base: do not use enum type when values are bitmask
>
> Artem Andreev (1):
> net/sfc: support link up/down
>
> Ivan Malov (14):
> net/sfc: support promiscuous and all-multicast control
> net/sfc: support main (the first) MAC address change
> net/sfc: support multicast addresses list controls
> net/sfc: add callback to get transmit queue information
> net/sfc: support Tx free threshold
> net/sfc: support deferred start of transmit queues
> net/sfc: support VLAN offload on transmit path
> net/sfc: add basic stubs for RSS support on driver attach
> net/sfc: support RSS hash offload
> net/sfc: add callback to query RSS key and hash types config
> net/sfc: add callback to set RSS key and hash types config
> net/sfc: add callback to query RSS redirection table
> net/sfc: add callback to update RSS redirection table
> net/sfc: support firmware-assisted TSOv2
>
<...>
Series applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask Andrew Rybchenko
@ 2017-01-18 11:30 ` Ferruh Yigit
2017-01-18 11:52 ` Andrew Rybchenko
0 siblings, 1 reply; 70+ messages in thread
From: Ferruh Yigit @ 2017-01-18 11:30 UTC (permalink / raw)
To: Andrew Rybchenko, dev; +Cc: Andrew Rybchenko
On 12/15/2016 12:51 PM, Andrew Rybchenko wrote:
> From: Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
Hi Andrew,
For this patch "Signed-off" and "From" mail addresses are different.
Since both are same person and you, is there any problem using "Andrew
Rybchenko <arybchenko@solarflare.com>" as author of the patch?
Thanks,
ferruh
>
> ICC complains that enumerated type mixed with another type.
>
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Reviewed-by: Andrew Lee <alee@solarflare.com>
> Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
> ---
<...>
^ permalink raw reply [flat|nested] 70+ messages in thread
* Re: [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask
2017-01-18 11:30 ` Ferruh Yigit
@ 2017-01-18 11:52 ` Andrew Rybchenko
0 siblings, 0 replies; 70+ messages in thread
From: Andrew Rybchenko @ 2017-01-18 11:52 UTC (permalink / raw)
To: Ferruh Yigit, dev; +Cc: Andrew Rybchenko
On 01/18/2017 02:30 PM, Ferruh Yigit wrote:
> On 12/15/2016 12:51 PM, Andrew Rybchenko wrote:
>> From: Andrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
> Hi Andrew,
>
> For this patch "Signed-off" and "From" mail addresses are different.
> Since both are same person and you, is there any problem using "Andrew
> Rybchenko <arybchenko@solarflare.com>" as author of the patch?
Yes, please, use "Andrew Rybchenko <arybchenko@solarflare.com>"
It was my mistake in configs.
Thanks,
Andrew.
> Thanks,
> ferruh
>
>> ICC complains that enumerated type mixed with another type.
>>
>> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
>> Reviewed-by: Andrew Lee <alee@solarflare.com>
>> Reviewed-by: Robert Stonehouse <rstonehouse@solarflare.com>
>> ---
> <...>
^ permalink raw reply [flat|nested] 70+ messages in thread
end of thread, other threads:[~2017-01-18 11:52 UTC | newest]
Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-02 7:44 [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 01/31] net/sfc: implement MCDI logging callback Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 02/31] net/sfc: support parameter to choose performance profile Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 03/31] net/sfc: implement ethdev hook to get basic statistics Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 04/31] net/sfc: support extended statistics Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 05/31] net/sfc: support flow control settings get/set Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 06/31] net/sfc: support link status change interrupt Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 07/31] net/sfc: implement device operation to change MTU Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 08/31] net/sfc: support link speed and duplex settings Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 09/31] net/sfc: support link up/down Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 10/31] net/sfc: support promiscuous and all-multicast control Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 11/31] net/sfc: support main (the first) MAC address change Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 12/31] net/sfc: support multicast addresses list controls Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 13/31] net/sfc: support checksum offloads on receive Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 14/31] net/sfc: handle received packet type info provided by HW Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 15/31] net/sfc: support callback to get receive queue information Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 16/31] net/sfc: support Rx free threshold Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 17/31] net/sfc: add callback to get RxQ pending descriptors count Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 18/31] net/sfc: add RxQ descriptor done callback Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 19/31] net/sfc: support scattered Rx DMA Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 20/31] net/sfc: support deferred start of receive queues Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 21/31] net/sfc: add callback to get transmit queue information Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 22/31] net/sfc: support Tx free threshold Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 23/31] net/sfc: support deferred start of transmit queues Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 24/31] net/sfc: support VLAN offload on transmit path Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 25/31] net/sfc: add basic stubs for RSS support on driver attach Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 26/31] net/sfc: support RSS hash offload Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 27/31] net/sfc: add callback to query RSS key and hash types config Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 28/31] net/sfc: add callback to set " Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 29/31] net/sfc: add callback to query RSS redirection table Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 30/31] net/sfc: add callback to update " Andrew Rybchenko
2016-12-02 7:44 ` [dpdk-dev] [PATCH 31/31] net/sfc: support firmware-assisted TSOv2 Andrew Rybchenko
2016-12-09 17:34 ` [dpdk-dev] [PATCH 00/31] Support more features in Solarflare PMD Ferruh Yigit
2016-12-15 12:50 ` Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 00/32] " Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 01/32] net/sfc: implement MCDI logging callback Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 02/32] net/sfc: support parameter to choose performance profile Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 03/32] net/sfc: implement ethdev hook to get basic statistics Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 04/32] net/sfc: support extended statistics Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 05/32] net/sfc: support flow control settings get/set Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 06/32] net/sfc: support link status change interrupt Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 07/32] net/sfc: implement device operation to change MTU Andrew Rybchenko
2016-12-15 12:50 ` [dpdk-dev] [PATCH v2 08/32] net/sfc: support link speed and duplex settings Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 09/32] net/sfc: support link up/down Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 10/32] net/sfc: support promiscuous and all-multicast control Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 11/32] net/sfc: support main (the first) MAC address change Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 12/32] net/sfc: support multicast addresses list controls Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 13/32] net/sfc: support checksum offloads on receive Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 14/32] net/sfc: handle received packet type info provided by HW Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 15/32] net/sfc: support callback to get receive queue information Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 16/32] net/sfc: support Rx free threshold Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 17/32] net/sfc: add callback to get RxQ pending descriptors count Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 18/32] net/sfc: add RxQ descriptor done callback Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 19/32] net/sfc: support scattered Rx DMA Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 20/32] net/sfc: support deferred start of receive queues Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 21/32] net/sfc: add callback to get transmit queue information Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 22/32] net/sfc: support Tx free threshold Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 23/32] net/sfc: support deferred start of transmit queues Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 24/32] net/sfc: support VLAN offload on transmit path Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 25/32] net/sfc/base: do not use enum type when values are bitmask Andrew Rybchenko
2017-01-18 11:30 ` Ferruh Yigit
2017-01-18 11:52 ` Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 26/32] net/sfc: add basic stubs for RSS support on driver attach Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 27/32] net/sfc: support RSS hash offload Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 28/32] net/sfc: add callback to query RSS key and hash types config Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 29/32] net/sfc: add callback to set " Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 30/32] net/sfc: add callback to query RSS redirection table Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 31/32] net/sfc: add callback to update " Andrew Rybchenko
2016-12-15 12:51 ` [dpdk-dev] [PATCH v2 32/32] net/sfc: support firmware-assisted TSOv2 Andrew Rybchenko
2016-12-16 9:57 ` [dpdk-dev] [PATCH v2 00/32] Support more features in Solarflare PMD 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).