From 3e3b2e4ceaed54071a0113812a54e28ca0634ee3 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Thu, 15 Dec 2016 12:50:52 +0000 Subject: [PATCH] net/sfc: implement MCDI logging callback Signed-off-by: Andrew Rybchenko Reviewed-by: Andrew Lee Reviewed-by: Robert Stonehouse --- 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 aadd775931..2cca287760 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 e4d503561e..d48eb4c5e7 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 c6bb5e8c42..568a40e952 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -110,6 +110,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 68717a6529..bb79c9cc92 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -463,4 +463,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 fe8a1fe2e6..5496b12e48 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) struct rte_devargs *devargs = eth_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 0b53963f63..ffce851dd3 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 9ba28e181c..3bed2e0b13 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.20.1