summaryrefslogtreecommitdiffstats
path: root/sys/dev/sfxge/common/efx_mcdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sfxge/common/efx_mcdi.c')
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c589
1 files changed, 455 insertions, 134 deletions
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index e1c4b45..07224c7 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -31,11 +31,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "efsys.h"
#include "efx.h"
-#include "efx_types.h"
-#include "efx_regs.h"
-#include "efx_regs_mcdi.h"
#include "efx_impl.h"
#if EFSYS_OPT_MCDI
@@ -46,42 +42,40 @@ __FBSDID("$FreeBSD$");
static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
siena_mcdi_init, /* emco_init */
siena_mcdi_request_copyin, /* emco_request_copyin */
- siena_mcdi_request_poll, /* emco_request_poll */
siena_mcdi_request_copyout, /* emco_request_copyout */
siena_mcdi_poll_reboot, /* emco_poll_reboot */
+ siena_mcdi_poll_response, /* emco_poll_response */
+ siena_mcdi_read_response, /* emco_read_response */
siena_mcdi_fini, /* emco_fini */
- siena_mcdi_fw_update_supported, /* emco_fw_update_supported */
- siena_mcdi_macaddr_change_supported,
- /* emco_macaddr_change_supported */
+ siena_mcdi_feature_supported, /* emco_feature_supported */
};
#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_HUNTINGTON
-
-static efx_mcdi_ops_t __efx_mcdi_hunt_ops = {
- hunt_mcdi_init, /* emco_init */
- hunt_mcdi_request_copyin, /* emco_request_copyin */
- hunt_mcdi_request_poll, /* emco_request_poll */
- hunt_mcdi_request_copyout, /* emco_request_copyout */
- hunt_mcdi_poll_reboot, /* emco_poll_reboot */
- hunt_mcdi_fini, /* emco_fini */
- hunt_mcdi_fw_update_supported, /* emco_fw_update_supported */
- hunt_mcdi_macaddr_change_supported,
- /* emco_macaddr_change_supported */
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
+
+static efx_mcdi_ops_t __efx_mcdi_ef10_ops = {
+ ef10_mcdi_init, /* emco_init */
+ ef10_mcdi_request_copyin, /* emco_request_copyin */
+ ef10_mcdi_request_copyout, /* emco_request_copyout */
+ ef10_mcdi_poll_reboot, /* emco_poll_reboot */
+ ef10_mcdi_poll_response, /* emco_poll_response */
+ ef10_mcdi_read_response, /* emco_read_response */
+ ef10_mcdi_fini, /* emco_fini */
+ ef10_mcdi_feature_supported, /* emco_feature_supported */
};
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_init(
__in efx_nic_t *enp,
__in const efx_mcdi_transport_t *emtp)
{
efx_mcdi_ops_t *emcop;
- int rc;
+ efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
@@ -102,10 +96,16 @@ efx_mcdi_init(
#if EFSYS_OPT_HUNTINGTON
case EFX_FAMILY_HUNTINGTON:
- emcop = (efx_mcdi_ops_t *)&__efx_mcdi_hunt_ops;
+ emcop = (efx_mcdi_ops_t *)&__efx_mcdi_ef10_ops;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
+#if EFSYS_OPT_MEDFORD
+ case EFX_FAMILY_MEDFORD:
+ emcop = (efx_mcdi_ops_t *)&__efx_mcdi_ef10_ops;
+ break;
+#endif /* EFSYS_OPT_MEDFORD */
+
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;
@@ -136,7 +136,7 @@ fail3:
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
enp->en_mcdi.em_emcop = NULL;
enp->en_mcdi.em_emtp = NULL;
@@ -178,6 +178,62 @@ efx_mcdi_new_epoch(
EFSYS_UNLOCK(enp->en_eslp, state);
}
+static void
+efx_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+}
+
+static void
+efx_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ emcop->emco_request_copyout(enp, emrp);
+}
+
+static efx_rc_t
+efx_mcdi_poll_reboot(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_rc_t rc;
+
+ rc = emcop->emco_poll_reboot(enp);
+ return (rc);
+}
+
+static boolean_t
+efx_mcdi_poll_response(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ boolean_t available;
+
+ available = emcop->emco_poll_response(enp);
+ return (available);
+}
+
+static void
+efx_mcdi_read_response(
+ __in efx_nic_t *enp,
+ __out void *bufferp,
+ __in size_t offset,
+ __in size_t length)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ emcop->emco_read_response(enp, bufferp, offset, length);
+}
void
efx_mcdi_request_start(
@@ -186,7 +242,6 @@ efx_mcdi_request_start(
__in boolean_t ev_cpl)
{
efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
unsigned int seq;
boolean_t new_epoch;
int state;
@@ -195,9 +250,6 @@ efx_mcdi_request_start(
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- if (emcop == NULL || emcop->emco_request_copyin == NULL)
- return;
-
/*
* efx_mcdi_request_start() is naturally serialised against both
* efx_mcdi_request_poll() and efx_mcdi_ev_cpl()/efx_mcdi_ev_death(),
@@ -219,26 +271,194 @@ efx_mcdi_request_start(
new_epoch = emip->emi_new_epoch;
EFSYS_UNLOCK(enp->en_eslp, state);
- emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+ efx_mcdi_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+}
+
+
+ void
+efx_mcdi_read_response_header(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp)
+{
+#if EFSYS_OPT_MCDI_LOGGING
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t hdr[2];
+ unsigned int hdr_len;
+ unsigned int data_len;
+ unsigned int seq;
+ unsigned int cmd;
+ unsigned int error;
+ efx_rc_t rc;
+
+ EFSYS_ASSERT(emrp != NULL);
+
+ efx_mcdi_read_response(enp, &hdr[0], 0, sizeof (hdr[0]));
+ hdr_len = sizeof (hdr[0]);
+
+ cmd = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_CODE);
+ seq = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_SEQ);
+ error = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_ERROR);
+
+ if (cmd != MC_CMD_V2_EXTN) {
+ data_len = EFX_DWORD_FIELD(hdr[0], MCDI_HEADER_DATALEN);
+ } else {
+ efx_mcdi_read_response(enp, &hdr[1], hdr_len, sizeof (hdr[1]));
+ hdr_len += sizeof (hdr[1]);
+
+ cmd = EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
+ data_len =
+ EFX_DWORD_FIELD(hdr[1], MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ }
+
+ if (error && (data_len == 0)) {
+ /* The MC has rebooted since the request was sent. */
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
+ efx_mcdi_poll_reboot(enp);
+ rc = EIO;
+ goto fail1;
+ }
+ if ((cmd != emrp->emr_cmd) ||
+ (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) {
+ /* Response is for a different request */
+ rc = EIO;
+ goto fail2;
+ }
+ if (error) {
+ efx_dword_t err[2];
+ unsigned int err_len = MIN(data_len, sizeof (err));
+ int err_code = MC_CMD_ERR_EPROTO;
+ int err_arg = 0;
+
+ /* Read error code (and arg num for MCDI v2 commands) */
+ efx_mcdi_read_response(enp, &err, hdr_len, err_len);
+
+ if (err_len >= (MC_CMD_ERR_CODE_OFST + sizeof (efx_dword_t)))
+ err_code = EFX_DWORD_FIELD(err[0], EFX_DWORD_0);
+#ifdef WITH_MCDI_V2
+ if (err_len >= (MC_CMD_ERR_ARG_OFST + sizeof (efx_dword_t)))
+ err_arg = EFX_DWORD_FIELD(err[1], EFX_DWORD_0);
+#endif
+ emrp->emr_err_code = err_code;
+ emrp->emr_err_arg = err_arg;
+
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ if ((err_code == MC_CMD_ERR_PROXY_PENDING) &&
+ (err_len == sizeof (err))) {
+ /*
+ * The MCDI request would normally fail with EPERM, but
+ * firmware has forwarded it to an authorization agent
+ * attached to a privileged PF.
+ *
+ * Save the authorization request handle. The client
+ * must wait for a PROXY_RESPONSE event, or timeout.
+ */
+ emrp->emr_proxy_handle = err_arg;
+ }
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
+#if EFSYS_OPT_MCDI_LOGGING
+ if (emtp->emt_logger != NULL) {
+ emtp->emt_logger(emtp->emt_context,
+ EFX_LOG_MCDI_RESPONSE,
+ &hdr, hdr_len,
+ &err, err_len);
+ }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
+ int, err_code, int, err_arg);
+ }
+
+ rc = efx_mcdi_request_errcode(err_code);
+ goto fail3;
+ }
+
+ emrp->emr_rc = 0;
+ emrp->emr_out_length_used = data_len;
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+ emrp->emr_proxy_handle = 0;
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+ return;
+
+fail3:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail3);
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ emrp->emr_rc = rc;
+ emrp->emr_out_length_used = 0;
}
+
__checkReturn boolean_t
efx_mcdi_request_poll(
__in efx_nic_t *enp)
{
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- boolean_t completed;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t *emrp;
+ int state;
+ efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- completed = B_FALSE;
+ /* Serialise against post-watchdog efx_mcdi_ev* */
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ EFSYS_ASSERT(emip->emi_pending_req != NULL);
+ EFSYS_ASSERT(!emip->emi_ev_cpl);
+ emrp = emip->emi_pending_req;
+
+ /* Check for reboot atomically w.r.t efx_mcdi_request_start */
+ if (emip->emi_poll_cnt++ == 0) {
+ if ((rc = efx_mcdi_poll_reboot(enp)) != 0) {
+ emip->emi_pending_req = NULL;
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ goto fail1;
+ }
+ }
+
+ /* Check if a response is available */
+ if (efx_mcdi_poll_response(enp) == B_FALSE) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+
+ /* Read the response header */
+ efx_mcdi_read_response_header(enp, emrp);
+
+ /* Request complete */
+ emip->emi_pending_req = NULL;
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ if ((rc = emrp->emr_rc) != 0)
+ goto fail2;
+
+ efx_mcdi_request_copyout(enp, emrp);
+ return (B_TRUE);
+
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
- if (emcop != NULL && emcop->emco_request_poll != NULL)
- completed = emcop->emco_request_poll(enp);
+ /* Reboot/Assertion */
+ if (rc == EIO || rc == EINTR)
+ efx_mcdi_raise_exception(enp, emrp, rc);
- return (completed);
+ return (B_TRUE);
}
__checkReturn boolean_t
@@ -285,7 +505,7 @@ efx_mcdi_request_abort(
return (aborted);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_request_errcode(
__in unsigned int err)
{
@@ -346,6 +566,9 @@ efx_mcdi_request_errcode(
case MC_CMD_ERR_MAC_EXIST:
return (EEXIST);
+ case MC_CMD_ERR_PROXY_PENDING:
+ return (EAGAIN);
+
default:
EFSYS_PROBE1(mc_pcol_error, int, err);
return (EIO);
@@ -378,16 +601,6 @@ efx_mcdi_raise_exception(
emtp->emt_exception(emtp->emt_context, exception);
}
-static int
-efx_mcdi_poll_reboot(
- __in efx_nic_t *enp)
-{
- efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
-
- return (emcop->emco_poll_reboot(enp));
-}
-
-
void
efx_mcdi_execute(
__in efx_nic_t *enp,
@@ -450,27 +663,86 @@ efx_mcdi_ev_cpl(
emip->emi_pending_req = NULL;
EFSYS_UNLOCK(enp->en_eslp, state);
- /*
- * Fill out the remaining hdr fields, and copyout the payload
- * if the user supplied an output buffer.
- */
- if (errcode != 0) {
- if (!emrp->emr_quiet) {
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
- int, errcode);
- }
- emrp->emr_out_length_used = 0;
- emrp->emr_rc = efx_mcdi_request_errcode(errcode);
+ if (emip->emi_max_version >= 2) {
+ /* MCDIv2 response details do not fit into an event. */
+ efx_mcdi_read_response_header(enp, emrp);
} else {
- emrp->emr_out_length_used = outlen;
- emrp->emr_rc = 0;
-
+ if (errcode != 0) {
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
+ int, errcode);
+ }
+ emrp->emr_out_length_used = 0;
+ emrp->emr_rc = efx_mcdi_request_errcode(errcode);
+ } else {
+ emrp->emr_out_length_used = outlen;
+ emrp->emr_rc = 0;
+ }
+ }
+ if (errcode == 0) {
emcop->emco_request_copyout(enp, emrp);
}
emtp->emt_ev_cpl(emtp->emt_context);
}
+#if EFSYS_OPT_MCDI_PROXY_AUTH
+
+ __checkReturn efx_rc_t
+efx_mcdi_get_proxy_handle(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __out uint32_t *handlep)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_rc_t rc;
+
+ /*
+ * Return proxy handle from MCDI request that returned with error
+ * MC_MCD_ERR_PROXY_PENDING. This handle is used to wait for a matching
+ * PROXY_RESPONSE event.
+ */
+ if ((emrp == NULL) || (handlep == NULL)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+ if ((emrp->emr_rc != 0) &&
+ (emrp->emr_err_code == MC_CMD_ERR_PROXY_PENDING)) {
+ *handlep = emrp->emr_proxy_handle;
+ rc = 0;
+ } else {
+ *handlep = 0;
+ rc = ENOENT;
+ }
+ return (rc);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+ return (rc);
+}
+
+ void
+efx_mcdi_ev_proxy_response(
+ __in efx_nic_t *enp,
+ __in unsigned int handle,
+ __in unsigned int status)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efx_rc_t rc;
+
+ /*
+ * Handle results of an authorization request for a privileged MCDI
+ * command. If authorization was granted then we must re-issue the
+ * original MCDI request. If authorization failed or timed out,
+ * then the original MCDI request should be completed with the
+ * result code from this event.
+ */
+ rc = (status == 0) ? 0 : efx_mcdi_request_errcode(status);
+
+ emtp->emt_ev_proxy_response(emtp->emt_context, handle, rc);
+}
+#endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
+
void
efx_mcdi_ev_death(
__in efx_nic_t *enp,
@@ -524,7 +796,7 @@ efx_mcdi_ev_death(
emtp->emt_ev_cpl(emtp->emt_context);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_version(
__in efx_nic_t *enp,
__out_ecount_opt(4) uint16_t versionp[4],
@@ -540,7 +812,7 @@ efx_mcdi_version(
uint16_t version[4];
uint32_t build;
efx_mcdi_boot_t status;
- int rc;
+ efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
@@ -635,19 +907,19 @@ fail3:
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
-static __checkReturn int
+static __checkReturn efx_rc_t
efx_mcdi_do_reboot(
__in efx_nic_t *enp,
__in boolean_t after_assertion)
{
uint8_t payload[MAX(MC_CMD_REBOOT_IN_LEN, MC_CMD_REBOOT_OUT_LEN)];
efx_mcdi_req_t req;
- int rc;
+ efx_rc_t rc;
/*
* We could require the caller to have caused en_mod_flags=0 to
@@ -685,26 +957,26 @@ out:
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_reboot(
__in efx_nic_t *enp)
{
return (efx_mcdi_do_reboot(enp, B_FALSE));
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_exit_assertion_handler(
__in efx_nic_t *enp)
{
return (efx_mcdi_do_reboot(enp, B_TRUE));
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_read_assertion(
__in efx_nic_t *enp)
{
@@ -716,7 +988,7 @@ efx_mcdi_read_assertion(
unsigned int index;
unsigned int ofst;
int retry;
- int rc;
+ efx_rc_t rc;
/*
* Before we attempt to chat to the MC, we should verify that the MC
@@ -795,7 +1067,7 @@ out:
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
@@ -805,7 +1077,7 @@ fail1:
* Internal routines for for specific MCDI requests.
*/
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_drv_attach(
__in efx_nic_t *enp,
__in boolean_t attach)
@@ -815,7 +1087,7 @@ efx_mcdi_drv_attach(
uint8_t payload[MAX(MC_CMD_DRV_ATTACH_IN_LEN,
MC_CMD_DRV_ATTACH_EXT_OUT_LEN)];
uint32_t flags;
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_DRV_ATTACH;
@@ -878,12 +1150,12 @@ fail3:
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_get_board_cfg(
__in efx_nic_t *enp,
__out_opt uint32_t *board_typep,
@@ -894,7 +1166,7 @@ efx_mcdi_get_board_cfg(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
MC_CMD_GET_BOARD_CFG_OUT_LENMIN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOARD_CFG;
@@ -959,12 +1231,12 @@ fail3:
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_get_resource_limits(
__in efx_nic_t *enp,
__out_opt uint32_t *nevqp,
@@ -974,7 +1246,7 @@ efx_mcdi_get_resource_limits(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
@@ -1007,12 +1279,12 @@ efx_mcdi_get_resource_limits(
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_get_phy_cfg(
__in efx_nic_t *enp)
{
@@ -1021,7 +1293,7 @@ efx_mcdi_get_phy_cfg(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_PHY_CFG_IN_LEN,
MC_CMD_GET_PHY_CFG_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_CFG;
@@ -1113,23 +1385,22 @@ efx_mcdi_get_phy_cfg(
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
-
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_firmware_update_supported(
__in efx_nic_t *enp,
__out boolean_t *supportedp)
{
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- int rc;
+ efx_rc_t rc;
- if (emcop != NULL && emcop->emco_fw_update_supported != NULL) {
- if ((rc = emcop->emco_fw_update_supported(enp, supportedp))
- != 0)
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_FW_UPDATE, supportedp)) != 0)
goto fail1;
} else {
/* Earlier devices always supported updates */
@@ -1139,22 +1410,22 @@ efx_mcdi_firmware_update_supported(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_macaddr_change_supported(
__in efx_nic_t *enp,
__out boolean_t *supportedp)
{
efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- int rc;
+ efx_rc_t rc;
- if (emcop != NULL && emcop->emco_macaddr_change_supported != NULL) {
- if ((rc = emcop->emco_macaddr_change_supported(enp, supportedp))
- != 0)
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_MACADDR_CHANGE, supportedp)) != 0)
goto fail1;
} else {
/* Earlier devices always supported MAC changes */
@@ -1164,25 +1435,75 @@ efx_mcdi_macaddr_change_supported(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_link_control_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_rc_t rc;
+
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_LINK_CONTROL, supportedp)) != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported link control */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+efx_mcdi_mac_spoofing_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ efx_rc_t rc;
+
+ if (emcop != NULL) {
+ if ((rc = emcop->emco_feature_supported(enp,
+ EFX_MCDI_FEATURE_MAC_SPOOFING, supportedp)) != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported MAC spoofing */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
#if EFSYS_OPT_BIST
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
/*
* Enter bist offline mode. This is a fw mode which puts the NIC into a state
* where memory BIST tests can be run and not much else can interfere or happen.
* A reboot is required to exit this mode.
*/
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_bist_enable_offline(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- int rc;
+ efx_rc_t rc;
EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_IN_LEN == 0);
EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_OUT_LEN == 0);
@@ -1203,13 +1524,13 @@ efx_mcdi_bist_enable_offline(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_bist_start(
__in efx_nic_t *enp,
__in efx_bist_type_t type)
@@ -1217,7 +1538,7 @@ efx_mcdi_bist_start(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_START_BIST_IN_LEN,
MC_CMD_START_BIST_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_START_BIST;
@@ -1264,7 +1585,7 @@ efx_mcdi_bist_start(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
@@ -1273,14 +1594,14 @@ fail1:
/* Enable logging of some events (e.g. link state changes) */
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_log_ctrl(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_LOG_CTRL_IN_LEN,
MC_CMD_LOG_CTRL_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LOG_CTRL;
@@ -1303,7 +1624,7 @@ efx_mcdi_log_ctrl(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
@@ -1320,7 +1641,7 @@ typedef enum efx_stats_action_e
EFX_STATS_DISABLE,
} efx_stats_action_t;
-static __checkReturn int
+static __checkReturn efx_rc_t
efx_mcdi_mac_stats(
__in efx_nic_t *enp,
__in_opt efsys_mem_t *esmp,
@@ -1334,7 +1655,7 @@ efx_mcdi_mac_stats(
int enable = (action == EFX_STATS_ENABLE_NOEVENTS);
int events = (action == EFX_STATS_ENABLE_EVENTS);
int disable = (action == EFX_STATS_DISABLE);
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_MAC_STATS;
@@ -1388,16 +1709,16 @@ efx_mcdi_mac_stats(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_mac_stats_clear(
__in efx_nic_t *enp)
{
- int rc;
+ efx_rc_t rc;
if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR)) != 0)
goto fail1;
@@ -1405,17 +1726,17 @@ efx_mcdi_mac_stats_clear(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_mac_stats_upload(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp)
{
- int rc;
+ efx_rc_t rc;
/*
* The MC DMAs aggregate statistics for our convenience, so we can
@@ -1428,19 +1749,19 @@ efx_mcdi_mac_stats_upload(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_mac_stats_periodic(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__in uint16_t period,
__in boolean_t events)
{
- int rc;
+ efx_rc_t rc;
/*
* The MC DMAs aggregate statistics for our convenience, so we can
@@ -1461,14 +1782,14 @@ efx_mcdi_mac_stats_periodic(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
#endif /* EFSYS_OPT_MAC_STATS */
-#if EFSYS_OPT_HUNTINGTON
+#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
/*
* This function returns the pf and vf number of a function. If it is a pf the
@@ -1476,7 +1797,7 @@ fail1:
* function. So if you have 3 vfs on pf 0 the 3 vfs will return (pf=0,vf=0),
* (pf=0,vf=1), (pf=0,vf=2) aand the pf will return (pf=0, vf=0xffff).
*/
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_get_function_info(
__in efx_nic_t *enp,
__out uint32_t *pfp,
@@ -1485,7 +1806,7 @@ efx_mcdi_get_function_info(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_FUNCTION_INFO_IN_LEN,
MC_CMD_GET_FUNCTION_INFO_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_FUNCTION_INFO;
@@ -1515,12 +1836,12 @@ efx_mcdi_get_function_info(
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_privilege_mask(
__in efx_nic_t *enp,
__in uint32_t pf,
@@ -1530,7 +1851,7 @@ efx_mcdi_privilege_mask(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_PRIVILEGE_MASK_IN_LEN,
MC_CMD_PRIVILEGE_MASK_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
@@ -1562,14 +1883,14 @@ efx_mcdi_privilege_mask(
fail2:
EFSYS_PROBE(fail2);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
-#endif /* EFSYS_OPT_HUNTINGTON */
+#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_set_workaround(
__in efx_nic_t *enp,
__in uint32_t type,
@@ -1579,7 +1900,7 @@ efx_mcdi_set_workaround(
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_WORKAROUND_IN_LEN,
MC_CMD_WORKAROUND_EXT_OUT_LEN)];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WORKAROUND;
@@ -1608,13 +1929,13 @@ efx_mcdi_set_workaround(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
- __checkReturn int
+ __checkReturn efx_rc_t
efx_mcdi_get_workarounds(
__in efx_nic_t *enp,
__out_opt uint32_t *implementedp,
@@ -1622,7 +1943,7 @@ efx_mcdi_get_workarounds(
{
efx_mcdi_req_t req;
uint8_t payload[MC_CMD_GET_WORKAROUNDS_OUT_LEN];
- int rc;
+ efx_rc_t rc;
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
@@ -1650,7 +1971,7 @@ efx_mcdi_get_workarounds(
return (0);
fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
OpenPOWER on IntegriCloud