X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fsfc%2Fsfc.c;h=59e535d71635f48568eb32bcb138f823ffa2c9fa;hb=ca01bc1ab73b9f85e8344b1313b753a0a4365f1e;hp=cc81fd9988c6aebc33cbe28798e7c3648ce324cf;hpb=37a42c61c415a6cf3202f2a9cd689be1e9edd0da;p=dpdk.git diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index cc81fd9988..59e535d716 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -33,6 +33,7 @@ #include #include +#include #include "efx.h" @@ -61,8 +62,8 @@ sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id, return ENOMEM; } - esmp->esm_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr); - if (esmp->esm_addr == RTE_BAD_PHYS_ADDR) { + esmp->esm_addr = mz->iova; + if (esmp->esm_addr == RTE_BAD_IOVA) { (void)rte_memzone_free(mz); return EFAULT; } @@ -270,27 +271,16 @@ 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) { + const efx_nic_cfg_t *encp; 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); @@ -302,6 +292,14 @@ sfc_start(struct sfc_adapter *sa) if (rc != 0) goto fail_nic_init; + encp = efx_nic_cfg_get(sa->nic); + if (encp->enc_tunnel_encapsulations_supported != 0) { + sfc_log_init(sa, "apply tunnel config"); + rc = efx_tunnel_reconfigure(sa->nic); + if (rc != 0) + goto fail_tunnel_reconfigure; + } + rc = sfc_intr_start(sa); if (rc != 0) goto fail_intr_start; @@ -326,7 +324,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; @@ -346,10 +343,51 @@ fail_ev_start: sfc_intr_stop(sa); fail_intr_start: +fail_tunnel_reconfigure: efx_nic_fini(sa->nic); 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); @@ -389,6 +427,58 @@ sfc_stop(struct sfc_adapter *sa) sfc_log_init(sa, "done"); } +static int +sfc_restart(struct sfc_adapter *sa) +{ + int rc; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + if (sa->state != SFC_ADAPTER_STARTED) + return EINVAL; + + sfc_stop(sa); + + rc = sfc_start(sa); + if (rc != 0) + sfc_err(sa, "restart failed"); + + return rc; +} + +static void +sfc_restart_if_required(void *arg) +{ + struct sfc_adapter *sa = arg; + + /* If restart is scheduled, clear the flag and do it */ + if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required, + 1, 0)) { + sfc_adapter_lock(sa); + if (sa->state == SFC_ADAPTER_STARTED) + (void)sfc_restart(sa); + sfc_adapter_unlock(sa); + } +} + +void +sfc_schedule_restart(struct sfc_adapter *sa) +{ + int rc; + + /* Schedule restart alarm if it is not scheduled yet */ + if (!rte_atomic32_test_and_set(&sa->restart_required)) + return; + + rc = rte_eal_alarm_set(1, sfc_restart_if_required, sa); + if (rc == -ENOTSUP) + sfc_warn(sa, "alarms are not supported, restart is pending"); + else if (rc != 0) + sfc_err(sa, "cannot arm restart alarm (rc=%d)", rc); + else + sfc_info(sa, "restart scheduled"); +} + int sfc_configure(struct sfc_adapter *sa) { @@ -583,6 +673,16 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_nic_reset; + /* + * Probed NIC is sufficient for tunnel init. + * Initialize tunnel support to be able to use libefx + * efx_tunnel_config_udp_{add,remove}() in any state and + * efx_tunnel_reconfigure() on start up. + */ + rc = efx_tunnel_init(enp); + if (rc != 0) + goto fail_tunnel_init; + encp = efx_nic_cfg_get(sa->nic); if (sa->dp_tx->features & SFC_DP_TX_FEAT_TSO) { @@ -644,6 +744,9 @@ fail_intr_attach: efx_nic_fini(sa->nic); fail_estimate_rsrc_limits: +fail_tunnel_init: + efx_tunnel_fini(sa->nic); + fail_nic_reset: sfc_log_init(sa, "failed %d", rc); @@ -663,6 +766,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_port_detach(sa); sfc_ev_detach(sa); sfc_intr_detach(sa); + efx_tunnel_fini(sa->nic); sa->state = SFC_ADAPTER_UNINITIALIZED; } @@ -679,6 +783,7 @@ sfc_probe(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); sa->socket_id = rte_socket_id(); + rte_atomic32_init(&sa->restart_required); sfc_log_init(sa, "init mem bar"); rc = sfc_mem_bar_init(sa); @@ -743,6 +848,14 @@ sfc_unprobe(struct sfc_adapter *sa) sfc_mcdi_fini(sa); + /* + * Make sure there is no pending alarm to restart since we are + * going to free device private which is passed as the callback + * opaque data. A new alarm cannot be scheduled since MCDI is + * shut down. + */ + rte_eal_alarm_cancel(sfc_restart_if_required, sa); + sfc_log_init(sa, "destroy nic"); sa->nic = NULL; efx_nic_destroy(enp);