summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2016-01-14 15:07:02 +0000
committerarybchik <arybchik@FreeBSD.org>2016-01-14 15:07:02 +0000
commit9f1d56691ca1f1a273fe41709ac162ebbb31dcb4 (patch)
treed356c8c7605e2e309fe95c7a47718d55f08ffd3d
parent73ae6a20799dd833416f8e7b89ed784d0251f3b3 (diff)
downloadFreeBSD-src-9f1d56691ca1f1a273fe41709ac162ebbb31dcb4.zip
FreeBSD-src-9f1d56691ca1f1a273fe41709ac162ebbb31dcb4.tar.gz
MFC r291843
sfxge: support for MCDI logging implemented Submitted by: Artem V. Andreev <Artem.Andreev at oktetlabs.ru> Sponsored by: Solarflare Communications, Inc.
-rw-r--r--share/man/man4/sfxge.48
-rw-r--r--sys/dev/sfxge/sfxge.c16
-rw-r--r--sys/dev/sfxge/sfxge.h3
-rw-r--r--sys/dev/sfxge/sfxge_mcdi.c70
4 files changed, 97 insertions, 0 deletions
diff --git a/share/man/man4/sfxge.4 b/share/man/man4/sfxge.4
index c6319fc..b924986 100644
--- a/share/man/man4/sfxge.4
+++ b/share/man/man4/sfxge.4
@@ -148,6 +148,14 @@ Number of packets with payload that must arrive in-order following loss
before a connection is eligible for LRO.
The idea is we should avoid coalescing segments when the sender is recovering
from loss, because reducing the ACK rate can damage performance.
+.It Va hw.sfxge.mcdi_logging
+Enable logging of MCDI protocol messages (only available if enabled at compile-time).
+.It Va hw.sfxge.N.mcdi_logging
+Enable or disable logging of MCDI protocol messages on a per-port basis. The default for each
+port will be the value of
+.Va hw.sfxge.mcdi_logging.
+The logging may also be enabled or disabled after the driver is loaded using the sysctl
+.Va dev.sfxge.%d.mcdi_logging.
.El
.Sh SUPPORT
For general information and support,
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index cb34882..718f724 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -102,6 +102,12 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period, CTLFLAG_RDTUN,
&sfxge_stats_update_period, 0,
"netstat interface statistics update period in ticks");
+#if EFSYS_OPT_MCDI_LOGGING
+#define SFXGE_PARAM_MCDI_LOGGING SFXGE_PARAM(mcdi_logging)
+static int sfxge_mcdi_logging = 0;
+TUNABLE_INT(SFXGE_PARAM_MCDI_LOGGING, &sfxge_mcdi_logging);
+#endif
+
static void
sfxge_reset(void *arg, int npending);
@@ -644,6 +650,9 @@ sfxge_create(struct sfxge_softc *sc)
efx_nic_t *enp;
int error;
char rss_param_name[sizeof(SFXGE_PARAM(%d.max_rss_channels))];
+#if EFSYS_OPT_MCDI_LOGGING
+ char mcdi_log_param_name[sizeof(SFXGE_PARAM(%d.mcdi_logging))];
+#endif
dev = sc->dev;
@@ -654,6 +663,13 @@ sfxge_create(struct sfxge_softc *sc)
SFXGE_PARAM(%d.max_rss_channels),
(int)device_get_unit(dev));
TUNABLE_INT_FETCH(rss_param_name, &sc->max_rss_channels);
+#if EFSYS_OPT_MCDI_LOGGING
+ sc->mcdi_logging = sfxge_mcdi_logging;
+ snprintf(mcdi_log_param_name, sizeof(mcdi_log_param_name),
+ SFXGE_PARAM(%d.mcdi_logging),
+ (int)device_get_unit(dev));
+ TUNABLE_INT_FETCH(mcdi_log_param_name, &sc->mcdi_logging);
+#endif
sc->stats_node = SYSCTL_ADD_NODE(
device_get_sysctl_ctx(dev),
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index cfaf06d..bea1eba 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -284,6 +284,9 @@ struct sfxge_softc {
unsigned int txq_count;
int tso_fw_assisted;
+#if EFSYS_OPT_MCDI_LOGGING
+ int mcdi_logging;
+#endif
};
#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN)
diff --git a/sys/dev/sfxge/sfxge_mcdi.c b/sys/dev/sfxge/sfxge_mcdi.c
index fb9f650..3a85c28 100644
--- a/sys/dev/sfxge/sfxge_mcdi.c
+++ b/sys/dev/sfxge/sfxge_mcdi.c
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#include "sfxge.h"
+#if EFSYS_OPT_MCDI_LOGGING
+#include <dev/pci/pcivar.h>
+#endif
+
#define SFXGE_MCDI_POLL_INTERVAL_MIN 10 /* 10us in 1us units */
#define SFXGE_MCDI_POLL_INTERVAL_MAX 100000 /* 100ms in 1us units */
#define SFXGE_MCDI_WATCHDOG_INTERVAL 10000000 /* 10s in 1us units */
@@ -163,6 +167,64 @@ sfxge_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
sfxge_schedule_reset(sc);
}
+#if EFSYS_OPT_MCDI_LOGGING
+
+#define SFXGE_MCDI_LOG_BUF_SIZE 128
+
+static size_t
+sfxge_mcdi_do_log(char *buffer, void *data, size_t data_size,
+ size_t pfxsize, size_t position)
+{
+ uint32_t *words = data;
+ size_t i;
+
+ for (i = 0; i < data_size; i += sizeof(*words)) {
+ if (position + 2 * sizeof(*words) + 1 >= SFXGE_MCDI_LOG_BUF_SIZE) {
+ buffer[position] = '\0';
+ printf("%s \\\n", buffer);
+ position = pfxsize;
+ }
+ snprintf(buffer + position, SFXGE_MCDI_LOG_BUF_SIZE - position,
+ " %08x", *words);
+ words++;
+ position += 2 * sizeof(uint32_t) + 1;
+ }
+ return (position);
+}
+
+static void
+sfxge_mcdi_logger(void *arg, efx_log_msg_t type,
+ void *header, size_t header_size,
+ void *data, size_t data_size)
+{
+ struct sfxge_softc *sc = (struct sfxge_softc *)arg;
+ char buffer[SFXGE_MCDI_LOG_BUF_SIZE];
+ size_t pfxsize;
+ size_t start;
+
+ if (!sc->mcdi_logging)
+ return;
+
+ pfxsize = snprintf(buffer, sizeof(buffer),
+ "sfc %04x:%02x:%02x.%02x %s MCDI RPC %s:",
+ pci_get_domain(sc->dev),
+ pci_get_bus(sc->dev),
+ pci_get_slot(sc->dev),
+ pci_get_function(sc->dev),
+ device_get_nameunit(sc->dev),
+ type == EFX_LOG_MCDI_REQUEST ? "REQ" :
+ type == EFX_LOG_MCDI_RESPONSE ? "RESP" : "???");
+ start = sfxge_mcdi_do_log(buffer, header, header_size,
+ pfxsize, pfxsize);
+ start = sfxge_mcdi_do_log(buffer, data, data_size, pfxsize, start);
+ if (start != pfxsize) {
+ buffer[start] = '\0';
+ printf("%s\n", buffer);
+ }
+}
+
+#endif
+
int
sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip)
{
@@ -269,6 +331,14 @@ sfxge_mcdi_init(struct sfxge_softc *sc)
emtp->emt_execute = sfxge_mcdi_execute;
emtp->emt_ev_cpl = sfxge_mcdi_ev_cpl;
emtp->emt_exception = sfxge_mcdi_exception;
+#if EFSYS_OPT_MCDI_LOGGING
+ emtp->emt_logger = sfxge_mcdi_logger;
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
+ OID_AUTO, "mcdi_logging", CTLFLAG_RW,
+ &sc->mcdi_logging, 0,
+ "MCDI logging");
+#endif
if ((rc = efx_mcdi_init(enp, emtp)) != 0)
goto fail;
OpenPOWER on IntegriCloud