sfxge(4): add API to inform libefx of hardware removal

The efx_nic_hw_unavailable() checks ensure that if the NIC hardware
has failed or has been physically removed then libefx will stop
further attempts to access the hardware.

Add an interface for libefx clients to force unavailability, so the
hardware is treated as dead or removed even if still physically present.

Submitted by:   Andy Moreton <amoreton at solarflare.com>
Sponsored by:   Solarflare Communications, Inc.
Differential Revision:  https://reviews.freebsd.org/D18261
This commit is contained in:
Andrew Rybchenko 2018-11-30 07:06:01 +00:00
parent c6d5e85dbe
commit b2053d8025
5 changed files with 35 additions and 4 deletions

View File

@ -220,6 +220,10 @@ extern __checkReturn boolean_t
ef10_nic_hw_unavailable(
__in efx_nic_t *enp);
extern void
ef10_nic_set_hw_unavailable(
__in efx_nic_t *enp);
#if EFSYS_OPT_DIAG
extern __checkReturn efx_rc_t

View File

@ -2347,12 +2347,20 @@ ef10_nic_hw_unavailable(
return (B_FALSE);
unavail:
EFSYS_PROBE(hw_unavail);
enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
ef10_nic_set_hw_unavailable(enp);
return (B_TRUE);
}
void
ef10_nic_set_hw_unavailable(
__in efx_nic_t *enp)
{
EFSYS_PROBE(hw_unavail);
enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
}
void
ef10_nic_fini(
__in efx_nic_t *enp)

View File

@ -187,6 +187,10 @@ extern __checkReturn boolean_t
efx_nic_hw_unavailable(
__in efx_nic_t *enp);
extern void
efx_nic_set_hw_unavailable(
__in efx_nic_t *enp);
#if EFSYS_OPT_DIAG
extern __checkReturn efx_rc_t

View File

@ -386,6 +386,7 @@ typedef struct efx_nic_ops_s {
efx_rc_t (*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
uint32_t *, size_t *);
boolean_t (*eno_hw_unavailable)(efx_nic_t *);
void (*eno_set_hw_unavailable)(efx_nic_t *);
#if EFSYS_OPT_DIAG
efx_rc_t (*eno_register_test)(efx_nic_t *);
#endif /* EFSYS_OPT_DIAG */

View File

@ -130,6 +130,7 @@ static const efx_nic_ops_t __efx_nic_siena_ops = {
NULL, /* eno_get_vi_pool */
NULL, /* eno_get_bar_region */
NULL, /* eno_hw_unavailable */
NULL, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
siena_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@ -150,6 +151,7 @@ static const efx_nic_ops_t __efx_nic_hunt_ops = {
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
ef10_nic_hw_unavailable, /* eno_hw_unavailable */
ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@ -170,6 +172,7 @@ static const efx_nic_ops_t __efx_nic_medford_ops = {
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
ef10_nic_hw_unavailable, /* eno_hw_unavailable */
ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@ -190,6 +193,7 @@ static const efx_nic_ops_t __efx_nic_medford2_ops = {
ef10_nic_get_vi_pool, /* eno_get_vi_pool */
ef10_nic_get_bar_region, /* eno_get_bar_region */
ef10_nic_hw_unavailable, /* eno_hw_unavailable */
ef10_nic_set_hw_unavailable, /* eno_set_hw_unavailable */
#if EFSYS_OPT_DIAG
ef10_nic_register_test, /* eno_register_test */
#endif /* EFSYS_OPT_DIAG */
@ -702,11 +706,21 @@ efx_nic_hw_unavailable(
return (B_FALSE);
unavail:
EFSYS_PROBE(hw_unavail);
return (B_TRUE);
}
void
efx_nic_set_hw_unavailable(
__in efx_nic_t *enp)
{
const efx_nic_ops_t *enop = enp->en_enop;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
if (enop->eno_set_hw_unavailable != NULL)
enop->eno_set_hw_unavailable(enp);
}
#if EFSYS_OPT_DIAG