sfxge: unify MCDI response polling
Submitted by: Andy Moreton <amoreton at solarflare.com> Reviewed by: philip Sponsored by: Solarflare Communications, Inc. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D4496
This commit is contained in:
parent
610d610a77
commit
ebdff42c42
@ -456,12 +456,12 @@ typedef struct efx_mcdi_ops_s {
|
||||
efx_rc_t (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
|
||||
void (*emco_request_copyin)(efx_nic_t *, efx_mcdi_req_t *,
|
||||
unsigned int, boolean_t, boolean_t);
|
||||
boolean_t (*emco_request_poll)(efx_nic_t *);
|
||||
void (*emco_request_copyout)(efx_nic_t *, efx_mcdi_req_t *);
|
||||
efx_rc_t (*emco_poll_reboot)(efx_nic_t *);
|
||||
boolean_t (*emco_poll_response)(efx_nic_t *);
|
||||
void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t);
|
||||
void (*emco_fini)(efx_nic_t *);
|
||||
efx_rc_t (*emco_feature_supported)(efx_nic_t *, efx_mcdi_feature_id_t, boolean_t *);
|
||||
void (*emco_read_response)(efx_nic_t *, void *, size_t, size_t);
|
||||
} efx_mcdi_ops_t;
|
||||
|
||||
typedef struct efx_mcdi_s {
|
||||
|
@ -46,12 +46,12 @@ __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_feature_supported, /* emco_feature_supported */
|
||||
siena_mcdi_read_response, /* emco_read_response */
|
||||
};
|
||||
|
||||
#endif /* EFSYS_OPT_SIENA */
|
||||
@ -61,12 +61,12 @@ static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
|
||||
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_poll_response, /* emco_poll_response */
|
||||
hunt_mcdi_read_response, /* emco_read_response */
|
||||
hunt_mcdi_fini, /* emco_fini */
|
||||
hunt_mcdi_feature_supported, /* emco_feature_supported */
|
||||
hunt_mcdi_read_response, /* emco_read_response */
|
||||
};
|
||||
|
||||
#endif /* EFSYS_OPT_HUNTINGTON */
|
||||
@ -189,7 +189,7 @@ efx_mcdi_request_copyin(
|
||||
emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
|
||||
}
|
||||
|
||||
static void __unused
|
||||
static void
|
||||
efx_mcdi_request_copyout(
|
||||
__in efx_nic_t *enp,
|
||||
__in efx_mcdi_req_t *emrp)
|
||||
@ -210,6 +210,17 @@ efx_mcdi_poll_reboot(
|
||||
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,
|
||||
@ -389,19 +400,63 @@ fail1:
|
||||
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);
|
||||
|
||||
if (emcop != NULL && emcop->emco_request_poll != NULL)
|
||||
completed = emcop->emco_request_poll(enp);
|
||||
EFSYS_ASSERT(emip->emi_pending_req != NULL);
|
||||
EFSYS_ASSERT(!emip->emi_ev_cpl);
|
||||
emrp = emip->emi_pending_req;
|
||||
|
||||
return (completed);
|
||||
/* 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);
|
||||
|
||||
/* Reboot/Assertion */
|
||||
if (rc == EIO || rc == EINTR)
|
||||
efx_mcdi_raise_exception(enp, emrp, rc);
|
||||
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
__checkReturn boolean_t
|
||||
|
@ -263,6 +263,10 @@ hunt_mcdi_request_copyin(
|
||||
__in boolean_t ev_cpl,
|
||||
__in boolean_t new_epoch);
|
||||
|
||||
extern __checkReturn boolean_t
|
||||
hunt_mcdi_poll_response(
|
||||
__in efx_nic_t *enp);
|
||||
|
||||
extern void
|
||||
hunt_mcdi_read_response(
|
||||
__in efx_nic_t *enp,
|
||||
@ -270,10 +274,6 @@ hunt_mcdi_read_response(
|
||||
__in size_t offset,
|
||||
__in size_t length);
|
||||
|
||||
extern __checkReturn boolean_t
|
||||
hunt_mcdi_request_poll(
|
||||
__in efx_nic_t *enp);
|
||||
|
||||
extern void
|
||||
hunt_mcdi_request_copyout(
|
||||
__in efx_nic_t *enp,
|
||||
|
@ -268,7 +268,7 @@ hunt_mcdi_request_copyout(
|
||||
#endif /* EFSYS_OPT_MCDI_LOGGING */
|
||||
}
|
||||
|
||||
static __checkReturn boolean_t
|
||||
__checkReturn boolean_t
|
||||
hunt_mcdi_poll_response(
|
||||
__in efx_nic_t *enp)
|
||||
{
|
||||
@ -299,59 +299,6 @@ hunt_mcdi_read_response(
|
||||
}
|
||||
}
|
||||
|
||||
__checkReturn boolean_t
|
||||
hunt_mcdi_request_poll(
|
||||
__in efx_nic_t *enp)
|
||||
{
|
||||
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_family, ==, EFX_FAMILY_HUNTINGTON);
|
||||
|
||||
/* 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 if a response is available */
|
||||
if (hunt_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;
|
||||
|
||||
/* Ensure stale MCDI requests fail after an MC reboot. */
|
||||
emip->emi_new_epoch = B_FALSE;
|
||||
|
||||
EFSYS_UNLOCK(enp->en_eslp, state);
|
||||
|
||||
if ((rc = emrp->emr_rc) != 0)
|
||||
goto fail1;
|
||||
|
||||
hunt_mcdi_request_copyout(enp, emrp);
|
||||
goto out;
|
||||
|
||||
fail1:
|
||||
if (!emrp->emr_quiet)
|
||||
EFSYS_PROBE1(fail1, efx_rc_t, rc);
|
||||
|
||||
/* Reboot/Assertion */
|
||||
if (rc == EIO || rc == EINTR)
|
||||
efx_mcdi_raise_exception(enp, emrp, rc);
|
||||
|
||||
out:
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
efx_rc_t
|
||||
hunt_mcdi_poll_reboot(
|
||||
__in efx_nic_t *enp)
|
||||
|
@ -121,6 +121,10 @@ siena_mcdi_request_copyin(
|
||||
__in boolean_t ev_cpl,
|
||||
__in boolean_t new_epoch);
|
||||
|
||||
extern __checkReturn boolean_t
|
||||
siena_mcdi_poll_response(
|
||||
__in efx_nic_t *enp);
|
||||
|
||||
extern void
|
||||
siena_mcdi_read_response(
|
||||
__in efx_nic_t *enp,
|
||||
@ -128,10 +132,6 @@ siena_mcdi_read_response(
|
||||
__in size_t offset,
|
||||
__in size_t length);
|
||||
|
||||
extern __checkReturn boolean_t
|
||||
siena_mcdi_request_poll(
|
||||
__in efx_nic_t *enp);
|
||||
|
||||
extern void
|
||||
siena_mcdi_request_copyout(
|
||||
__in efx_nic_t *enp,
|
||||
|
@ -180,7 +180,7 @@ siena_mcdi_poll_reboot(
|
||||
#endif
|
||||
}
|
||||
|
||||
static __checkReturn boolean_t
|
||||
extern __checkReturn boolean_t
|
||||
siena_mcdi_poll_response(
|
||||
__in efx_nic_t *enp)
|
||||
{
|
||||
@ -218,69 +218,6 @@ siena_mcdi_read_response(
|
||||
}
|
||||
}
|
||||
|
||||
__checkReturn boolean_t
|
||||
siena_mcdi_request_poll(
|
||||
__in efx_nic_t *enp)
|
||||
{
|
||||
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_family, ==, EFX_FAMILY_SIENA);
|
||||
|
||||
/* 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 = siena_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 (siena_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;
|
||||
|
||||
siena_mcdi_request_copyout(enp, emrp);
|
||||
goto out;
|
||||
|
||||
fail2:
|
||||
if (!emrp->emr_quiet)
|
||||
EFSYS_PROBE(fail2);
|
||||
fail1:
|
||||
if (!emrp->emr_quiet)
|
||||
EFSYS_PROBE1(fail1, efx_rc_t, rc);
|
||||
|
||||
/* Reboot/Assertion */
|
||||
if (rc == EIO || rc == EINTR)
|
||||
efx_mcdi_raise_exception(enp, emrp, rc);
|
||||
|
||||
out:
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
__checkReturn efx_rc_t
|
||||
siena_mcdi_init(
|
||||
__in efx_nic_t *enp,
|
||||
|
Loading…
x
Reference in New Issue
Block a user