From dfdaa95c7abc3dc7acf44b0c4aeac4c3c44966d6 Mon Sep 17 00:00:00 2001 From: Daniel Pieczko Date: Wed, 18 Sep 2013 10:16:24 +0100 Subject: [PATCH 1/2] sfc: Wait for MC reboot to complete before scheduling driver reset Scheduling a reset following an MC reboot event before waiting for reboot to complete results in a race that can lead to a state where must_realloc_vis is false in efx_ef10_fini_dmaq() but the VIs have been destroyed during the MC reboot. To avoid MC errors when trying to remove VIs that do not exist, wait for the MC reboot to complete before scheduling the reset. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 128d7cdf9eb2..73143ece4832 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -800,9 +800,6 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) } else { int count; - /* Nobody was waiting for an MCDI request, so trigger a reset */ - efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); - /* Consume the status word since efx_mcdi_rpc_finish() won't */ for (count = 0; count < MCDI_STATUS_DELAY_COUNT; ++count) { if (efx_mcdi_poll_reboot(efx)) @@ -810,6 +807,9 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) udelay(MCDI_STATUS_DELAY_US); } mcdi->new_epoch = true; + + /* Nobody was waiting for an MCDI request, so trigger a reset */ + efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); } spin_unlock(&mcdi->iface_lock); From b2d32f03e67cc9b0ad16fc1fff87edf90f059883 Mon Sep 17 00:00:00 2001 From: Daniel Pieczko Date: Fri, 20 Sep 2013 16:45:10 +0100 Subject: [PATCH 2/2] sfc: Increase MCDI status timeout to 250ms The SFC9120 MC firmware often takes longer than 20ms to reboot and update the warm boot count in BIU_MC_SFT_STATUS_REG. A timeout of 250ms is very generous for an MC reboot. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 73143ece4832..c082562dbf4e 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -27,10 +27,10 @@ /* A reboot/assertion causes the MCDI status word to be set after the * command word is set or a REBOOT event is sent. If we notice a reboot - * via these mechanisms then wait 20ms for the status word to be set. + * via these mechanisms then wait 250ms for the status word to be set. */ #define MCDI_STATUS_DELAY_US 100 -#define MCDI_STATUS_DELAY_COUNT 200 +#define MCDI_STATUS_DELAY_COUNT 2500 #define MCDI_STATUS_SLEEP_MS \ (MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000)