]> git.droids-corp.org - dpdk.git/commitdiff
net/sfc: implement MCDI logging callback
authorAndrew Rybchenko <arybchenko@solarflare.com>
Thu, 15 Dec 2016 12:50:52 +0000 (12:50 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:40:50 +0000 (19:40 +0100)
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
drivers/net/sfc/efsys.h
drivers/net/sfc/sfc.h
drivers/net/sfc/sfc_ethdev.c
drivers/net/sfc/sfc_kvargs.c
drivers/net/sfc/sfc_kvargs.h
drivers/net/sfc/sfc_mcdi.c

index aadd775931dbdfbd155bb40cf751cdbd6da0fa97..2cca287760f6aa807edf4ca82e15f45af24603d4 100644 (file)
@@ -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.
index e4d503561ee4b944eefaca333f4a80387c8d85fb..d48eb4c5e76ff188c86c76e1e30894aff7437eea 100644 (file)
@@ -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
index c6bb5e8c4278d79e11f6a680d8fcb8799e21d87b..568a40e952136cefee503d3b6d227d46b0f5e6df 100644 (file)
@@ -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 {
index 68717a6529e7e2abe404b954106b9073d85f7728..bb79c9cc921bc374bc7705dd61aa504747141079 100644 (file)
@@ -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);
index fe8a1fe2e6ebd869f598fb3afe72464d0f19412c..5496b12e48c18c5b31edc453c38ab8ffd6ef7e7f 100644 (file)
@@ -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,
        };
 
index 0b53963f635fb141a3acc1c59375ad237eaec9ce..ffce851dd31708a728a0d1074d2b0fdc156166ec 100644 (file)
@@ -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);
index 9ba28e181cd2e186cfaee0dc066f93bbd0272391..3bed2e0b13241b7712924c8a24394c08cfcb6d78 100644 (file)
@@ -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: