src/dpdk/drivers/net/sfc/sfc.c
static int
sfc_estimate_resource_limits(struct sfc_adapter *sa)
{
	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
	efx_drv_limits_t limits;
	int rc;
	uint32_t evq_allocated;
	uint32_t rxq_allocated;
	uint32_t txq_allocated;

	memset(&limits, 0, sizeof(limits));

	/* Request at least one Rx and Tx queue */
	limits.edl_min_rxq_count = 1;
	limits.edl_min_txq_count = 1;
	/* Management event queue plus event queue for each Tx and Rx queue */
	limits.edl_min_evq_count =
		1 + limits.edl_min_rxq_count + limits.edl_min_txq_count;

	/* Divide by number of functions to guarantee that all functions
	 * will get promised resources
	 */
	/* FIXME Divide by number of functions (not 2) below */
	limits.edl_max_evq_count = encp->enc_evq_limit / 2;
	SFC_ASSERT(limits.edl_max_evq_count >= limits.edl_min_rxq_count);

	/* Split equally between receive and transmit */
	limits.edl_max_rxq_count =
		MIN(encp->enc_rxq_limit, (limits.edl_max_evq_count - 1) / 2);
	SFC_ASSERT(limits.edl_max_rxq_count >= limits.edl_min_rxq_count);

	limits.edl_max_txq_count =
		MIN(encp->enc_txq_limit,
		    limits.edl_max_evq_count - 1 - limits.edl_max_rxq_count);

	if (sa->tso && encp->enc_fw_assisted_tso_v2_enabled)
		limits.edl_max_txq_count =
			MIN(limits.edl_max_txq_count,
			    encp->enc_fw_assisted_tso_v2_n_contexts /
			    encp->enc_hw_pf_count);

	SFC_ASSERT(limits.edl_max_txq_count >= limits.edl_min_rxq_count);

	/* Configure the minimum required resources needed for the
	 * driver to operate, and the maximum desired resources that the
	 * driver is capable of using.
	 */
	efx_nic_set_drv_limits(sa->nic, &limits);

	sfc_log_init(sa, "init nic");
	rc = efx_nic_init(sa->nic);
	if (rc != 0)
		goto fail_nic_init;

	/* Find resource dimensions assigned by firmware to this function */
	rc = efx_nic_get_vi_pool(sa->nic, &evq_allocated, &rxq_allocated,
				 &txq_allocated);
	if (rc != 0)
		goto fail_get_vi_pool;

	/* It still may allocate more than maximum, ensure limit */
	evq_allocated = MIN(evq_allocated, limits.edl_max_evq_count);
	rxq_allocated = MIN(rxq_allocated, limits.edl_max_rxq_count);
	txq_allocated = MIN(txq_allocated, limits.edl_max_txq_count);

	/* Subtract management EVQ not used for traffic */
	SFC_ASSERT(evq_allocated > 0);
	evq_allocated--;

	/* Right now we use separate EVQ for Rx and Tx */
	sa->rxq_max = MIN(rxq_allocated, evq_allocated / 2);
	sa->txq_max = MIN(txq_allocated, evq_allocated - sa->rxq_max);

	/* Keep NIC initialized */
	return 0;

fail_get_vi_pool:
	efx_nic_fini(sa->nic);
fail_nic_init:
	return rc;
}
/*
 * Find out maximum number of receive and transmit queues which could be
 * advertised.
 *
 * NIC is kept initialized on success to allow other modules acquire
 * defaults and capabilities.
 */
Find out maximum number of receive and transmit queues which could be
advertised.

