MC reboot may be provoked by the other function which is either starting in parallel or, for example, reconfiguring UDP tunnel ports.
Signed-off-by: Andrew Rybchenko <arybche...@solarflare.com> Reviewed-by: Andy Moreton <amore...@solarflare.com> Reviewed-by: Ivan Malov <ivan.ma...@oktetlabs.ru> --- drivers/net/sfc/sfc.c | 59 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 0dcfdd8..1ca123a 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -271,27 +271,15 @@ sfc_set_drv_limits(struct sfc_adapter *sa) return efx_nic_set_drv_limits(sa->nic, &lim); } -int -sfc_start(struct sfc_adapter *sa) +static int +sfc_try_start(struct sfc_adapter *sa) { int rc; sfc_log_init(sa, "entry"); SFC_ASSERT(sfc_adapter_is_locked(sa)); - - switch (sa->state) { - case SFC_ADAPTER_CONFIGURED: - break; - case SFC_ADAPTER_STARTED: - sfc_info(sa, "already started"); - return 0; - default: - rc = EINVAL; - goto fail_bad_state; - } - - sa->state = SFC_ADAPTER_STARTING; + SFC_ASSERT(sa->state == SFC_ADAPTER_STARTING); sfc_log_init(sa, "set resource limits"); rc = sfc_set_drv_limits(sa); @@ -327,7 +315,6 @@ sfc_start(struct sfc_adapter *sa) if (rc != 0) goto fail_flows_insert; - sa->state = SFC_ADAPTER_STARTED; sfc_log_init(sa, "done"); return 0; @@ -351,6 +338,46 @@ sfc_start(struct sfc_adapter *sa) fail_nic_init: fail_set_drv_limits: + sfc_log_init(sa, "failed %d", rc); + return rc; +} + +int +sfc_start(struct sfc_adapter *sa) +{ + unsigned int start_tries = 3; + int rc; + + sfc_log_init(sa, "entry"); + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + switch (sa->state) { + case SFC_ADAPTER_CONFIGURED: + break; + case SFC_ADAPTER_STARTED: + sfc_info(sa, "already started"); + return 0; + default: + rc = EINVAL; + goto fail_bad_state; + } + + sa->state = SFC_ADAPTER_STARTING; + + do { + rc = sfc_try_start(sa); + } while ((--start_tries > 0) && + (rc == EIO || rc == EAGAIN || rc == ENOENT || rc == EINVAL)); + + if (rc != 0) + goto fail_try_start; + + sa->state = SFC_ADAPTER_STARTED; + sfc_log_init(sa, "done"); + return 0; + +fail_try_start: sa->state = SFC_ADAPTER_CONFIGURED; fail_bad_state: sfc_log_init(sa, "failed %d", rc); -- 2.7.4