sfxge: add MCDI logging support to common code
Submitted by: Andy Moreton <amoreton at solarflare.com> Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D4331
This commit is contained in:
parent
1f49e276c3
commit
3314a1ba8f
@ -245,6 +245,7 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
|
||||
#endif
|
||||
|
||||
#define EFSYS_OPT_MCDI 1
|
||||
#define EFSYS_OPT_MCDI_LOGGING 0
|
||||
|
||||
#define EFSYS_OPT_MAC_FALCON_GMAC 0
|
||||
#define EFSYS_OPT_MAC_FALCON_XMAC 0
|
||||
|
@ -201,12 +201,25 @@ typedef enum efx_mcdi_exception_e {
|
||||
EFX_MCDI_EXCEPTION_MC_BADASSERT,
|
||||
} efx_mcdi_exception_t;
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
typedef enum efx_log_msg_e
|
||||
{
|
||||
EFX_LOG_INVALID,
|
||||
EFX_LOG_MCDI_REQUEST,
|
||||
EFX_LOG_MCDI_RESPONSE,
|
||||
} efx_log_msg_t;
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
|
||||
typedef struct efx_mcdi_transport_s {
|
||||
void *emt_context;
|
||||
efsys_mem_t *emt_dma_mem;
|
||||
void (*emt_execute)(void *, efx_mcdi_req_t *);
|
||||
void (*emt_ev_cpl)(void *);
|
||||
void (*emt_exception)(void *, efx_mcdi_exception_t);
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
void (*emt_logger)(void *, efx_log_msg_t,
|
||||
void *, size_t, void *, size_t);
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
} efx_mcdi_transport_t;
|
||||
|
||||
extern __checkReturn efx_rc_t
|
||||
|
@ -146,6 +146,13 @@
|
||||
# error "HUNTINGTON requires MCDI"
|
||||
#endif
|
||||
|
||||
/* Support MCDI logging */
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
# if !EFSYS_OPT_MCDI
|
||||
# error "MCDI_LOGGING requires MCDI"
|
||||
# endif
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
|
||||
/* Support LM87 monitor */
|
||||
#if EFSYS_OPT_MON_LM87
|
||||
# if !EFSYS_OPT_FALCON
|
||||
|
@ -468,9 +468,8 @@ efx_mcdi_ev_cpl(
|
||||
} else {
|
||||
emrp->emr_out_length_used = outlen;
|
||||
emrp->emr_rc = 0;
|
||||
|
||||
emcop->emco_request_copyout(enp, emrp);
|
||||
}
|
||||
emcop->emco_request_copyout(enp, emrp);
|
||||
|
||||
emtp->emt_ev_cpl(emtp->emt_context);
|
||||
}
|
||||
|
@ -143,6 +143,7 @@ hunt_mcdi_request_copyin(
|
||||
efsys_mem_t *esmp = emtp->emt_dma_mem;
|
||||
efx_mcdi_header_type_t hdr_type;
|
||||
efx_dword_t dword;
|
||||
efx_dword_t hdr[2];
|
||||
unsigned int xflags;
|
||||
unsigned int pos;
|
||||
size_t offset;
|
||||
@ -160,7 +161,7 @@ hunt_mcdi_request_copyin(
|
||||
|
||||
if (hdr_type == EFX_MCDI_HEADER_TYPE_V2) {
|
||||
/* Construct MCDI v2 header */
|
||||
EFX_POPULATE_DWORD_8(dword,
|
||||
EFX_POPULATE_DWORD_8(hdr[0],
|
||||
MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
|
||||
MCDI_HEADER_RESYNC, 1,
|
||||
MCDI_HEADER_DATALEN, 0,
|
||||
@ -169,17 +170,17 @@ hunt_mcdi_request_copyin(
|
||||
MCDI_HEADER_ERROR, 0,
|
||||
MCDI_HEADER_RESPONSE, 0,
|
||||
MCDI_HEADER_XFLAGS, xflags);
|
||||
EFSYS_MEM_WRITED(esmp, offset, &dword);
|
||||
offset += sizeof (dword);
|
||||
EFSYS_MEM_WRITED(esmp, offset, &hdr[0]);
|
||||
offset += sizeof (efx_dword_t);
|
||||
|
||||
EFX_POPULATE_DWORD_2(dword,
|
||||
EFX_POPULATE_DWORD_2(hdr[1],
|
||||
MC_CMD_V2_EXTN_IN_EXTENDED_CMD, emrp->emr_cmd,
|
||||
MC_CMD_V2_EXTN_IN_ACTUAL_LEN, emrp->emr_in_length);
|
||||
EFSYS_MEM_WRITED(esmp, offset, &dword);
|
||||
offset += sizeof (dword);
|
||||
EFSYS_MEM_WRITED(esmp, offset, &hdr[1]);
|
||||
offset += sizeof (efx_dword_t);
|
||||
} else {
|
||||
/* Construct MCDI v1 header */
|
||||
EFX_POPULATE_DWORD_8(dword,
|
||||
EFX_POPULATE_DWORD_8(hdr[0],
|
||||
MCDI_HEADER_CODE, emrp->emr_cmd,
|
||||
MCDI_HEADER_RESYNC, 1,
|
||||
MCDI_HEADER_DATALEN, emrp->emr_in_length,
|
||||
@ -188,10 +189,18 @@ hunt_mcdi_request_copyin(
|
||||
MCDI_HEADER_ERROR, 0,
|
||||
MCDI_HEADER_RESPONSE, 0,
|
||||
MCDI_HEADER_XFLAGS, xflags);
|
||||
EFSYS_MEM_WRITED(esmp, offset, &dword);
|
||||
offset += sizeof (dword);
|
||||
EFSYS_MEM_WRITED(esmp, 0, &hdr[0]);
|
||||
offset += sizeof (efx_dword_t);
|
||||
}
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
if (emtp->emt_logger != NULL) {
|
||||
emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
|
||||
&hdr, offset,
|
||||
emrp->emr_in_buf, emrp->emr_in_length);
|
||||
}
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
|
||||
/* Construct the payload */
|
||||
for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
|
||||
memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
|
||||
@ -224,8 +233,7 @@ hunt_mcdi_request_copyout(
|
||||
efsys_mem_t *esmp = emtp->emt_dma_mem;
|
||||
unsigned int pos;
|
||||
unsigned int offset;
|
||||
efx_dword_t hdr;
|
||||
efx_dword_t hdr2;
|
||||
efx_dword_t hdr[2];
|
||||
efx_dword_t data;
|
||||
size_t bytes;
|
||||
|
||||
@ -233,16 +241,16 @@ hunt_mcdi_request_copyout(
|
||||
return;
|
||||
|
||||
/* Read the command header to detect MCDI response format */
|
||||
EFSYS_MEM_READD(esmp, 0, &hdr);
|
||||
if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
|
||||
EFSYS_MEM_READD(esmp, 0, &hdr[0]);
|
||||
if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
|
||||
offset = 2 * sizeof (efx_dword_t);
|
||||
|
||||
/*
|
||||
* Read the actual payload length. The length given in the event
|
||||
* is only correct for responses with the V1 format.
|
||||
*/
|
||||
EFSYS_MEM_READD(esmp, sizeof (efx_dword_t), &hdr2);
|
||||
emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr2,
|
||||
EFSYS_MEM_READD(esmp, sizeof (efx_dword_t), &hdr[1]);
|
||||
emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr[1],
|
||||
MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
|
||||
} else {
|
||||
offset = sizeof (efx_dword_t);
|
||||
@ -255,6 +263,15 @@ hunt_mcdi_request_copyout(
|
||||
memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
|
||||
MIN(sizeof (data), bytes - pos));
|
||||
}
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
if (emtp->emt_logger != NULL) {
|
||||
emtp->emt_logger(emtp->emt_context,
|
||||
EFX_LOG_MCDI_RESPONSE,
|
||||
&hdr, offset,
|
||||
emrp->emr_out_buf, emrp->emr_out_length_used);
|
||||
}
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
}
|
||||
|
||||
__checkReturn boolean_t
|
||||
@ -265,7 +282,7 @@ hunt_mcdi_request_poll(
|
||||
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
|
||||
efsys_mem_t *esmp = emtp->emt_dma_mem;
|
||||
efx_mcdi_req_t *emrp;
|
||||
efx_dword_t dword;
|
||||
efx_dword_t hdr[2];
|
||||
unsigned int seq;
|
||||
unsigned int cmd;
|
||||
unsigned int length;
|
||||
@ -285,23 +302,21 @@ hunt_mcdi_request_poll(
|
||||
offset = 0;
|
||||
|
||||
/* Read the command header */
|
||||
EFSYS_MEM_READD(esmp, offset, &dword);
|
||||
EFSYS_MEM_READD(esmp, offset, &hdr[0]);
|
||||
offset += sizeof (efx_dword_t);
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
|
||||
if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_RESPONSE) == 0) {
|
||||
EFSYS_UNLOCK(enp->en_eslp, state);
|
||||
return (B_FALSE);
|
||||
}
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
|
||||
efx_dword_t dword2;
|
||||
|
||||
EFSYS_MEM_READD(esmp, offset, &dword2);
|
||||
if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
|
||||
EFSYS_MEM_READD(esmp, offset, &hdr[1]);
|
||||
offset += sizeof (efx_dword_t);
|
||||
|
||||
cmd = EFX_DWORD_FIELD(dword2, MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
|
||||
length = EFX_DWORD_FIELD(dword2, MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
|
||||
cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
|
||||
length = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
|
||||
} else {
|
||||
cmd = EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE);
|
||||
length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
|
||||
cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE);
|
||||
length = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN);
|
||||
}
|
||||
|
||||
/* Request complete */
|
||||
@ -309,7 +324,7 @@ hunt_mcdi_request_poll(
|
||||
seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
|
||||
|
||||
/* Check for synchronous reboot */
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 && length == 0) {
|
||||
if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR) != 0 && length == 0) {
|
||||
/* The MC has rebooted since the request was sent. */
|
||||
EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
|
||||
hunt_mcdi_poll_reboot(enp);
|
||||
@ -326,22 +341,31 @@ hunt_mcdi_request_poll(
|
||||
|
||||
/* Check that the returned data is consistent */
|
||||
if (cmd != emrp->emr_cmd ||
|
||||
EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
|
||||
EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ) != seq) {
|
||||
/* Response is for a different request */
|
||||
rc = EIO;
|
||||
goto fail2;
|
||||
}
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
|
||||
efx_dword_t errdword;
|
||||
if (EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR)) {
|
||||
efx_dword_t err[2];
|
||||
int errcode;
|
||||
int argnum;
|
||||
|
||||
/* Read error code (and arg num for MCDI v2 commands) */
|
||||
EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_CODE_OFST, &errdword);
|
||||
errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
|
||||
EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_CODE_OFST, &err[0]);
|
||||
errcode = EFX_DWORD_FIELD(err[0], EFX_DWORD_0);
|
||||
|
||||
EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_ARG_OFST, &errdword);
|
||||
argnum = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
|
||||
EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_ARG_OFST, &err[1]);
|
||||
argnum = EFX_DWORD_FIELD(err[1], EFX_DWORD_0);
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
if (emtp->emt_logger != NULL) {
|
||||
emtp->emt_logger(emtp->emt_context,
|
||||
EFX_LOG_MCDI_RESPONSE,
|
||||
&hdr, offset,
|
||||
&err, sizeof (err));
|
||||
}
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
|
||||
rc = efx_mcdi_request_errcode(errcode);
|
||||
if (!emrp->emr_quiet) {
|
||||
|
@ -61,7 +61,11 @@ siena_mcdi_request_copyin(
|
||||
__in boolean_t ev_cpl,
|
||||
__in boolean_t new_epoch)
|
||||
{
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
|
||||
#endif
|
||||
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
|
||||
efx_dword_t hdr;
|
||||
efx_dword_t dword;
|
||||
unsigned int xflags;
|
||||
unsigned int pdur;
|
||||
@ -80,15 +84,24 @@ siena_mcdi_request_copyin(
|
||||
xflags |= MCDI_HEADER_XFLAGS_EVREQ;
|
||||
|
||||
/* Construct the header in shared memory */
|
||||
EFX_POPULATE_DWORD_6(dword,
|
||||
EFX_POPULATE_DWORD_6(hdr,
|
||||
MCDI_HEADER_CODE, emrp->emr_cmd,
|
||||
MCDI_HEADER_RESYNC, 1,
|
||||
MCDI_HEADER_DATALEN, emrp->emr_in_length,
|
||||
MCDI_HEADER_SEQ, seq,
|
||||
MCDI_HEADER_RESPONSE, 0,
|
||||
MCDI_HEADER_XFLAGS, xflags);
|
||||
EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
|
||||
EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_TRUE);
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
if (emtp->emt_logger != NULL) {
|
||||
emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
|
||||
&hdr, sizeof (hdr),
|
||||
emrp->emr_in_buf, emrp->emr_in_length);
|
||||
}
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
|
||||
/* Construct the payload */
|
||||
for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
|
||||
memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
|
||||
MIN(sizeof (dword), emrp->emr_in_length - pos));
|
||||
@ -106,6 +119,10 @@ siena_mcdi_request_copyout(
|
||||
__in efx_nic_t *enp,
|
||||
__in efx_mcdi_req_t *emrp)
|
||||
{
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
|
||||
efx_dword_t hdr;
|
||||
#endif
|
||||
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
|
||||
unsigned int pos;
|
||||
unsigned int pdur;
|
||||
@ -124,6 +141,17 @@ siena_mcdi_request_copyout(
|
||||
MIN(sizeof (data), bytes - pos));
|
||||
}
|
||||
}
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
if (emtp->emt_logger != NULL) {
|
||||
EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE);
|
||||
|
||||
emtp->emt_logger(emtp->emt_context,
|
||||
EFX_LOG_MCDI_RESPONSE,
|
||||
&hdr, sizeof (hdr),
|
||||
emrp->emr_out_buf, emrp->emr_out_length_used);
|
||||
}
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
}
|
||||
|
||||
efx_rc_t
|
||||
@ -167,9 +195,12 @@ siena_mcdi_poll_reboot(
|
||||
siena_mcdi_request_poll(
|
||||
__in efx_nic_t *enp)
|
||||
{
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
|
||||
#endif
|
||||
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
|
||||
efx_mcdi_req_t *emrp;
|
||||
efx_dword_t dword;
|
||||
efx_dword_t hdr;
|
||||
unsigned int pdur;
|
||||
unsigned int seq;
|
||||
unsigned int length;
|
||||
@ -199,8 +230,8 @@ siena_mcdi_request_poll(
|
||||
pdur = SIENA_MCDI_PDU(emip);
|
||||
|
||||
/* Read the command header */
|
||||
EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE);
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
|
||||
EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &hdr, B_FALSE);
|
||||
if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE) == 0) {
|
||||
EFSYS_UNLOCK(enp->en_eslp, state);
|
||||
return (B_FALSE);
|
||||
}
|
||||
@ -210,8 +241,8 @@ siena_mcdi_request_poll(
|
||||
seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
|
||||
|
||||
/* Check for synchronous reboot */
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 &&
|
||||
EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) {
|
||||
if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR) != 0 &&
|
||||
EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN) == 0) {
|
||||
/* Consume status word */
|
||||
EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
|
||||
siena_mcdi_poll_reboot(enp);
|
||||
@ -223,15 +254,15 @@ siena_mcdi_request_poll(
|
||||
EFSYS_UNLOCK(enp->en_eslp, state);
|
||||
|
||||
/* Check that the returned data is consistent */
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd ||
|
||||
EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
|
||||
if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) != emrp->emr_cmd ||
|
||||
EFX_DWORD_FIELD(hdr, MCDI_HEADER_SEQ) != seq) {
|
||||
/* Response is for a different request */
|
||||
rc = EIO;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
|
||||
if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
|
||||
length = EFX_DWORD_FIELD(hdr, MCDI_HEADER_DATALEN);
|
||||
if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_ERROR)) {
|
||||
efx_dword_t errdword;
|
||||
int errcode;
|
||||
|
||||
@ -240,6 +271,16 @@ siena_mcdi_request_poll(
|
||||
pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
|
||||
&errdword, B_FALSE);
|
||||
errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
|
||||
|
||||
#if EFSYS_OPT_MCDI_LOGGING
|
||||
if (emtp->emt_logger != NULL) {
|
||||
emtp->emt_logger(emtp->emt_context,
|
||||
EFX_LOG_MCDI_RESPONSE,
|
||||
&hdr, sizeof (hdr),
|
||||
&errdword, sizeof (errdword));
|
||||
}
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
|
||||
rc = efx_mcdi_request_errcode(errcode);
|
||||
if (!emrp->emr_quiet) {
|
||||
EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
|
||||
|
Loading…
x
Reference in New Issue
Block a user