From 4625c4f5277d16b0a9ad0a6a193f7f4818f110e8 Mon Sep 17 00:00:00 2001 From: Gautam Dawar Date: Mon, 10 Jun 2019 08:38:37 +0100 Subject: [PATCH] net/sfc/base: factor out upstream port vAdaptor allocation Separate out vAdaptor allocation from ef10_nic_init() as it is not required for SR-IOV use case. In case of SR-IOV, vAdaptor is allocated early along with vSwitch creation and vPort configuration. Signed-off-by: Gautam Dawar Signed-off-by: Andrew Rybchenko --- drivers/net/sfc/base/ef10_nic.c | 110 +++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 38 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index 7eada57a10..0cf9ddde74 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -2220,6 +2220,58 @@ fail1: return (rc); } +static __checkReturn efx_rc_t +ef10_upstream_port_vadaptor_alloc( + __in efx_nic_t *enp) +{ + uint32_t retry; + uint32_t delay_us; + efx_rc_t rc; + + /* + * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF + * driver has yet to bring up the EVB port. See bug 56147. In this case, + * retry the request several times after waiting a while. The wait time + * between retries starts small (10ms) and exponentially increases. + * Total wait time is a little over two seconds. Retry logic in the + * client driver may mean this whole loop is repeated if it continues to + * fail. + */ + retry = 0; + delay_us = 10000; + while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { + if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || + (rc != ENOENT)) { + /* + * Do not retry alloc for PF, or for other errors on + * a VF. + */ + goto fail1; + } + + /* VF startup before PF is ready. Retry allocation. */ + if (retry > 5) { + /* Too many attempts */ + rc = EINVAL; + goto fail2; + } + EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); + EFSYS_SLEEP(delay_us); + retry++; + if (delay_us < 500000) + delay_us <<= 2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + __checkReturn efx_rc_t ef10_nic_init( __in efx_nic_t *enp) @@ -2228,12 +2280,13 @@ ef10_nic_init( uint32_t min_vi_count, max_vi_count; uint32_t vi_count, vi_base, vi_shift; uint32_t i; - uint32_t retry; - uint32_t delay_us; uint32_t vi_window_size; efx_rc_t rc; + boolean_t alloc_vadaptor = B_TRUE; - EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); + EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || + enp->en_family == EFX_FAMILY_MEDFORD || + enp->en_family == EFX_FAMILY_MEDFORD2); /* Enable reporting of some events (e.g. link change) */ if ((rc = efx_mcdi_log_ctrl(enp)) != 0) @@ -2330,48 +2383,29 @@ ef10_nic_init( } /* - * Allocate a vAdaptor attached to our upstream vPort/pPort. - * - * On a VF, this may fail with MC_CMD_ERR_NO_EVB_PORT (ENOENT) if the PF - * driver has yet to bring up the EVB port. See bug 56147. In this case, - * retry the request several times after waiting a while. The wait time - * between retries starts small (10ms) and exponentially increases. - * Total wait time is a little over two seconds. Retry logic in the - * client driver may mean this whole loop is repeated if it continues to - * fail. + * For SR-IOV use case, vAdaptor is allocated for PF and associated VFs + * during NIC initialization when vSwitch is created and vports are + * allocated. Hence, skip vAdaptor allocation for EVB and update vport + * id in NIC structure with the one allocated for PF. */ - retry = 0; - delay_us = 10000; - while ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0) { - if (EFX_PCI_FUNCTION_IS_PF(&enp->en_nic_cfg) || - (rc != ENOENT)) { - /* - * Do not retry alloc for PF, or for other errors on - * a VF. - */ - goto fail5; - } - - /* VF startup before PF is ready. Retry allocation. */ - if (retry > 5) { - /* Too many attempts */ - rc = EINVAL; - goto fail6; - } - EFSYS_PROBE1(mcdi_no_evb_port_retry, int, retry); - EFSYS_SLEEP(delay_us); - retry++; - if (delay_us < 500000) - delay_us <<= 2; - } enp->en_vport_id = EVB_PORT_ID_ASSIGNED; +#if EFSYS_OPT_EVB + if ((enp->en_vswitchp != NULL) && (enp->en_vswitchp->ev_evcp != NULL)) { + /* For EVB use vport allocated on vswitch */ + enp->en_vport_id = enp->en_vswitchp->ev_evcp->evc_vport_id; + alloc_vadaptor = B_FALSE; + } +#endif + if (alloc_vadaptor != B_FALSE) { + /* Allocate a vAdaptor attached to our upstream vPort/pPort */ + if ((rc = ef10_upstream_port_vadaptor_alloc(enp)) != 0) + goto fail5; + } enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2; return (0); -fail6: - EFSYS_PROBE(fail6); fail5: EFSYS_PROBE(fail5); fail4: -- 2.20.1