sfc: Add MC BISTs to ethtool offline self test on EF10
To run BISTs the MC goes down in to a special mode where it will only respond to MCDI from the testing PF, and TX, RX and event queues are torn down. Other PFs get a message as it goes down to tell them it's going down. When the other PFs get this message, they check the soft status register to tell when the MC has rebooted after BIST mode and they can start recovery. [bwh: Convert the test result to 1 or -1 as for earlier NICs] Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:

committed by
Ben Hutchings

parent
512bb06c65
commit
74cd60a4d7
@@ -83,6 +83,7 @@ const char *const efx_reset_type_names[] = {
|
||||
[RESET_TYPE_DMA_ERROR] = "DMA_ERROR",
|
||||
[RESET_TYPE_TX_SKIP] = "TX_SKIP",
|
||||
[RESET_TYPE_MC_FAILURE] = "MC_FAILURE",
|
||||
[RESET_TYPE_MC_BIST] = "MC_BIST",
|
||||
};
|
||||
|
||||
/* Reset workqueue. If any NIC has a hardware failure then a reset will be
|
||||
@@ -91,6 +92,12 @@ const char *const efx_reset_type_names[] = {
|
||||
*/
|
||||
static struct workqueue_struct *reset_workqueue;
|
||||
|
||||
/* How often and how many times to poll for a reset while waiting for a
|
||||
* BIST that another function started to complete.
|
||||
*/
|
||||
#define BIST_WAIT_DELAY_MS 100
|
||||
#define BIST_WAIT_DELAY_COUNT 100
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Configurable values
|
||||
@@ -2389,6 +2396,24 @@ int efx_try_recovery(struct efx_nic *efx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void efx_wait_for_bist_end(struct efx_nic *efx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BIST_WAIT_DELAY_COUNT; ++i) {
|
||||
if (efx_mcdi_poll_reboot(efx))
|
||||
goto out;
|
||||
msleep(BIST_WAIT_DELAY_MS);
|
||||
}
|
||||
|
||||
netif_err(efx, drv, efx->net_dev, "Warning: No MC reboot after BIST mode\n");
|
||||
out:
|
||||
/* Either way unset the BIST flag. If we found no reboot we probably
|
||||
* won't recover, but we should try.
|
||||
*/
|
||||
efx->mc_bist_for_other_fn = false;
|
||||
}
|
||||
|
||||
/* The worker thread exists so that code that cannot sleep can
|
||||
* schedule a reset for later.
|
||||
*/
|
||||
@@ -2401,6 +2426,9 @@ static void efx_reset_work(struct work_struct *data)
|
||||
pending = ACCESS_ONCE(efx->reset_pending);
|
||||
method = fls(pending) - 1;
|
||||
|
||||
if (method == RESET_TYPE_MC_BIST)
|
||||
efx_wait_for_bist_end(efx);
|
||||
|
||||
if ((method == RESET_TYPE_RECOVER_OR_DISABLE ||
|
||||
method == RESET_TYPE_RECOVER_OR_ALL) &&
|
||||
efx_try_recovery(efx))
|
||||
@@ -2439,6 +2467,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
|
||||
case RESET_TYPE_WORLD:
|
||||
case RESET_TYPE_DISABLE:
|
||||
case RESET_TYPE_RECOVER_OR_DISABLE:
|
||||
case RESET_TYPE_MC_BIST:
|
||||
method = type;
|
||||
netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n",
|
||||
RESET_TYPE(method));
|
||||
|
Reference in New Issue
Block a user