* [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
* 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
* [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
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).