NIC is kept initialized on success to allow other modules acquire
defaults and capabilities.
Find out maximum number of receive and transmit queues which could be advertised . NIC is kept initialized on success to allow other modules acquire defaults and capabilities .
static int
sfc_estimate_resource_limits(struct sfc_adapter *sa)
{
	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
	efx_drv_limits_t limits;
	int rc;
	uint32_t evq_allocated;
	uint32_t rxq_allocated;
	uint32_t txq_allocated;
	memset(&limits, 0, sizeof(limits));
	limits.edl_min_rxq_count = 1;
	limits.edl_min_txq_count = 1;
	limits.edl_min_evq_count =
		1 + limits.edl_min_rxq_count + limits.edl_min_txq_count;
	limits.edl_max_evq_count = encp->enc_evq_limit / 2;
	SFC_ASSERT(limits.edl_max_evq_count >= limits.edl_min_rxq_count);
	limits.edl_max_rxq_count =
		MIN(encp->enc_rxq_limit, (limits.edl_max_evq_count - 1) / 2);
	SFC_ASSERT(limits.edl_max_rxq_count >= limits.edl_min_rxq_count);
	limits.edl_max_txq_count =
		MIN(encp->enc_txq_limit,
		    limits.edl_max_evq_count - 1 - limits.edl_max_rxq_count);
	if (sa->tso && encp->enc_fw_assisted_tso_v2_enabled)
		limits.edl_max_txq_count =
			MIN(limits.edl_max_txq_count,
			    encp->enc_fw_assisted_tso_v2_n_contexts /
			    encp->enc_hw_pf_count);
	SFC_ASSERT(limits.edl_max_txq_count >= limits.edl_min_rxq_count);
	efx_nic_set_drv_limits(sa->nic, &limits);
	sfc_log_init(sa, "init nic");
	rc = efx_nic_init(sa->nic);
	if (rc != 0)
		goto fail_nic_init;
	rc = efx_nic_get_vi_pool(sa->nic, &evq_allocated, &rxq_allocated,
				 &txq_allocated);
	if (rc != 0)
		goto fail_get_vi_pool;
	evq_allocated = MIN(evq_allocated, limits.edl_max_evq_count);
	rxq_allocated = MIN(rxq_allocated, limits.edl_max_rxq_count);
	txq_allocated = MIN(txq_allocated, limits.edl_max_txq_count);
	SFC_ASSERT(evq_allocated > 0);
	evq_allocated--;
	sa->rxq_max = MIN(rxq_allocated, evq_allocated / 2);
	sa->txq_max = MIN(txq_allocated, evq_allocated - sa->rxq_max);
	return 0;
fail_get_vi_pool:
	efx_nic_fini(sa->nic);
fail_nic_init:
	return rc;
}
static int sfc_estimate_resource_limits ( struct sfc_adapter * sa ) { const efx_nic_cfg_t * encp = efx_nic_cfg_get ( sa -> nic ) ; efx_drv_limits_t limits ; int rc ; uint32_t evq_allocated ; uint32_t rxq_allocated ; uint32_t txq_allocated ; memset ( & limits , 0 , sizeof ( limits ) ) ; limits . edl_min_rxq_count = 1 ; limits . edl_min_txq_count = 1 ; limits . edl_min_evq_count = 1 + limits . edl_min_rxq_count + limits . edl_min_txq_count ; limits . edl_max_evq_count = encp -> enc_evq_limit / 2 ; SFC_ASSERT ( limits . edl_max_evq_count >= limits . edl_min_rxq_count ) ; limits . edl_max_rxq_count = MIN ( encp -> enc_rxq_limit , ( limits . edl_max_evq_count - 1 ) / 2 ) ; SFC_ASSERT ( limits . edl_max_rxq_count >= limits . edl_min_rxq_count ) ; limits . edl_max_txq_count = MIN ( encp -> enc_txq_limit , limits . edl_max_evq_count - 1 - limits . edl_max_rxq_count ) ; if ( sa -> tso && encp -> enc_fw_assisted_tso_v2_enabled ) limits . edl_max_txq_count = MIN ( limits . edl_max_txq_count , encp -> enc_fw_assisted_tso_v2_n_contexts / encp -> enc_hw_pf_count ) ; SFC_ASSERT ( limits . edl_max_txq_count >= limits . edl_min_rxq_count ) ; efx_nic_set_drv_limits ( sa -> nic , & limits ) ; sfc_log_init ( sa , " " ) ; rc = efx_nic_init ( sa -> nic ) ; if ( rc != 0 ) goto fail_nic_init ; rc = efx_nic_get_vi_pool ( sa -> nic , & evq_allocated , & rxq_allocated , & txq_allocated ) ; if ( rc != 0 ) goto fail_get_vi_pool ; evq_allocated = MIN ( evq_allocated , limits . edl_max_evq_count ) ; rxq_allocated = MIN ( rxq_allocated , limits . edl_max_rxq_count ) ; txq_allocated = MIN ( txq_allocated , limits . edl_max_txq_count ) ; SFC_ASSERT ( evq_allocated > 0 ) ; evq_allocated -- ; sa -> rxq_max = MIN ( rxq_allocated , evq_allocated / 2 ) ; sa -> txq_max = MIN ( txq_allocated , evq_allocated - sa -> rxq_max ) ; return 0 ; fail_get_vi_pool : efx_nic_fini ( sa -> nic ) ; fail_nic_init : return rc ; }
Find out maximum number of receive and transmit queues which could be
 advertised.
Find out maximum number of receive and transmit queues which could be advertised .
/* Request at least one Rx and Tx queue */ /* Management event queue plus event queue for each Tx and Rx queue */ /* Divide by number of functions to guarantee that all functions
	 * will get promised resources
	 */ /* FIXME Divide by number of functions (not 2) below */ /* Split equally between receive and transmit */ /* Configure the minimum required resources needed for the
	 * driver to operate, and the maximum desired resources that the
	 * driver is capable of using.
	 */ /* Find resource dimensions assigned by firmware to this function */ /* It still may allocate more than maximum, ensure limit */ /* Subtract management EVQ not used for traffic */ /* Right now we use separate EVQ for Rx and Tx */ /* Keep NIC initialized */