diff options
author | arybchik <arybchik@FreeBSD.org> | 2016-01-14 15:07:02 +0000 |
---|---|---|
committer | arybchik <arybchik@FreeBSD.org> | 2016-01-14 15:07:02 +0000 |
commit | 9f1d56691ca1f1a273fe41709ac162ebbb31dcb4 (patch) | |
tree | d356c8c7605e2e309fe95c7a47718d55f08ffd3d | |
parent | 73ae6a20799dd833416f8e7b89ed784d0251f3b3 (diff) | |
download | FreeBSD-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.4 | 8 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge.c | 16 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge.h | 3 | ||||
-rw-r--r-- | sys/dev/sfxge/sfxge_mcdi.c | 70 |
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; |