LCOV - code coverage report
Current view: top level - drivers/net/sfc - sfc.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 678 0.0 %
Date: 2025-03-01 20:23:48 Functions: 0 31 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 289 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *
       3                 :            :  * Copyright(c) 2019-2021 Xilinx, Inc.
       4                 :            :  * Copyright(c) 2016-2019 Solarflare Communications Inc.
       5                 :            :  *
       6                 :            :  * This software was jointly developed between OKTET Labs (under contract
       7                 :            :  * for Solarflare) and Solarflare Communications, Inc.
       8                 :            :  */
       9                 :            : 
      10                 :            : /* sysconf() */
      11                 :            : #include <unistd.h>
      12                 :            : 
      13                 :            : #include <rte_errno.h>
      14                 :            : #include <rte_alarm.h>
      15                 :            : 
      16                 :            : #include "efx.h"
      17                 :            : 
      18                 :            : #include "sfc.h"
      19                 :            : #include "sfc_debug.h"
      20                 :            : #include "sfc_log.h"
      21                 :            : #include "sfc_ev.h"
      22                 :            : #include "sfc_rx.h"
      23                 :            : #include "sfc_mae_counter.h"
      24                 :            : #include "sfc_tx.h"
      25                 :            : #include "sfc_kvargs.h"
      26                 :            : #include "sfc_tweak.h"
      27                 :            : #include "sfc_sw_stats.h"
      28                 :            : #include "sfc_switch.h"
      29                 :            : #include "sfc_nic_dma.h"
      30                 :            : 
      31                 :            : bool
      32                 :          0 : sfc_repr_supported(const struct sfc_adapter *sa)
      33                 :            : {
      34         [ #  # ]:          0 :         if (!sa->switchdev)
      35                 :            :                 return false;
      36                 :            : 
      37                 :            :         /*
      38                 :            :          * Representor proxy should use service lcore on PF's socket
      39                 :            :          * (sa->socket_id) to be efficient. But the proxy will fall back
      40                 :            :          * to any socket if it is not possible to get the service core
      41                 :            :          * on the same socket. Check that at least service core on any
      42                 :            :          * socket is available.
      43                 :            :          */
      44         [ #  # ]:          0 :         if (sfc_get_service_lcore(SOCKET_ID_ANY) == RTE_MAX_LCORE)
      45                 :          0 :                 return false;
      46                 :            : 
      47                 :            :         return true;
      48                 :            : }
      49                 :            : 
      50                 :            : bool
      51                 :          0 : sfc_repr_available(const struct sfc_adapter_shared *sas)
      52                 :            : {
      53   [ #  #  #  # ]:          0 :         return sas->nb_repr_rxq > 0 && sas->nb_repr_txq > 0;
      54                 :            : }
      55                 :            : 
      56                 :            : int
      57                 :          0 : sfc_dma_alloc(struct sfc_adapter *sa, const char *name, uint16_t id,
      58                 :            :               efx_nic_dma_addr_type_t addr_type, size_t len, int socket_id,
      59                 :            :               efsys_mem_t *esmp)
      60                 :            : {
      61                 :            :         const struct rte_memzone *mz;
      62                 :            :         int rc;
      63                 :            : 
      64                 :          0 :         sfc_log_init(sa, "name=%s id=%u len=%zu socket_id=%d",
      65                 :            :                      name, id, len, socket_id);
      66                 :            : 
      67                 :          0 :         mz = rte_eth_dma_zone_reserve(sa->eth_dev, name, id, len,
      68                 :          0 :                                       sysconf(_SC_PAGESIZE), socket_id);
      69         [ #  # ]:          0 :         if (mz == NULL) {
      70                 :          0 :                 sfc_err(sa, "cannot reserve DMA zone for %s:%u %#x@%d: %s",
      71                 :            :                         name, (unsigned int)id, (unsigned int)len, socket_id,
      72                 :            :                         rte_strerror(rte_errno));
      73                 :          0 :                 return ENOMEM;
      74                 :            :         }
      75         [ #  # ]:          0 :         if (mz->iova == RTE_BAD_IOVA) {
      76                 :          0 :                 (void)rte_memzone_free(mz);
      77                 :          0 :                 return EFAULT;
      78                 :            :         }
      79                 :            : 
      80                 :          0 :         rc = sfc_nic_dma_mz_map(sa, mz, addr_type, &esmp->esm_addr);
      81         [ #  # ]:          0 :         if (rc != 0) {
      82                 :          0 :                 (void)rte_memzone_free(mz);
      83                 :          0 :                 return rc;
      84                 :            :         }
      85                 :            : 
      86                 :          0 :         esmp->esm_mz = mz;
      87                 :          0 :         esmp->esm_base = mz->addr;
      88                 :            : 
      89                 :          0 :         sfc_info(sa,
      90                 :            :                  "DMA name=%s id=%u len=%lu socket_id=%d => virt=%p iova=%lx",
      91                 :            :                  name, id, len, socket_id, esmp->esm_base,
      92                 :            :                  (unsigned long)esmp->esm_addr);
      93                 :            : 
      94                 :          0 :         return 0;
      95                 :            : }
      96                 :            : 
      97                 :            : void
      98                 :          0 : sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp)
      99                 :            : {
     100                 :            :         int rc;
     101                 :            : 
     102                 :          0 :         sfc_log_init(sa, "name=%s", esmp->esm_mz->name);
     103                 :            : 
     104                 :          0 :         rc = rte_memzone_free(esmp->esm_mz);
     105         [ #  # ]:          0 :         if (rc != 0)
     106                 :          0 :                 sfc_err(sa, "rte_memzone_free(() failed: %d", rc);
     107                 :            : 
     108                 :            :         memset(esmp, 0, sizeof(*esmp));
     109                 :          0 : }
     110                 :            : 
     111                 :            : static uint32_t
     112                 :          0 : sfc_phy_cap_from_link_speeds(uint32_t speeds)
     113                 :            : {
     114                 :            :         uint32_t phy_caps = 0;
     115                 :            : 
     116         [ #  # ]:          0 :         if (~speeds & RTE_ETH_LINK_SPEED_FIXED) {
     117                 :            :                 phy_caps |= (1 << EFX_PHY_CAP_AN);
     118                 :            :                 /*
     119                 :            :                  * If no speeds are specified in the mask, any supported
     120                 :            :                  * may be negotiated
     121                 :            :                  */
     122         [ #  # ]:          0 :                 if (speeds == RTE_ETH_LINK_SPEED_AUTONEG)
     123                 :            :                         phy_caps |=
     124                 :            :                                 (1 << EFX_PHY_CAP_1000FDX) |
     125                 :            :                                 (1 << EFX_PHY_CAP_10000FDX) |
     126                 :            :                                 (1 << EFX_PHY_CAP_25000FDX) |
     127                 :            :                                 (1 << EFX_PHY_CAP_40000FDX) |
     128                 :            :                                 (1 << EFX_PHY_CAP_50000FDX) |
     129                 :            :                                 (1 << EFX_PHY_CAP_100000FDX);
     130                 :            :         }
     131         [ #  # ]:          0 :         if (speeds & RTE_ETH_LINK_SPEED_1G)
     132                 :          0 :                 phy_caps |= (1 << EFX_PHY_CAP_1000FDX);
     133         [ #  # ]:          0 :         if (speeds & RTE_ETH_LINK_SPEED_10G)
     134                 :          0 :                 phy_caps |= (1 << EFX_PHY_CAP_10000FDX);
     135         [ #  # ]:          0 :         if (speeds & RTE_ETH_LINK_SPEED_25G)
     136                 :          0 :                 phy_caps |= (1 << EFX_PHY_CAP_25000FDX);
     137         [ #  # ]:          0 :         if (speeds & RTE_ETH_LINK_SPEED_40G)
     138                 :          0 :                 phy_caps |= (1 << EFX_PHY_CAP_40000FDX);
     139         [ #  # ]:          0 :         if (speeds & RTE_ETH_LINK_SPEED_50G)
     140                 :          0 :                 phy_caps |= (1 << EFX_PHY_CAP_50000FDX);
     141         [ #  # ]:          0 :         if (speeds & RTE_ETH_LINK_SPEED_100G)
     142                 :          0 :                 phy_caps |= (1 << EFX_PHY_CAP_100000FDX);
     143                 :            : 
     144                 :          0 :         return phy_caps;
     145                 :            : }
     146                 :            : 
     147                 :            : /*
     148                 :            :  * Check requested device level configuration.
     149                 :            :  * Receive and transmit configuration is checked in corresponding
     150                 :            :  * modules.
     151                 :            :  */
     152                 :            : static int
     153                 :          0 : sfc_check_conf(struct sfc_adapter *sa)
     154                 :            : {
     155                 :          0 :         const struct rte_eth_conf *conf = &sa->eth_dev->data->dev_conf;
     156                 :            :         int rc = 0;
     157                 :            : 
     158                 :          0 :         sa->port.phy_adv_cap =
     159                 :          0 :                 sfc_phy_cap_from_link_speeds(conf->link_speeds) &
     160                 :          0 :                 sa->port.phy_adv_cap_mask;
     161         [ #  # ]:          0 :         if ((sa->port.phy_adv_cap & ~(1 << EFX_PHY_CAP_AN)) == 0) {
     162                 :          0 :                 sfc_err(sa, "No link speeds from mask %#x are supported",
     163                 :            :                         conf->link_speeds);
     164                 :            :                 rc = EINVAL;
     165                 :            :         }
     166                 :            : 
     167                 :            : #if !EFSYS_OPT_LOOPBACK
     168                 :            :         if (conf->lpbk_mode != 0) {
     169                 :            :                 sfc_err(sa, "Loopback not supported");
     170                 :            :                 rc = EINVAL;
     171                 :            :         }
     172                 :            : #endif
     173                 :            : 
     174         [ #  # ]:          0 :         if (conf->dcb_capability_en != 0) {
     175                 :          0 :                 sfc_err(sa, "Priority-based flow control not supported");
     176                 :            :                 rc = EINVAL;
     177                 :            :         }
     178                 :            : 
     179         [ #  # ]:          0 :         if ((conf->intr_conf.lsc != 0) &&
     180   [ #  #  #  # ]:          0 :             (sa->intr.type != EFX_INTR_LINE) &&
     181                 :            :             (sa->intr.type != EFX_INTR_MESSAGE)) {
     182                 :          0 :                 sfc_err(sa, "Link status change interrupt not supported");
     183                 :            :                 rc = EINVAL;
     184                 :            :         }
     185                 :            : 
     186         [ #  # ]:          0 :         if (conf->intr_conf.rxq != 0 &&
     187         [ #  # ]:          0 :             (sa->priv.dp_rx->features & SFC_DP_RX_FEAT_INTR) == 0) {
     188                 :          0 :                 sfc_err(sa, "Receive queue interrupt not supported");
     189                 :            :                 rc = EINVAL;
     190                 :            :         }
     191                 :            : 
     192                 :          0 :         return rc;
     193                 :            : }
     194                 :            : 
     195                 :            : /*
     196                 :            :  * Find out maximum number of receive and transmit queues which could be
     197                 :            :  * advertised.
     198                 :            :  *
     199                 :            :  * NIC is kept initialized on success to allow other modules acquire
     200                 :            :  * defaults and capabilities.
     201                 :            :  */
     202                 :            : static int
     203                 :          0 : sfc_estimate_resource_limits(struct sfc_adapter *sa)
     204                 :            : {
     205                 :          0 :         const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
     206                 :            :         struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
     207                 :            :         efx_drv_limits_t limits;
     208                 :            :         int rc;
     209                 :            :         uint32_t evq_allocated;
     210                 :            :         uint32_t rxq_allocated;
     211                 :            :         uint32_t txq_allocated;
     212                 :            : 
     213                 :            :         memset(&limits, 0, sizeof(limits));
     214                 :            : 
     215                 :            :         /* Request at least one Rx and Tx queue */
     216                 :          0 :         limits.edl_min_rxq_count = 1;
     217                 :          0 :         limits.edl_min_txq_count = 1;
     218                 :            :         /* Management event queue plus event queue for each Tx and Rx queue */
     219                 :          0 :         limits.edl_min_evq_count =
     220                 :            :                 1 + limits.edl_min_rxq_count + limits.edl_min_txq_count;
     221                 :            : 
     222                 :            :         /* Divide by number of functions to guarantee that all functions
     223                 :            :          * will get promised resources
     224                 :            :          */
     225                 :            :         /* FIXME Divide by number of functions (not 2) below */
     226                 :          0 :         limits.edl_max_evq_count = encp->enc_evq_limit / 2;
     227                 :            :         SFC_ASSERT(limits.edl_max_evq_count >= limits.edl_min_rxq_count);
     228                 :            : 
     229                 :            :         /* Split equally between receive and transmit */
     230                 :          0 :         limits.edl_max_rxq_count =
     231                 :          0 :                 MIN(encp->enc_rxq_limit, (limits.edl_max_evq_count - 1) / 2);
     232                 :            :         SFC_ASSERT(limits.edl_max_rxq_count >= limits.edl_min_rxq_count);
     233                 :            : 
     234                 :          0 :         limits.edl_max_txq_count =
     235                 :          0 :                 MIN(encp->enc_txq_limit,
     236                 :            :                     limits.edl_max_evq_count - 1 - limits.edl_max_rxq_count);
     237                 :            : 
     238   [ #  #  #  # ]:          0 :         if (sa->tso && encp->enc_fw_assisted_tso_v2_enabled)
     239                 :          0 :                 limits.edl_max_txq_count =
     240                 :          0 :                         MIN(limits.edl_max_txq_count,
     241                 :            :                             encp->enc_fw_assisted_tso_v2_n_contexts /
     242                 :            :                             encp->enc_hw_pf_count);
     243                 :            : 
     244                 :            :         SFC_ASSERT(limits.edl_max_txq_count >= limits.edl_min_rxq_count);
     245                 :            : 
     246                 :            :         /* Configure the minimum required resources needed for the
     247                 :            :          * driver to operate, and the maximum desired resources that the
     248                 :            :          * driver is capable of using.
     249                 :            :          */
     250                 :          0 :         efx_nic_set_drv_limits(sa->nic, &limits);
     251                 :            : 
     252                 :          0 :         sfc_log_init(sa, "init nic");
     253                 :          0 :         rc = efx_nic_init(sa->nic);
     254         [ #  # ]:          0 :         if (rc != 0)
     255                 :          0 :                 goto fail_nic_init;
     256                 :            : 
     257                 :            :         /* Find resource dimensions assigned by firmware to this function */
     258                 :          0 :         rc = efx_nic_get_vi_pool(sa->nic, &evq_allocated, &rxq_allocated,
     259                 :            :                                  &txq_allocated);
     260         [ #  # ]:          0 :         if (rc != 0)
     261                 :          0 :                 goto fail_get_vi_pool;
     262                 :            : 
     263                 :            :         /* It still may allocate more than maximum, ensure limit */
     264                 :          0 :         evq_allocated = MIN(evq_allocated, limits.edl_max_evq_count);
     265                 :          0 :         rxq_allocated = MIN(rxq_allocated, limits.edl_max_rxq_count);
     266                 :          0 :         txq_allocated = MIN(txq_allocated, limits.edl_max_txq_count);
     267                 :            : 
     268                 :            :         /*
     269                 :            :          * Subtract management EVQ not used for traffic
     270                 :            :          * The resource allocation strategy is as follows:
     271                 :            :          * - one EVQ for management
     272                 :            :          * - one EVQ for each ethdev RXQ
     273                 :            :          * - one EVQ for each ethdev TXQ
     274                 :            :          * - one EVQ and one RXQ for optional MAE counters.
     275                 :            :          */
     276         [ #  # ]:          0 :         if (evq_allocated == 0) {
     277                 :          0 :                 sfc_err(sa, "count of allocated EvQ is 0");
     278                 :            :                 rc = ENOMEM;
     279                 :          0 :                 goto fail_allocate_evq;
     280                 :            :         }
     281                 :          0 :         evq_allocated--;
     282                 :            : 
     283                 :            :         /*
     284                 :            :          * Reserve absolutely required minimum.
     285                 :            :          * Right now we use separate EVQ for Rx and Tx.
     286                 :            :          */
     287   [ #  #  #  # ]:          0 :         if (rxq_allocated > 0 && evq_allocated > 0) {
     288                 :          0 :                 sa->rxq_max = 1;
     289                 :          0 :                 rxq_allocated--;
     290                 :          0 :                 evq_allocated--;
     291                 :            :         }
     292   [ #  #  #  # ]:          0 :         if (txq_allocated > 0 && evq_allocated > 0) {
     293                 :          0 :                 sa->txq_max = 1;
     294                 :          0 :                 txq_allocated--;
     295                 :          0 :                 evq_allocated--;
     296                 :            :         }
     297                 :            : 
     298         [ #  # ]:          0 :         if (sfc_mae_counter_rxq_required(sa) &&
     299   [ #  #  #  # ]:          0 :             rxq_allocated > 0 && evq_allocated > 0) {
     300                 :          0 :                 rxq_allocated--;
     301                 :          0 :                 evq_allocated--;
     302                 :          0 :                 sas->counters_rxq_allocated = true;
     303                 :            :         } else {
     304                 :          0 :                 sas->counters_rxq_allocated = false;
     305                 :            :         }
     306                 :            : 
     307         [ #  # ]:          0 :         if (sfc_repr_supported(sa) &&
     308         [ #  # ]:          0 :             evq_allocated >= SFC_REPR_PROXY_NB_RXQ_MIN +
     309                 :          0 :             SFC_REPR_PROXY_NB_TXQ_MIN &&
     310         [ #  # ]:          0 :             rxq_allocated >= SFC_REPR_PROXY_NB_RXQ_MIN &&
     311         [ #  # ]:          0 :             txq_allocated >= SFC_REPR_PROXY_NB_TXQ_MIN) {
     312                 :            :                 unsigned int extra;
     313                 :            : 
     314                 :          0 :                 txq_allocated -= SFC_REPR_PROXY_NB_TXQ_MIN;
     315                 :          0 :                 rxq_allocated -= SFC_REPR_PROXY_NB_RXQ_MIN;
     316                 :          0 :                 evq_allocated -= SFC_REPR_PROXY_NB_RXQ_MIN +
     317                 :            :                         SFC_REPR_PROXY_NB_TXQ_MIN;
     318                 :            : 
     319                 :          0 :                 sas->nb_repr_rxq = SFC_REPR_PROXY_NB_RXQ_MIN;
     320                 :          0 :                 sas->nb_repr_txq = SFC_REPR_PROXY_NB_TXQ_MIN;
     321                 :            : 
     322                 :            :                 /* Allocate extra representor RxQs up to the maximum */
     323                 :            :                 extra = MIN(evq_allocated, rxq_allocated);
     324                 :            :                 extra = MIN(extra,
     325                 :            :                             SFC_REPR_PROXY_NB_RXQ_MAX - sas->nb_repr_rxq);
     326                 :            :                 evq_allocated -= extra;
     327                 :            :                 rxq_allocated -= extra;
     328                 :            :                 sas->nb_repr_rxq += extra;
     329                 :            : 
     330                 :            :                 /* Allocate extra representor TxQs up to the maximum */
     331                 :            :                 extra = MIN(evq_allocated, txq_allocated);
     332                 :            :                 extra = MIN(extra,
     333                 :            :                             SFC_REPR_PROXY_NB_TXQ_MAX - sas->nb_repr_txq);
     334                 :            :                 evq_allocated -= extra;
     335                 :            :                 txq_allocated -= extra;
     336                 :            :                 sas->nb_repr_txq += extra;
     337                 :            :         } else {
     338                 :          0 :                 sas->nb_repr_rxq = 0;
     339                 :          0 :                 sas->nb_repr_txq = 0;
     340                 :            :         }
     341                 :            : 
     342                 :            :         /* Add remaining allocated queues */
     343                 :          0 :         sa->rxq_max += MIN(rxq_allocated, evq_allocated / 2);
     344                 :          0 :         sa->txq_max += MIN(txq_allocated, evq_allocated - sa->rxq_max);
     345                 :            : 
     346                 :            :         /* Keep NIC initialized */
     347                 :          0 :         return 0;
     348                 :            : 
     349                 :            : fail_allocate_evq:
     350                 :          0 : fail_get_vi_pool:
     351                 :          0 :         efx_nic_fini(sa->nic);
     352                 :            : fail_nic_init:
     353                 :            :         return rc;
     354                 :            : }
     355                 :            : 
     356                 :            : static int
     357                 :          0 : sfc_set_drv_limits(struct sfc_adapter *sa)
     358                 :            : {
     359                 :            :         struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
     360                 :          0 :         const struct rte_eth_dev_data *data = sa->eth_dev->data;
     361                 :            :         uint32_t rxq_reserved = sfc_nb_reserved_rxq(sas);
     362                 :            :         uint32_t txq_reserved = sfc_nb_txq_reserved(sas);
     363                 :            :         efx_drv_limits_t lim;
     364                 :            : 
     365                 :            :         memset(&lim, 0, sizeof(lim));
     366                 :            : 
     367                 :            :         /*
     368                 :            :          * Limits are strict since take into account initial estimation.
     369                 :            :          * Resource allocation strategy is described in
     370                 :            :          * sfc_estimate_resource_limits().
     371                 :            :          */
     372                 :          0 :         lim.edl_min_evq_count = lim.edl_max_evq_count =
     373                 :          0 :                 1 + data->nb_rx_queues + data->nb_tx_queues +
     374                 :          0 :                 rxq_reserved + txq_reserved;
     375                 :          0 :         lim.edl_min_rxq_count = lim.edl_max_rxq_count =
     376                 :          0 :                 data->nb_rx_queues + rxq_reserved;
     377                 :          0 :         lim.edl_min_txq_count = lim.edl_max_txq_count =
     378                 :          0 :                 data->nb_tx_queues + txq_reserved;
     379                 :            : 
     380                 :          0 :         return efx_nic_set_drv_limits(sa->nic, &lim);
     381                 :            : }
     382                 :            : 
     383                 :            : static int
     384                 :          0 : sfc_set_fw_subvariant(struct sfc_adapter *sa)
     385                 :            : {
     386                 :            :         struct sfc_adapter_shared *sas = sfc_sa2shared(sa);
     387                 :          0 :         const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
     388                 :          0 :         uint64_t tx_offloads = sa->eth_dev->data->dev_conf.txmode.offloads;
     389                 :            :         unsigned int txq_index;
     390                 :            :         efx_nic_fw_subvariant_t req_fw_subvariant;
     391                 :            :         efx_nic_fw_subvariant_t cur_fw_subvariant;
     392                 :            :         int rc;
     393                 :            : 
     394         [ #  # ]:          0 :         if (!encp->enc_fw_subvariant_no_tx_csum_supported) {
     395                 :          0 :                 sfc_info(sa, "no-Tx-checksum subvariant not supported");
     396                 :          0 :                 return 0;
     397                 :            :         }
     398                 :            : 
     399         [ #  # ]:          0 :         for (txq_index = 0; txq_index < sas->txq_count; ++txq_index) {
     400                 :          0 :                 struct sfc_txq_info *txq_info = &sas->txq_info[txq_index];
     401                 :            : 
     402         [ #  # ]:          0 :                 if (txq_info->state & SFC_TXQ_INITIALIZED)
     403                 :          0 :                         tx_offloads |= txq_info->offloads;
     404                 :            :         }
     405                 :            : 
     406         [ #  # ]:          0 :         if (tx_offloads & (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
     407                 :            :                            RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
     408                 :            :                            RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
     409                 :            :                            RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM))
     410                 :            :                 req_fw_subvariant = EFX_NIC_FW_SUBVARIANT_DEFAULT;
     411                 :            :         else
     412                 :            :                 req_fw_subvariant = EFX_NIC_FW_SUBVARIANT_NO_TX_CSUM;
     413                 :            : 
     414                 :          0 :         rc = efx_nic_get_fw_subvariant(sa->nic, &cur_fw_subvariant);
     415         [ #  # ]:          0 :         if (rc != 0) {
     416                 :          0 :                 sfc_err(sa, "failed to get FW subvariant: %d", rc);
     417                 :          0 :                 return rc;
     418                 :            :         }
     419                 :          0 :         sfc_info(sa, "FW subvariant is %u vs required %u",
     420                 :            :                  cur_fw_subvariant, req_fw_subvariant);
     421                 :            : 
     422         [ #  # ]:          0 :         if (cur_fw_subvariant == req_fw_subvariant)
     423                 :            :                 return 0;
     424                 :            : 
     425                 :          0 :         rc = efx_nic_set_fw_subvariant(sa->nic, req_fw_subvariant);
     426         [ #  # ]:          0 :         if (rc != 0) {
     427                 :          0 :                 sfc_err(sa, "failed to set FW subvariant %u: %d",
     428                 :            :                         req_fw_subvariant, rc);
     429                 :          0 :                 return rc;
     430                 :            :         }
     431                 :          0 :         sfc_info(sa, "FW subvariant set to %u", req_fw_subvariant);
     432                 :            : 
     433                 :          0 :         return 0;
     434                 :            : }
     435                 :            : 
     436                 :            : static int
     437                 :          0 : sfc_try_start(struct sfc_adapter *sa)
     438                 :            : {
     439                 :            :         const efx_nic_cfg_t *encp;
     440                 :            :         int rc;
     441                 :            : 
     442                 :          0 :         sfc_log_init(sa, "entry");
     443                 :            : 
     444                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     445                 :            :         SFC_ASSERT(sa->state == SFC_ETHDEV_STARTING);
     446                 :            : 
     447                 :          0 :         sfc_log_init(sa, "set FW subvariant");
     448                 :          0 :         rc = sfc_set_fw_subvariant(sa);
     449         [ #  # ]:          0 :         if (rc != 0)
     450                 :          0 :                 goto fail_set_fw_subvariant;
     451                 :            : 
     452                 :          0 :         sfc_log_init(sa, "set resource limits");
     453                 :          0 :         rc = sfc_set_drv_limits(sa);
     454         [ #  # ]:          0 :         if (rc != 0)
     455                 :          0 :                 goto fail_set_drv_limits;
     456                 :            : 
     457                 :          0 :         sfc_log_init(sa, "init nic");
     458                 :          0 :         rc = efx_nic_init(sa->nic);
     459         [ #  # ]:          0 :         if (rc != 0)
     460                 :          0 :                 goto fail_nic_init;
     461                 :            : 
     462                 :          0 :         sfc_log_init(sa, "reconfigure NIC DMA");
     463                 :          0 :         rc = efx_nic_dma_reconfigure(sa->nic);
     464         [ #  # ]:          0 :         if (rc != 0) {
     465                 :          0 :                 sfc_err(sa, "cannot reconfigure NIC DMA: %s", rte_strerror(rc));
     466                 :          0 :                 goto fail_nic_dma_reconfigure;
     467                 :            :         }
     468                 :            : 
     469                 :          0 :         encp = efx_nic_cfg_get(sa->nic);
     470                 :            : 
     471                 :            :         /*
     472                 :            :          * Refresh (since it may change on NIC reset/restart) a copy of
     473                 :            :          * supported tunnel encapsulations in shared memory to be used
     474                 :            :          * on supported Rx packet type classes get.
     475                 :            :          */
     476                 :          0 :         sa->priv.shared->tunnel_encaps =
     477                 :          0 :                 encp->enc_tunnel_encapsulations_supported;
     478                 :            : 
     479         [ #  # ]:          0 :         if (encp->enc_tunnel_encapsulations_supported != 0) {
     480                 :          0 :                 sfc_log_init(sa, "apply tunnel config");
     481                 :          0 :                 rc = efx_tunnel_reconfigure(sa->nic);
     482         [ #  # ]:          0 :                 if (rc != 0)
     483                 :          0 :                         goto fail_tunnel_reconfigure;
     484                 :            :         }
     485                 :            : 
     486                 :          0 :         rc = sfc_intr_start(sa);
     487         [ #  # ]:          0 :         if (rc != 0)
     488                 :          0 :                 goto fail_intr_start;
     489                 :            : 
     490                 :          0 :         rc = sfc_ev_start(sa);
     491         [ #  # ]:          0 :         if (rc != 0)
     492                 :          0 :                 goto fail_ev_start;
     493                 :            : 
     494                 :          0 :         rc = sfc_tbls_start(sa);
     495         [ #  # ]:          0 :         if (rc != 0)
     496                 :          0 :                 goto fail_tbls_start;
     497                 :            : 
     498                 :          0 :         rc = sfc_port_start(sa);
     499         [ #  # ]:          0 :         if (rc != 0)
     500                 :          0 :                 goto fail_port_start;
     501                 :            : 
     502                 :          0 :         rc = sfc_rx_start(sa);
     503         [ #  # ]:          0 :         if (rc != 0)
     504                 :          0 :                 goto fail_rx_start;
     505                 :            : 
     506                 :          0 :         rc = sfc_tx_start(sa);
     507         [ #  # ]:          0 :         if (rc != 0)
     508                 :          0 :                 goto fail_tx_start;
     509                 :            : 
     510                 :          0 :         rc = sfc_flow_start(sa);
     511         [ #  # ]:          0 :         if (rc != 0)
     512                 :          0 :                 goto fail_flows_insert;
     513                 :            : 
     514                 :          0 :         rc = sfc_repr_proxy_start(sa);
     515         [ #  # ]:          0 :         if (rc != 0)
     516                 :          0 :                 goto fail_repr_proxy_start;
     517                 :            : 
     518                 :          0 :         sfc_log_init(sa, "done");
     519                 :          0 :         return 0;
     520                 :            : 
     521                 :            : fail_repr_proxy_start:
     522                 :          0 :         sfc_flow_stop(sa);
     523                 :            : 
     524                 :          0 : fail_flows_insert:
     525                 :          0 :         sfc_tx_stop(sa);
     526                 :            : 
     527                 :          0 : fail_tx_start:
     528                 :          0 :         sfc_rx_stop(sa);
     529                 :            : 
     530                 :          0 : fail_rx_start:
     531                 :          0 :         sfc_port_stop(sa);
     532                 :            : 
     533                 :          0 : fail_tbls_start:
     534                 :          0 :         sfc_ev_stop(sa);
     535                 :            : 
     536                 :          0 : fail_port_start:
     537                 :            :         sfc_tbls_stop(sa);
     538                 :            : 
     539                 :          0 : fail_ev_start:
     540                 :          0 :         sfc_intr_stop(sa);
     541                 :            : 
     542                 :          0 : fail_intr_start:
     543                 :          0 : fail_tunnel_reconfigure:
     544                 :          0 : fail_nic_dma_reconfigure:
     545                 :          0 :         efx_nic_fini(sa->nic);
     546                 :            : 
     547                 :          0 : fail_nic_init:
     548                 :          0 : fail_set_drv_limits:
     549                 :          0 : fail_set_fw_subvariant:
     550                 :          0 :         sfc_log_init(sa, "failed %d", rc);
     551                 :          0 :         return rc;
     552                 :            : }
     553                 :            : 
     554                 :            : int
     555                 :          0 : sfc_start(struct sfc_adapter *sa)
     556                 :            : {
     557                 :            :         unsigned int start_tries = 3;
     558                 :            :         int rc;
     559                 :            : 
     560                 :          0 :         sfc_log_init(sa, "entry");
     561                 :            : 
     562                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     563                 :            : 
     564      [ #  #  # ]:          0 :         switch (sa->state) {
     565                 :            :         case SFC_ETHDEV_CONFIGURED:
     566                 :            :                 break;
     567                 :          0 :         case SFC_ETHDEV_STARTED:
     568                 :          0 :                 sfc_notice(sa, "already started");
     569                 :          0 :                 return 0;
     570                 :          0 :         default:
     571                 :            :                 rc = EINVAL;
     572                 :          0 :                 goto fail_bad_state;
     573                 :            :         }
     574                 :            : 
     575                 :          0 :         sa->state = SFC_ETHDEV_STARTING;
     576                 :            : 
     577                 :            :         rc = 0;
     578                 :            :         do {
     579                 :            :                 /*
     580                 :            :                  * FIXME Try to recreate vSwitch on start retry.
     581                 :            :                  * vSwitch is absent after MC reboot like events and
     582                 :            :                  * we should recreate it. May be we need proper
     583                 :            :                  * indication instead of guessing.
     584                 :            :                  */
     585         [ #  # ]:          0 :                 if (rc != 0) {
     586                 :          0 :                         sfc_sriov_vswitch_destroy(sa);
     587                 :          0 :                         rc = sfc_sriov_vswitch_create(sa);
     588         [ #  # ]:          0 :                         if (rc != 0)
     589                 :          0 :                                 goto fail_sriov_vswitch_create;
     590                 :            :                 }
     591                 :          0 :                 rc = sfc_try_start(sa);
     592         [ #  # ]:          0 :         } while ((--start_tries > 0) &&
     593         [ #  # ]:          0 :                  (rc == EIO || rc == EAGAIN || rc == ENOENT || rc == EINVAL));
     594                 :            : 
     595         [ #  # ]:          0 :         if (rc != 0)
     596                 :          0 :                 goto fail_try_start;
     597                 :            : 
     598                 :          0 :         sa->state = SFC_ETHDEV_STARTED;
     599                 :          0 :         sfc_log_init(sa, "done");
     600                 :          0 :         return 0;
     601                 :            : 
     602                 :            : fail_try_start:
     603                 :          0 : fail_sriov_vswitch_create:
     604                 :          0 :         sa->state = SFC_ETHDEV_CONFIGURED;
     605                 :          0 : fail_bad_state:
     606                 :          0 :         sfc_log_init(sa, "failed %d", rc);
     607                 :          0 :         return rc;
     608                 :            : }
     609                 :            : 
     610                 :            : void
     611                 :          0 : sfc_stop(struct sfc_adapter *sa)
     612                 :            : {
     613                 :          0 :         sfc_log_init(sa, "entry");
     614                 :            : 
     615                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     616                 :            : 
     617      [ #  #  # ]:          0 :         switch (sa->state) {
     618                 :            :         case SFC_ETHDEV_STARTED:
     619                 :            :                 break;
     620                 :          0 :         case SFC_ETHDEV_CONFIGURED:
     621                 :          0 :                 sfc_notice(sa, "already stopped");
     622                 :          0 :                 return;
     623                 :          0 :         default:
     624                 :          0 :                 sfc_err(sa, "stop in unexpected state %u", sa->state);
     625                 :            :                 SFC_ASSERT(B_FALSE);
     626                 :          0 :                 return;
     627                 :            :         }
     628                 :            : 
     629                 :          0 :         sa->state = SFC_ETHDEV_STOPPING;
     630                 :            : 
     631                 :          0 :         sfc_repr_proxy_stop(sa);
     632                 :          0 :         sfc_flow_stop(sa);
     633                 :          0 :         sfc_tx_stop(sa);
     634                 :          0 :         sfc_rx_stop(sa);
     635                 :          0 :         sfc_port_stop(sa);
     636                 :            :         sfc_tbls_stop(sa);
     637                 :          0 :         sfc_ev_stop(sa);
     638                 :          0 :         sfc_intr_stop(sa);
     639                 :          0 :         efx_nic_fini(sa->nic);
     640                 :            : 
     641                 :          0 :         sa->state = SFC_ETHDEV_CONFIGURED;
     642                 :          0 :         sfc_log_init(sa, "done");
     643                 :            : }
     644                 :            : 
     645                 :            : static int
     646                 :          0 : sfc_restart(struct sfc_adapter *sa)
     647                 :            : {
     648                 :            :         int rc;
     649                 :            : 
     650                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     651                 :            : 
     652         [ #  # ]:          0 :         if (sa->state != SFC_ETHDEV_STARTED)
     653                 :            :                 return EINVAL;
     654                 :            : 
     655                 :          0 :         sfc_stop(sa);
     656                 :            : 
     657                 :          0 :         rc = sfc_start(sa);
     658         [ #  # ]:          0 :         if (rc != 0)
     659                 :          0 :                 sfc_err(sa, "restart failed");
     660                 :            : 
     661                 :            :         return rc;
     662                 :            : }
     663                 :            : 
     664                 :            : static void
     665                 :          0 : sfc_restart_if_required(void *arg)
     666                 :            : {
     667                 :            :         struct sfc_adapter *sa = arg;
     668                 :            : 
     669                 :            :         /* If restart is scheduled, clear the flag and do it */
     670         [ #  # ]:          0 :         if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required,
     671                 :            :                                 1, 0)) {
     672                 :          0 :                 sfc_adapter_lock(sa);
     673         [ #  # ]:          0 :                 if (sa->state == SFC_ETHDEV_STARTED)
     674                 :          0 :                         (void)sfc_restart(sa);
     675                 :            :                 sfc_adapter_unlock(sa);
     676                 :            :         }
     677                 :          0 : }
     678                 :            : 
     679                 :            : void
     680                 :          0 : sfc_schedule_restart(struct sfc_adapter *sa)
     681                 :            : {
     682                 :            :         int rc;
     683                 :            : 
     684                 :            :         /* Schedule restart alarm if it is not scheduled yet */
     685         [ #  # ]:          0 :         if (!rte_atomic32_test_and_set(&sa->restart_required))
     686                 :            :                 return;
     687                 :            : 
     688                 :          0 :         rc = rte_eal_alarm_set(1, sfc_restart_if_required, sa);
     689         [ #  # ]:          0 :         if (rc == -ENOTSUP)
     690                 :          0 :                 sfc_warn(sa, "alarms are not supported, restart is pending");
     691         [ #  # ]:          0 :         else if (rc != 0)
     692                 :          0 :                 sfc_err(sa, "cannot arm restart alarm (rc=%d)", rc);
     693                 :            :         else
     694                 :          0 :                 sfc_notice(sa, "restart scheduled");
     695                 :            : }
     696                 :            : 
     697                 :            : int
     698                 :          0 : sfc_configure(struct sfc_adapter *sa)
     699                 :            : {
     700                 :            :         int rc;
     701                 :            : 
     702                 :          0 :         sfc_log_init(sa, "entry");
     703                 :            : 
     704                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     705                 :            : 
     706                 :            :         SFC_ASSERT(sa->state == SFC_ETHDEV_INITIALIZED ||
     707                 :            :                    sa->state == SFC_ETHDEV_CONFIGURED);
     708                 :          0 :         sa->state = SFC_ETHDEV_CONFIGURING;
     709                 :            : 
     710                 :          0 :         rc = sfc_check_conf(sa);
     711         [ #  # ]:          0 :         if (rc != 0)
     712                 :          0 :                 goto fail_check_conf;
     713                 :            : 
     714                 :          0 :         rc = sfc_intr_configure(sa);
     715         [ #  # ]:          0 :         if (rc != 0)
     716                 :          0 :                 goto fail_intr_configure;
     717                 :            : 
     718                 :          0 :         rc = sfc_port_configure(sa);
     719         [ #  # ]:          0 :         if (rc != 0)
     720                 :          0 :                 goto fail_port_configure;
     721                 :            : 
     722                 :          0 :         rc = sfc_rx_configure(sa);
     723         [ #  # ]:          0 :         if (rc != 0)
     724                 :          0 :                 goto fail_rx_configure;
     725                 :            : 
     726                 :          0 :         rc = sfc_tx_configure(sa);
     727         [ #  # ]:          0 :         if (rc != 0)
     728                 :          0 :                 goto fail_tx_configure;
     729                 :            : 
     730                 :          0 :         rc = sfc_sw_xstats_configure(sa);
     731         [ #  # ]:          0 :         if (rc != 0)
     732                 :          0 :                 goto fail_sw_xstats_configure;
     733                 :            : 
     734                 :          0 :         sa->state = SFC_ETHDEV_CONFIGURED;
     735                 :          0 :         sfc_log_init(sa, "done");
     736                 :          0 :         return 0;
     737                 :            : 
     738                 :            : fail_sw_xstats_configure:
     739                 :          0 :         sfc_tx_close(sa);
     740                 :            : 
     741                 :          0 : fail_tx_configure:
     742                 :          0 :         sfc_rx_close(sa);
     743                 :            : 
     744                 :          0 : fail_rx_configure:
     745                 :          0 :         sfc_port_close(sa);
     746                 :            : 
     747                 :          0 : fail_port_configure:
     748                 :          0 :         sfc_intr_close(sa);
     749                 :            : 
     750                 :          0 : fail_intr_configure:
     751                 :          0 : fail_check_conf:
     752                 :          0 :         sa->state = SFC_ETHDEV_INITIALIZED;
     753                 :          0 :         sfc_log_init(sa, "failed %d", rc);
     754                 :          0 :         return rc;
     755                 :            : }
     756                 :            : 
     757                 :            : void
     758                 :          0 : sfc_close(struct sfc_adapter *sa)
     759                 :            : {
     760                 :          0 :         sfc_log_init(sa, "entry");
     761                 :            : 
     762                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     763                 :            : 
     764                 :            :         SFC_ASSERT(sa->state == SFC_ETHDEV_CONFIGURED);
     765                 :          0 :         sa->state = SFC_ETHDEV_CLOSING;
     766                 :            : 
     767                 :          0 :         sfc_sw_xstats_close(sa);
     768                 :          0 :         sfc_tx_close(sa);
     769                 :          0 :         sfc_rx_close(sa);
     770                 :          0 :         sfc_port_close(sa);
     771                 :          0 :         sfc_intr_close(sa);
     772                 :            : 
     773                 :          0 :         sa->state = SFC_ETHDEV_INITIALIZED;
     774                 :          0 :         sfc_log_init(sa, "done");
     775                 :          0 : }
     776                 :            : 
     777                 :            : static int
     778                 :            : sfc_mem_bar_init(struct sfc_adapter *sa, const efx_bar_region_t *mem_ebrp)
     779                 :            : {
     780                 :          0 :         struct rte_eth_dev *eth_dev = sa->eth_dev;
     781                 :          0 :         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
     782                 :            :         efsys_bar_t *ebp = &sa->mem_bar;
     783                 :            :         struct rte_mem_resource *res =
     784                 :          0 :                 &pci_dev->mem_resource[mem_ebrp->ebr_index];
     785                 :            : 
     786                 :            :         SFC_BAR_LOCK_INIT(ebp, eth_dev->data->name);
     787                 :          0 :         ebp->esb_rid = mem_ebrp->ebr_index;
     788                 :          0 :         ebp->esb_dev = pci_dev;
     789                 :          0 :         ebp->esb_base = res->addr;
     790                 :            : 
     791                 :          0 :         sa->fcw_offset = mem_ebrp->ebr_offset;
     792                 :            : 
     793                 :            :         return 0;
     794                 :            : }
     795                 :            : 
     796                 :            : static void
     797                 :            : sfc_mem_bar_fini(struct sfc_adapter *sa)
     798                 :            : {
     799                 :          0 :         efsys_bar_t *ebp = &sa->mem_bar;
     800                 :            : 
     801                 :            :         SFC_BAR_LOCK_DESTROY(ebp);
     802                 :            :         memset(ebp, 0, sizeof(*ebp));
     803                 :          0 : }
     804                 :            : 
     805                 :            : /*
     806                 :            :  * A fixed RSS key which has a property of being symmetric
     807                 :            :  * (symmetrical flows are distributed to the same CPU)
     808                 :            :  * and also known to give a uniform distribution
     809                 :            :  * (a good distribution of traffic between different CPUs)
     810                 :            :  */
     811                 :            : static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = {
     812                 :            :         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
     813                 :            :         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
     814                 :            :         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
     815                 :            :         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
     816                 :            :         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
     817                 :            : };
     818                 :            : 
     819                 :            : static int
     820                 :          0 : sfc_rss_attach(struct sfc_adapter *sa)
     821                 :            : {
     822                 :            :         struct sfc_rss *rss = &sfc_sa2shared(sa)->rss;
     823                 :            :         int rc;
     824                 :            : 
     825                 :          0 :         rc = efx_intr_init(sa->nic, sa->intr.type, NULL);
     826         [ #  # ]:          0 :         if (rc != 0)
     827                 :          0 :                 goto fail_intr_init;
     828                 :            : 
     829                 :          0 :         rc = efx_ev_init(sa->nic);
     830         [ #  # ]:          0 :         if (rc != 0)
     831                 :          0 :                 goto fail_ev_init;
     832                 :            : 
     833                 :          0 :         rc = efx_rx_init(sa->nic);
     834         [ #  # ]:          0 :         if (rc != 0)
     835                 :          0 :                 goto fail_rx_init;
     836                 :            : 
     837                 :          0 :         rc = efx_rx_scale_default_support_get(sa->nic, &rss->context_type);
     838         [ #  # ]:          0 :         if (rc != 0)
     839                 :          0 :                 goto fail_scale_support_get;
     840                 :            : 
     841                 :          0 :         rc = efx_rx_hash_default_support_get(sa->nic, &rss->hash_support);
     842         [ #  # ]:          0 :         if (rc != 0)
     843                 :          0 :                 goto fail_hash_support_get;
     844                 :            : 
     845                 :          0 :         rc = sfc_rx_hash_init(sa);
     846         [ #  # ]:          0 :         if (rc != 0)
     847                 :          0 :                 goto fail_rx_hash_init;
     848                 :            : 
     849                 :          0 :         efx_rx_fini(sa->nic);
     850                 :          0 :         efx_ev_fini(sa->nic);
     851                 :          0 :         efx_intr_fini(sa->nic);
     852                 :            : 
     853         [ #  # ]:          0 :         rte_memcpy(rss->key, default_rss_key, sizeof(rss->key));
     854                 :          0 :         memset(&rss->dummy_ctx, 0, sizeof(rss->dummy_ctx));
     855                 :          0 :         rss->dummy_ctx.conf.qid_span = 1;
     856                 :          0 :         rss->dummy_ctx.dummy = true;
     857                 :            : 
     858                 :          0 :         return 0;
     859                 :            : 
     860                 :            : fail_rx_hash_init:
     861                 :          0 : fail_hash_support_get:
     862                 :          0 : fail_scale_support_get:
     863                 :          0 :         efx_rx_fini(sa->nic);
     864                 :            : 
     865                 :          0 : fail_rx_init:
     866                 :          0 :         efx_ev_fini(sa->nic);
     867                 :            : 
     868                 :          0 : fail_ev_init:
     869                 :          0 :         efx_intr_fini(sa->nic);
     870                 :            : 
     871                 :            : fail_intr_init:
     872                 :            :         return rc;
     873                 :            : }
     874                 :            : 
     875                 :            : static void
     876                 :            : sfc_rss_detach(struct sfc_adapter *sa)
     877                 :            : {
     878                 :          0 :         sfc_rx_hash_fini(sa);
     879                 :          0 : }
     880                 :            : 
     881                 :            : int
     882                 :          0 : sfc_attach(struct sfc_adapter *sa)
     883                 :            : {
     884                 :            :         const efx_nic_cfg_t *encp;
     885                 :          0 :         efx_nic_t *enp = sa->nic;
     886                 :            :         int rc;
     887                 :            : 
     888                 :          0 :         sfc_log_init(sa, "entry");
     889                 :            : 
     890                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
     891                 :            : 
     892                 :          0 :         efx_mcdi_new_epoch(enp);
     893                 :            : 
     894                 :          0 :         sfc_log_init(sa, "reset nic");
     895                 :          0 :         rc = efx_nic_reset(enp);
     896         [ #  # ]:          0 :         if (rc != 0)
     897                 :          0 :                 goto fail_nic_reset;
     898                 :            : 
     899                 :          0 :         rc = sfc_sriov_attach(sa);
     900         [ #  # ]:          0 :         if (rc != 0)
     901                 :          0 :                 goto fail_sriov_attach;
     902                 :            : 
     903                 :            :         /*
     904                 :            :          * Probed NIC is sufficient for tunnel init.
     905                 :            :          * Initialize tunnel support to be able to use libefx
     906                 :            :          * efx_tunnel_config_udp_{add,remove}() in any state and
     907                 :            :          * efx_tunnel_reconfigure() on start up.
     908                 :            :          */
     909                 :          0 :         rc = efx_tunnel_init(enp);
     910         [ #  # ]:          0 :         if (rc != 0)
     911                 :          0 :                 goto fail_tunnel_init;
     912                 :            : 
     913                 :          0 :         encp = efx_nic_cfg_get(sa->nic);
     914                 :            : 
     915                 :            :         /*
     916                 :            :          * Make a copy of supported tunnel encapsulations in shared
     917                 :            :          * memory to be used on supported Rx packet type classes get.
     918                 :            :          */
     919                 :          0 :         sa->priv.shared->tunnel_encaps =
     920                 :          0 :                 encp->enc_tunnel_encapsulations_supported;
     921                 :            : 
     922         [ #  # ]:          0 :         if (sfc_dp_tx_offload_capa(sa->priv.dp_tx) & RTE_ETH_TX_OFFLOAD_TCP_TSO) {
     923                 :          0 :                 sa->tso = encp->enc_fw_assisted_tso_v2_enabled ||
     924                 :            :                           encp->enc_tso_v3_enabled;
     925         [ #  # ]:          0 :                 if (!sa->tso)
     926                 :          0 :                         sfc_info(sa, "TSO support isn't available on this adapter");
     927                 :            :         }
     928                 :            : 
     929   [ #  #  #  # ]:          0 :         if (sa->tso &&
     930         [ #  # ]:          0 :             (sfc_dp_tx_offload_capa(sa->priv.dp_tx) &
     931                 :            :              (RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
     932                 :            :               RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO)) != 0) {
     933                 :          0 :                 sa->tso_encap = encp->enc_fw_assisted_tso_v2_encap_enabled ||
     934                 :            :                                 encp->enc_tso_v3_enabled;
     935         [ #  # ]:          0 :                 if (!sa->tso_encap)
     936                 :          0 :                         sfc_info(sa, "Encapsulated TSO support isn't available on this adapter");
     937                 :            :         }
     938                 :            : 
     939                 :          0 :         sfc_log_init(sa, "estimate resource limits");
     940                 :          0 :         rc = sfc_estimate_resource_limits(sa);
     941         [ #  # ]:          0 :         if (rc != 0)
     942                 :          0 :                 goto fail_estimate_rsrc_limits;
     943                 :            : 
     944                 :          0 :         sa->evq_max_entries = encp->enc_evq_max_nevs;
     945                 :            :         SFC_ASSERT(rte_is_power_of_2(sa->evq_max_entries));
     946                 :            : 
     947                 :          0 :         sa->evq_min_entries = encp->enc_evq_min_nevs;
     948                 :            :         SFC_ASSERT(rte_is_power_of_2(sa->evq_min_entries));
     949                 :            : 
     950                 :          0 :         sa->rxq_max_entries = encp->enc_rxq_max_ndescs;
     951                 :            :         SFC_ASSERT(rte_is_power_of_2(sa->rxq_max_entries));
     952                 :            : 
     953                 :          0 :         sa->rxq_min_entries = encp->enc_rxq_min_ndescs;
     954                 :            :         SFC_ASSERT(rte_is_power_of_2(sa->rxq_min_entries));
     955                 :            : 
     956                 :          0 :         sa->txq_max_entries = encp->enc_txq_max_ndescs;
     957                 :            :         SFC_ASSERT(rte_is_power_of_2(sa->txq_max_entries));
     958                 :            : 
     959                 :          0 :         sa->txq_min_entries = encp->enc_txq_min_ndescs;
     960                 :            :         SFC_ASSERT(rte_is_power_of_2(sa->txq_min_entries));
     961                 :            : 
     962                 :          0 :         rc = sfc_intr_attach(sa);
     963         [ #  # ]:          0 :         if (rc != 0)
     964                 :          0 :                 goto fail_intr_attach;
     965                 :            : 
     966                 :          0 :         rc = sfc_ev_attach(sa);
     967         [ #  # ]:          0 :         if (rc != 0)
     968                 :          0 :                 goto fail_ev_attach;
     969                 :            : 
     970                 :          0 :         rc = sfc_port_attach(sa);
     971         [ #  # ]:          0 :         if (rc != 0)
     972                 :          0 :                 goto fail_port_attach;
     973                 :            : 
     974                 :          0 :         rc = sfc_rss_attach(sa);
     975         [ #  # ]:          0 :         if (rc != 0)
     976                 :          0 :                 goto fail_rss_attach;
     977                 :            : 
     978                 :          0 :         sfc_flow_init(sa);
     979                 :            : 
     980                 :          0 :         rc = sfc_flow_rss_attach(sa);
     981         [ #  # ]:          0 :         if (rc != 0)
     982                 :          0 :                 goto fail_flow_rss_attach;
     983                 :            : 
     984                 :          0 :         rc = sfc_filter_attach(sa);
     985         [ #  # ]:          0 :         if (rc != 0)
     986                 :          0 :                 goto fail_filter_attach;
     987                 :            : 
     988                 :          0 :         rc = sfc_mae_counter_rxq_attach(sa);
     989         [ #  # ]:          0 :         if (rc != 0)
     990                 :          0 :                 goto fail_mae_counter_rxq_attach;
     991                 :            : 
     992                 :          0 :         rc = sfc_mae_attach(sa);
     993         [ #  # ]:          0 :         if (rc != 0)
     994                 :          0 :                 goto fail_mae_attach;
     995                 :            : 
     996                 :          0 :         rc = sfc_tbls_attach(sa);
     997         [ #  # ]:          0 :         if (rc != 0)
     998                 :          0 :                 goto fail_tables_attach;
     999                 :            : 
    1000                 :          0 :         rc = sfc_mae_switchdev_init(sa);
    1001         [ #  # ]:          0 :         if (rc != 0)
    1002                 :          0 :                 goto fail_mae_switchdev_init;
    1003                 :            : 
    1004                 :          0 :         rc = sfc_repr_proxy_attach(sa);
    1005         [ #  # ]:          0 :         if (rc != 0)
    1006                 :          0 :                 goto fail_repr_proxy_attach;
    1007                 :            : 
    1008                 :          0 :         sfc_log_init(sa, "fini nic");
    1009                 :          0 :         efx_nic_fini(enp);
    1010                 :            : 
    1011                 :          0 :         rc = sfc_sw_xstats_init(sa);
    1012         [ #  # ]:          0 :         if (rc != 0)
    1013                 :          0 :                 goto fail_sw_xstats_init;
    1014                 :            : 
    1015                 :            :         /*
    1016                 :            :          * Create vSwitch to be able to use VFs when PF is not started yet
    1017                 :            :          * as DPDK port. VFs should be able to talk to each other even
    1018                 :            :          * if PF is down.
    1019                 :            :          */
    1020                 :          0 :         rc = sfc_sriov_vswitch_create(sa);
    1021         [ #  # ]:          0 :         if (rc != 0)
    1022                 :          0 :                 goto fail_sriov_vswitch_create;
    1023                 :            : 
    1024                 :          0 :         sa->state = SFC_ETHDEV_INITIALIZED;
    1025                 :            : 
    1026                 :          0 :         sfc_log_init(sa, "done");
    1027                 :          0 :         return 0;
    1028                 :            : 
    1029                 :            : fail_sriov_vswitch_create:
    1030                 :          0 :         sfc_sw_xstats_close(sa);
    1031                 :            : 
    1032                 :          0 : fail_sw_xstats_init:
    1033                 :          0 :         sfc_repr_proxy_detach(sa);
    1034                 :            : 
    1035                 :          0 : fail_repr_proxy_attach:
    1036                 :          0 :         sfc_mae_switchdev_fini(sa);
    1037                 :            : 
    1038                 :          0 : fail_mae_switchdev_init:
    1039                 :          0 :         sfc_tbls_detach(sa);
    1040                 :            : 
    1041                 :          0 : fail_tables_attach:
    1042                 :          0 :         sfc_mae_detach(sa);
    1043                 :            : 
    1044                 :          0 : fail_mae_attach:
    1045                 :          0 :         sfc_mae_counter_rxq_detach(sa);
    1046                 :            : 
    1047                 :          0 : fail_mae_counter_rxq_attach:
    1048                 :          0 :         sfc_filter_detach(sa);
    1049                 :            : 
    1050                 :          0 : fail_filter_attach:
    1051                 :          0 :         sfc_flow_rss_detach(sa);
    1052                 :            : 
    1053                 :          0 : fail_flow_rss_attach:
    1054                 :          0 :         sfc_flow_fini(sa);
    1055                 :            :         sfc_rss_detach(sa);
    1056                 :            : 
    1057                 :          0 : fail_rss_attach:
    1058                 :          0 :         sfc_port_detach(sa);
    1059                 :            : 
    1060                 :          0 : fail_port_attach:
    1061                 :          0 :         sfc_ev_detach(sa);
    1062                 :            : 
    1063                 :          0 : fail_ev_attach:
    1064                 :          0 :         sfc_intr_detach(sa);
    1065                 :            : 
    1066                 :          0 : fail_intr_attach:
    1067                 :          0 :         efx_nic_fini(sa->nic);
    1068                 :            : 
    1069                 :          0 : fail_estimate_rsrc_limits:
    1070                 :          0 : fail_tunnel_init:
    1071                 :          0 :         efx_tunnel_fini(sa->nic);
    1072                 :          0 :         sfc_sriov_detach(sa);
    1073                 :            : 
    1074                 :          0 : fail_sriov_attach:
    1075                 :          0 : fail_nic_reset:
    1076                 :            : 
    1077                 :          0 :         sfc_log_init(sa, "failed %d", rc);
    1078                 :          0 :         return rc;
    1079                 :            : }
    1080                 :            : 
    1081                 :            : void
    1082                 :          0 : sfc_pre_detach(struct sfc_adapter *sa)
    1083                 :            : {
    1084                 :          0 :         sfc_log_init(sa, "entry");
    1085                 :            : 
    1086                 :            :         SFC_ASSERT(!sfc_adapter_is_locked(sa));
    1087                 :            : 
    1088                 :          0 :         sfc_repr_proxy_pre_detach(sa);
    1089                 :            : 
    1090                 :          0 :         sfc_log_init(sa, "done");
    1091                 :          0 : }
    1092                 :            : 
    1093                 :            : void
    1094                 :          0 : sfc_detach(struct sfc_adapter *sa)
    1095                 :            : {
    1096                 :          0 :         sfc_log_init(sa, "entry");
    1097                 :            : 
    1098                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
    1099                 :            : 
    1100                 :          0 :         sfc_sriov_vswitch_destroy(sa);
    1101                 :            : 
    1102                 :          0 :         sfc_repr_proxy_detach(sa);
    1103                 :          0 :         sfc_mae_switchdev_fini(sa);
    1104                 :          0 :         sfc_tbls_detach(sa);
    1105                 :          0 :         sfc_mae_detach(sa);
    1106                 :          0 :         sfc_mae_counter_rxq_detach(sa);
    1107                 :          0 :         sfc_filter_detach(sa);
    1108                 :          0 :         sfc_flow_rss_detach(sa);
    1109                 :          0 :         sfc_flow_fini(sa);
    1110                 :            :         sfc_rss_detach(sa);
    1111                 :          0 :         sfc_port_detach(sa);
    1112                 :          0 :         sfc_ev_detach(sa);
    1113                 :          0 :         sfc_intr_detach(sa);
    1114                 :          0 :         efx_tunnel_fini(sa->nic);
    1115                 :          0 :         sfc_sriov_detach(sa);
    1116                 :            : 
    1117                 :          0 :         sa->state = SFC_ETHDEV_UNINITIALIZED;
    1118                 :          0 : }
    1119                 :            : 
    1120                 :            : static int
    1121                 :          0 : sfc_kvarg_fv_variant_handler(__rte_unused const char *key,
    1122                 :            :                              const char *value_str, void *opaque)
    1123                 :            : {
    1124                 :            :         uint32_t *value = opaque;
    1125                 :            : 
    1126         [ #  # ]:          0 :         if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_DONT_CARE) == 0)
    1127                 :          0 :                 *value = EFX_FW_VARIANT_DONT_CARE;
    1128         [ #  # ]:          0 :         else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_FULL_FEATURED) == 0)
    1129                 :          0 :                 *value = EFX_FW_VARIANT_FULL_FEATURED;
    1130         [ #  # ]:          0 :         else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_LOW_LATENCY) == 0)
    1131                 :          0 :                 *value = EFX_FW_VARIANT_LOW_LATENCY;
    1132         [ #  # ]:          0 :         else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_PACKED_STREAM) == 0)
    1133                 :          0 :                 *value = EFX_FW_VARIANT_PACKED_STREAM;
    1134         [ #  # ]:          0 :         else if (strcasecmp(value_str, SFC_KVARG_FW_VARIANT_DPDK) == 0)
    1135                 :          0 :                 *value = EFX_FW_VARIANT_DPDK;
    1136                 :            :         else
    1137                 :            :                 return -EINVAL;
    1138                 :            : 
    1139                 :            :         return 0;
    1140                 :            : }
    1141                 :            : 
    1142                 :            : static int
    1143                 :          0 : sfc_get_fw_variant(struct sfc_adapter *sa, efx_fw_variant_t *efv)
    1144                 :            : {
    1145                 :            :         efx_nic_fw_info_t enfi;
    1146                 :            :         int rc;
    1147                 :            : 
    1148                 :          0 :         rc = efx_nic_get_fw_version(sa->nic, &enfi);
    1149         [ #  # ]:          0 :         if (rc != 0)
    1150                 :            :                 return rc;
    1151         [ #  # ]:          0 :         else if (!enfi.enfi_dpcpu_fw_ids_valid)
    1152                 :            :                 return ENOTSUP;
    1153                 :            : 
    1154                 :            :         /*
    1155                 :            :          * Firmware variant can be uniquely identified by the RxDPCPU
    1156                 :            :          * firmware id
    1157                 :            :          */
    1158   [ #  #  #  #  :          0 :         switch (enfi.enfi_rx_dpcpu_fw_id) {
                      # ]
    1159                 :          0 :         case EFX_RXDP_FULL_FEATURED_FW_ID:
    1160                 :          0 :                 *efv = EFX_FW_VARIANT_FULL_FEATURED;
    1161                 :          0 :                 break;
    1162                 :            : 
    1163                 :          0 :         case EFX_RXDP_LOW_LATENCY_FW_ID:
    1164                 :          0 :                 *efv = EFX_FW_VARIANT_LOW_LATENCY;
    1165                 :          0 :                 break;
    1166                 :            : 
    1167                 :          0 :         case EFX_RXDP_PACKED_STREAM_FW_ID:
    1168                 :          0 :                 *efv = EFX_FW_VARIANT_PACKED_STREAM;
    1169                 :          0 :                 break;
    1170                 :            : 
    1171                 :          0 :         case EFX_RXDP_DPDK_FW_ID:
    1172                 :          0 :                 *efv = EFX_FW_VARIANT_DPDK;
    1173                 :          0 :                 break;
    1174                 :            : 
    1175                 :          0 :         default:
    1176                 :            :                 /*
    1177                 :            :                  * Other firmware variants are not considered, since they are
    1178                 :            :                  * not supported in the device parameters
    1179                 :            :                  */
    1180                 :          0 :                 *efv = EFX_FW_VARIANT_DONT_CARE;
    1181                 :          0 :                 break;
    1182                 :            :         }
    1183                 :            : 
    1184                 :            :         return 0;
    1185                 :            : }
    1186                 :            : 
    1187                 :            : static const char *
    1188                 :            : sfc_fw_variant2str(efx_fw_variant_t efv)
    1189                 :            : {
    1190                 :          0 :         switch (efv) {
    1191                 :            :         case EFX_RXDP_FULL_FEATURED_FW_ID:
    1192                 :            :                 return SFC_KVARG_FW_VARIANT_FULL_FEATURED;
    1193                 :          0 :         case EFX_RXDP_LOW_LATENCY_FW_ID:
    1194                 :          0 :                 return SFC_KVARG_FW_VARIANT_LOW_LATENCY;
    1195                 :          0 :         case EFX_RXDP_PACKED_STREAM_FW_ID:
    1196                 :          0 :                 return SFC_KVARG_FW_VARIANT_PACKED_STREAM;
    1197                 :          0 :         case EFX_RXDP_DPDK_FW_ID:
    1198                 :          0 :                 return SFC_KVARG_FW_VARIANT_DPDK;
    1199                 :          0 :         default:
    1200                 :          0 :                 return "unknown";
    1201                 :            :         }
    1202                 :            : }
    1203                 :            : 
    1204                 :            : static int
    1205                 :          0 : sfc_kvarg_rxd_wait_timeout_ns(struct sfc_adapter *sa)
    1206                 :            : {
    1207                 :            :         int rc;
    1208                 :            :         long value;
    1209                 :            : 
    1210                 :          0 :         value = SFC_RXD_WAIT_TIMEOUT_NS_DEF;
    1211                 :            : 
    1212                 :          0 :         rc = sfc_kvargs_process(sa, SFC_KVARG_RXD_WAIT_TIMEOUT_NS,
    1213                 :            :                                 sfc_kvarg_long_handler, &value);
    1214         [ #  # ]:          0 :         if (rc != 0)
    1215                 :            :                 return rc;
    1216                 :            : 
    1217         [ #  # ]:          0 :         if (value < 0 ||
    1218                 :            :             (unsigned long)value > EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX) {
    1219                 :          0 :                 sfc_err(sa, "wrong '" SFC_KVARG_RXD_WAIT_TIMEOUT_NS "' "
    1220                 :            :                             "was set (%ld);", value);
    1221                 :          0 :                 sfc_err(sa, "it must not be less than 0 or greater than %u",
    1222                 :            :                             EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX);
    1223                 :          0 :                 return EINVAL;
    1224                 :            :         }
    1225                 :            : 
    1226                 :          0 :         sa->rxd_wait_timeout_ns = value;
    1227                 :          0 :         return 0;
    1228                 :            : }
    1229                 :            : 
    1230                 :            : static int
    1231                 :          0 : sfc_nic_probe(struct sfc_adapter *sa)
    1232                 :            : {
    1233                 :          0 :         efx_nic_t *enp = sa->nic;
    1234                 :            :         efx_fw_variant_t preferred_efv;
    1235                 :            :         efx_fw_variant_t efv;
    1236                 :            :         int rc;
    1237                 :            : 
    1238                 :          0 :         preferred_efv = EFX_FW_VARIANT_DONT_CARE;
    1239                 :          0 :         rc = sfc_kvargs_process(sa, SFC_KVARG_FW_VARIANT,
    1240                 :            :                                 sfc_kvarg_fv_variant_handler,
    1241                 :            :                                 &preferred_efv);
    1242         [ #  # ]:          0 :         if (rc != 0) {
    1243                 :          0 :                 sfc_err(sa, "invalid %s parameter value", SFC_KVARG_FW_VARIANT);
    1244                 :          0 :                 return rc;
    1245                 :            :         }
    1246                 :            : 
    1247                 :          0 :         rc = sfc_kvarg_rxd_wait_timeout_ns(sa);
    1248         [ #  # ]:          0 :         if (rc != 0)
    1249                 :            :                 return rc;
    1250                 :            : 
    1251                 :          0 :         rc = efx_nic_probe(enp, preferred_efv);
    1252         [ #  # ]:          0 :         if (rc == EACCES) {
    1253                 :            :                 /* Unprivileged functions cannot set FW variant */
    1254                 :          0 :                 rc = efx_nic_probe(enp, EFX_FW_VARIANT_DONT_CARE);
    1255                 :            :         }
    1256         [ #  # ]:          0 :         if (rc != 0)
    1257                 :            :                 return rc;
    1258                 :            : 
    1259                 :          0 :         rc = sfc_get_fw_variant(sa, &efv);
    1260         [ #  # ]:          0 :         if (rc == ENOTSUP) {
    1261                 :          0 :                 sfc_warn(sa, "FW variant can not be obtained");
    1262                 :          0 :                 return 0;
    1263                 :            :         }
    1264         [ #  # ]:          0 :         if (rc != 0)
    1265                 :            :                 return rc;
    1266                 :            : 
    1267                 :            :         /* Check that firmware variant was changed to the requested one */
    1268   [ #  #  #  # ]:          0 :         if (preferred_efv != EFX_FW_VARIANT_DONT_CARE && preferred_efv != efv) {
    1269   [ #  #  #  #  :          0 :                 sfc_warn(sa, "FW variant has not changed to the requested %s",
                      # ]
    1270                 :            :                          sfc_fw_variant2str(preferred_efv));
    1271                 :            :         }
    1272                 :            : 
    1273   [ #  #  #  #  :          0 :         sfc_notice(sa, "running FW variant is %s", sfc_fw_variant2str(efv));
                      # ]
    1274                 :            : 
    1275                 :          0 :         return 0;
    1276                 :            : }
    1277                 :            : 
    1278                 :            : int
    1279                 :          0 : sfc_probe(struct sfc_adapter *sa)
    1280                 :            : {
    1281                 :            :         efx_bar_region_t mem_ebrp;
    1282                 :          0 :         struct rte_eth_dev *eth_dev = sa->eth_dev;
    1283                 :          0 :         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
    1284                 :            :         efx_nic_t *enp;
    1285                 :            :         int rc;
    1286                 :            : 
    1287                 :          0 :         sfc_log_init(sa, "entry");
    1288                 :            : 
    1289                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
    1290                 :            : 
    1291                 :          0 :         sa->socket_id = rte_socket_id();
    1292                 :            :         rte_atomic32_init(&sa->restart_required);
    1293                 :            : 
    1294                 :          0 :         sfc_log_init(sa, "get family");
    1295                 :          0 :         rc = sfc_efx_family(pci_dev, &mem_ebrp, &sa->family);
    1296                 :            : 
    1297         [ #  # ]:          0 :         if (rc != 0)
    1298                 :          0 :                 goto fail_family;
    1299                 :          0 :         sfc_log_init(sa,
    1300                 :            :                      "family is %u, membar is %u, function control window offset is %lu",
    1301                 :            :                      sa->family, mem_ebrp.ebr_index, mem_ebrp.ebr_offset);
    1302                 :            : 
    1303                 :          0 :         sfc_log_init(sa, "init mem bar");
    1304                 :            :         rc = sfc_mem_bar_init(sa, &mem_ebrp);
    1305                 :            :         if (rc != 0)
    1306                 :            :                 goto fail_mem_bar_init;
    1307                 :            : 
    1308                 :          0 :         sfc_log_init(sa, "create nic");
    1309                 :            :         rte_spinlock_init(&sa->nic_lock);
    1310                 :          0 :         rc = efx_nic_create(sa->family, (efsys_identifier_t *)sa,
    1311                 :          0 :                             &sa->mem_bar, mem_ebrp.ebr_offset,
    1312                 :          0 :                             &sa->nic_lock, &enp);
    1313         [ #  # ]:          0 :         if (rc != 0)
    1314                 :          0 :                 goto fail_nic_create;
    1315                 :          0 :         sa->nic = enp;
    1316                 :            : 
    1317                 :          0 :         rc = sfc_mcdi_init(sa);
    1318         [ #  # ]:          0 :         if (rc != 0)
    1319                 :          0 :                 goto fail_mcdi_init;
    1320                 :            : 
    1321                 :          0 :         sfc_log_init(sa, "probe nic");
    1322                 :          0 :         rc = sfc_nic_probe(sa);
    1323         [ #  # ]:          0 :         if (rc != 0)
    1324                 :          0 :                 goto fail_nic_probe;
    1325                 :            : 
    1326                 :          0 :         sfc_log_init(sa, "done");
    1327                 :          0 :         return 0;
    1328                 :            : 
    1329                 :            : fail_nic_probe:
    1330                 :          0 :         sfc_mcdi_fini(sa);
    1331                 :            : 
    1332                 :          0 : fail_mcdi_init:
    1333                 :          0 :         sfc_log_init(sa, "destroy nic");
    1334                 :          0 :         sa->nic = NULL;
    1335                 :          0 :         efx_nic_destroy(enp);
    1336                 :            : 
    1337                 :          0 : fail_nic_create:
    1338                 :            :         sfc_mem_bar_fini(sa);
    1339                 :            : 
    1340                 :          0 : fail_mem_bar_init:
    1341                 :          0 : fail_family:
    1342                 :          0 :         sfc_log_init(sa, "failed %d", rc);
    1343                 :          0 :         return rc;
    1344                 :            : }
    1345                 :            : 
    1346                 :            : void
    1347                 :          0 : sfc_unprobe(struct sfc_adapter *sa)
    1348                 :            : {
    1349                 :          0 :         efx_nic_t *enp = sa->nic;
    1350                 :            : 
    1351                 :          0 :         sfc_log_init(sa, "entry");
    1352                 :            : 
    1353                 :            :         SFC_ASSERT(sfc_adapter_is_locked(sa));
    1354                 :            : 
    1355                 :          0 :         sfc_log_init(sa, "unprobe nic");
    1356                 :          0 :         efx_nic_unprobe(enp);
    1357                 :            : 
    1358                 :          0 :         sfc_mcdi_fini(sa);
    1359                 :            : 
    1360                 :            :         /*
    1361                 :            :          * Make sure there is no pending alarm to restart since we are
    1362                 :            :          * going to free device private which is passed as the callback
    1363                 :            :          * opaque data. A new alarm cannot be scheduled since MCDI is
    1364                 :            :          * shut down.
    1365                 :            :          */
    1366                 :          0 :         rte_eal_alarm_cancel(sfc_restart_if_required, sa);
    1367                 :            : 
    1368                 :          0 :         sfc_mae_clear_switch_port(sa->mae.switch_domain_id,
    1369                 :          0 :                                   sa->mae.switch_port_id);
    1370                 :            : 
    1371                 :          0 :         sfc_log_init(sa, "destroy nic");
    1372                 :          0 :         sa->nic = NULL;
    1373                 :          0 :         efx_nic_destroy(enp);
    1374                 :            : 
    1375                 :            :         sfc_mem_bar_fini(sa);
    1376                 :            : 
    1377                 :          0 :         sfc_flow_fini(sa);
    1378                 :          0 :         sa->state = SFC_ETHDEV_UNINITIALIZED;
    1379                 :          0 : }
    1380                 :            : 
    1381                 :            : uint32_t
    1382                 :          0 : sfc_register_logtype(const struct rte_pci_addr *pci_addr,
    1383                 :            :                      const char *lt_prefix_str, uint32_t ll_default)
    1384                 :            : {
    1385                 :          0 :         size_t lt_prefix_str_size = strlen(lt_prefix_str);
    1386                 :            :         size_t lt_str_size_max;
    1387                 :            :         char *lt_str = NULL;
    1388                 :            :         int ret;
    1389                 :            : 
    1390                 :            :         if (SIZE_MAX - PCI_PRI_STR_SIZE - 1 > lt_prefix_str_size) {
    1391                 :          0 :                 ++lt_prefix_str_size; /* Reserve space for prefix separator */
    1392                 :          0 :                 lt_str_size_max = lt_prefix_str_size + PCI_PRI_STR_SIZE + 1;
    1393                 :            :         } else {
    1394                 :            :                 return sfc_logtype_driver;
    1395                 :            :         }
    1396                 :            : 
    1397                 :          0 :         lt_str = rte_zmalloc("logtype_str", lt_str_size_max, 0);
    1398         [ #  # ]:          0 :         if (lt_str == NULL)
    1399                 :          0 :                 return sfc_logtype_driver;
    1400                 :            : 
    1401                 :            :         strncpy(lt_str, lt_prefix_str, lt_prefix_str_size);
    1402                 :          0 :         lt_str[lt_prefix_str_size - 1] = '.';
    1403                 :          0 :         rte_pci_device_name(pci_addr, lt_str + lt_prefix_str_size,
    1404                 :            :                             lt_str_size_max - lt_prefix_str_size);
    1405                 :          0 :         lt_str[lt_str_size_max - 1] = '\0';
    1406                 :            : 
    1407                 :          0 :         ret = rte_log_register_type_and_pick_level(lt_str, ll_default);
    1408                 :          0 :         rte_free(lt_str);
    1409                 :            : 
    1410         [ #  # ]:          0 :         if (ret < 0)
    1411                 :          0 :                 return sfc_logtype_driver;
    1412                 :            : 
    1413                 :          0 :         return ret;
    1414                 :            : }
    1415                 :            : 
    1416                 :            : struct sfc_hw_switch_id {
    1417                 :            :         char    board_sn[RTE_SIZEOF_FIELD(efx_nic_board_info_t, enbi_serial)];
    1418                 :            : };
    1419                 :            : 
    1420                 :            : int
    1421                 :          0 : sfc_hw_switch_id_init(struct sfc_adapter *sa,
    1422                 :            :                       struct sfc_hw_switch_id **idp)
    1423                 :            : {
    1424                 :            :         efx_nic_board_info_t board_info;
    1425                 :            :         struct sfc_hw_switch_id *id;
    1426                 :            :         int rc;
    1427                 :            : 
    1428         [ #  # ]:          0 :         if (idp == NULL)
    1429                 :            :                 return EINVAL;
    1430                 :            : 
    1431                 :          0 :         id = rte_zmalloc("sfc_hw_switch_id", sizeof(*id), 0);
    1432         [ #  # ]:          0 :         if (id == NULL)
    1433                 :            :                 return ENOMEM;
    1434                 :            : 
    1435                 :          0 :         rc = efx_nic_get_board_info(sa->nic, &board_info);
    1436         [ #  # ]:          0 :         if (rc != 0)
    1437                 :            :                 return rc;
    1438                 :            : 
    1439                 :          0 :         memcpy(id->board_sn, board_info.enbi_serial, sizeof(id->board_sn));
    1440                 :            : 
    1441                 :          0 :         *idp = id;
    1442                 :            : 
    1443                 :          0 :         return 0;
    1444                 :            : }
    1445                 :            : 
    1446                 :            : void
    1447                 :          0 : sfc_hw_switch_id_fini(__rte_unused struct sfc_adapter *sa,
    1448                 :            :                       struct sfc_hw_switch_id *id)
    1449                 :            : {
    1450                 :          0 :         rte_free(id);
    1451                 :          0 : }
    1452                 :            : 
    1453                 :            : bool
    1454                 :          0 : sfc_hw_switch_ids_equal(const struct sfc_hw_switch_id *left,
    1455                 :            :                         const struct sfc_hw_switch_id *right)
    1456                 :            : {
    1457                 :          0 :         return strncmp(left->board_sn, right->board_sn,
    1458                 :          0 :                        sizeof(left->board_sn)) == 0;
    1459                 :            : }

Generated by: LCOV version 1.14