cxgbe(4): Improvements to the code that deals with the firmware's log.

- Query the location of the log very early during attach.  Refresh the
  location later after establishing contact with the firmware.
- Save the log's location as a flat address in devlog_params.
- Use a memory window instead of backdoor access to the EDC/MC to read
  the log.
This commit is contained in:
Navdeep Parhar 2016-03-10 23:17:26 +00:00
parent d83e07789d
commit 98790d33c6
2 changed files with 29 additions and 27 deletions

View File

@ -262,6 +262,7 @@ struct devlog_params {
u32 memtype; /* which memory (FW_MEMTYPE_* ) */
u32 start; /* start of log in firmware memory */
u32 size; /* size of log */
u32 addr; /* start address in flat addr space */
};
/* Stores chip specific parameters */

View File

@ -409,6 +409,7 @@ static int validate_mem_range(struct adapter *, uint32_t, int);
static int fwmtype_to_hwmtype(int);
static int validate_mt_off_len(struct adapter *, int, uint32_t, int,
uint32_t *);
static int fixup_devlog_params(struct adapter *);
static int cfg_itype_and_nqueues(struct adapter *, int, int, int,
struct intrs_and_queues *);
static int prep_firmware(struct adapter *);
@ -733,6 +734,8 @@ t4_attach(device_t dev)
* will work even in "recovery mode".
*/
setup_memwin(sc);
if (t4_init_devlog_params(sc, 0) == 0)
fixup_devlog_params(sc);
sc->cdev = make_dev(is_t4(sc) ? &t4_cdevsw : &t5_cdevsw,
device_get_unit(dev), UID_ROOT, GID_WHEEL, 0600, "%s",
device_get_nameunit(dev));
@ -2332,6 +2335,18 @@ validate_mt_off_len(struct adapter *sc, int mtype, uint32_t off, int len,
return (validate_mem_range(sc, *addr, len));
}
static int
fixup_devlog_params(struct adapter *sc)
{
struct devlog_params *dparams = &sc->params.devlog;
int rc;
rc = validate_mt_off_len(sc, dparams->memtype, dparams->start,
dparams->size, &dparams->addr);
return (rc);
}
static int
cfg_itype_and_nqueues(struct adapter *sc, int n10g, int n1g, int num_vis,
struct intrs_and_queues *iaq)
@ -3052,8 +3067,6 @@ get_params__pre_init(struct adapter *sc)
{
int rc;
uint32_t param[2], val[2];
struct fw_devlog_cmd cmd;
struct devlog_params *dlog = &sc->params.devlog;
param[0] = FW_PARAM_DEV(PORTVEC);
param[1] = FW_PARAM_DEV(CCLK);
@ -3069,21 +3082,13 @@ get_params__pre_init(struct adapter *sc)
sc->params.vpd.cclk = val[1];
/* Read device log parameters. */
bzero(&cmd, sizeof(cmd));
cmd.op_to_write = htobe32(V_FW_CMD_OP(FW_DEVLOG_CMD) |
F_FW_CMD_REQUEST | F_FW_CMD_READ);
cmd.retval_len16 = htobe32(FW_LEN16(cmd));
rc = -t4_wr_mbox(sc, sc->mbox, &cmd, sizeof(cmd), &cmd);
if (rc != 0) {
rc = -t4_init_devlog_params(sc, 1);
if (rc == 0)
fixup_devlog_params(sc);
else {
device_printf(sc->dev,
"failed to get devlog parameters: %d.\n", rc);
bzero(dlog, sizeof (*dlog));
rc = 0; /* devlog isn't critical for device operation */
} else {
val[0] = be32toh(cmd.memtype_devlog_memaddr16_devlog);
dlog->memtype = G_FW_DEVLOG_CMD_MEMTYPE_DEVLOG(val[0]);
dlog->start = G_FW_DEVLOG_CMD_MEMADDR16_DEVLOG(val[0]) << 4;
dlog->size = be32toh(cmd.memsize_devlog);
}
return (rc);
@ -5875,7 +5880,7 @@ sysctl_ddp_stats(SYSCTL_HANDLER_ARGS)
return (rc);
}
const char *devlog_level_strings[] = {
static const char * const devlog_level_strings[] = {
[FW_DEVLOG_LEVEL_EMERG] = "EMERG",
[FW_DEVLOG_LEVEL_CRIT] = "CRIT",
[FW_DEVLOG_LEVEL_ERR] = "ERR",
@ -5884,7 +5889,7 @@ const char *devlog_level_strings[] = {
[FW_DEVLOG_LEVEL_DEBUG] = "DEBUG"
};
const char *devlog_facility_strings[] = {
static const char * const devlog_facility_strings[] = {
[FW_DEVLOG_FACILITY_CORE] = "CORE",
[FW_DEVLOG_FACILITY_CF] = "CF",
[FW_DEVLOG_FACILITY_SCHED] = "SCHED",
@ -5908,7 +5913,8 @@ const char *devlog_facility_strings[] = {
[FW_DEVLOG_FACILITY_ISCSI] = "ISCSI",
[FW_DEVLOG_FACILITY_FCOE] = "FCOE",
[FW_DEVLOG_FACILITY_FOISCSI] = "FOISCSI",
[FW_DEVLOG_FACILITY_FOFCOE] = "FOFCOE"
[FW_DEVLOG_FACILITY_FOFCOE] = "FOFCOE",
[FW_DEVLOG_FACILITY_CHNET] = "CHNET",
};
static int
@ -5917,27 +5923,22 @@ sysctl_devlog(SYSCTL_HANDLER_ARGS)
struct adapter *sc = arg1;
struct devlog_params *dparams = &sc->params.devlog;
struct fw_devlog_e *buf, *e;
int i, j, rc, nentries, first = 0, m;
int i, j, rc, nentries, first = 0;
struct sbuf *sb;
uint64_t ftstamp = UINT64_MAX;
if (dparams->start == 0) {
dparams->memtype = FW_MEMTYPE_EDC0;
dparams->start = 0x84000;
dparams->size = 32768;
}
nentries = dparams->size / sizeof(struct fw_devlog_e);
if (dparams->addr == 0)
return (ENXIO);
buf = malloc(dparams->size, M_CXGBE, M_NOWAIT);
if (buf == NULL)
return (ENOMEM);
m = fwmtype_to_hwmtype(dparams->memtype);
rc = -t4_mem_read(sc, m, dparams->start, dparams->size, (void *)buf);
rc = read_via_memwin(sc, 1, dparams->addr, (void *)buf, dparams->size);
if (rc != 0)
goto done;
nentries = dparams->size / sizeof(struct fw_devlog_e);
for (i = 0; i < nentries; i++) {
e = &buf[i];