Commit 6b294b8e authored by Robert Stonehouse's avatar Robert Stonehouse Committed by Ben Hutchings

sfc: Poll for MCDI completion once before timeout occurs

There is an as-yet unexplained bug that sometimes prevents (or delays)
the driver seeing the completion event for a completed MCDI request on
the SFC9120.  The requested configuration change will have happened
but the driver assumes it to have failed, and this can result in
further failures.  We can mitigate this by polling for completion
after unsuccessfully waiting for an event.

Fixes: 8127d661 ('sfc: Add support for Solarflare SFC9100 family')
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent 5731d7b3
...@@ -630,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, ...@@ -630,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
rc = efx_mcdi_await_completion(efx); rc = efx_mcdi_await_completion(efx);
if (rc != 0) { if (rc != 0) {
netif_err(efx, hw, efx->net_dev,
"MC command 0x%x inlen %d mode %d timed out\n",
cmd, (int)inlen, mcdi->mode);
if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) {
netif_err(efx, hw, efx->net_dev,
"MCDI request was completed without an event\n");
rc = 0;
}
/* Close the race with efx_mcdi_ev_cpl() executing just too late /* Close the race with efx_mcdi_ev_cpl() executing just too late
* and completing a request we've just cancelled, by ensuring * and completing a request we've just cancelled, by ensuring
* that the seqno check therein fails. * that the seqno check therein fails.
...@@ -638,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, ...@@ -638,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen,
++mcdi->seqno; ++mcdi->seqno;
++mcdi->credits; ++mcdi->credits;
spin_unlock_bh(&mcdi->iface_lock); spin_unlock_bh(&mcdi->iface_lock);
}
netif_err(efx, hw, efx->net_dev, if (rc == 0) {
"MC command 0x%x inlen %d mode %d timed out\n",
cmd, (int)inlen, mcdi->mode);
} else {
size_t hdr_len, data_len; size_t hdr_len, data_len;
/* At the very least we need a memory barrier here to ensure /* At the very least we need a memory barrier here to ensure
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment