sfxge: support for MCDI logging implemented
Submitted by: Artem V. Andreev <Artem.Andreev at oktetlabs.ru> Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D4355
This commit is contained in:
parent
d5903f4e62
commit
0b3051dae1
@ -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,
|
||||
|
@ -95,6 +95,12 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN,
|
||||
&sfxge_tx_ring_entries, 0,
|
||||
"Maximum number of descriptors in a transmit ring");
|
||||
|
||||
#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);
|
||||
|
||||
@ -620,6 +626,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;
|
||||
|
||||
@ -630,6 +639,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),
|
||||
|
@ -281,6 +281,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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user