dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
+ dev_info->max_vfs = sa->sriov.num_vfs;
+
/* Autonegotiation may be disabled */
dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
if (sa->port.phy_adv_cap_mask & (1u << EFX_PHY_CAP_1000FDX))
return ret;
}
-static void
+static int
sfc_dev_stop(struct rte_eth_dev *dev)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
sfc_adapter_unlock(sa);
sfc_log_init(sa, "done");
+
+ return 0;
}
static int
}
static void
+sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev)
+{
+ free(dev->process_private);
+ rte_eth_dev_release_port(dev);
+}
+
+static int
sfc_dev_close(struct rte_eth_dev *dev)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
sfc_log_init(sa, "entry");
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ sfc_eth_dev_secondary_clear_ops(dev);
+ return 0;
+ }
+
sfc_adapter_lock(sa);
switch (sa->state) {
case SFC_ADAPTER_STARTED:
}
/*
- * Cleanup all resources in accordance with RTE_ETH_DEV_CLOSE_REMOVE.
+ * Cleanup all resources.
* Rollback primary process sfc_eth_dev_init() below.
*/
/* Required for logging, so cleanup last */
sa->eth_dev = NULL;
- dev->process_private = NULL;
free(sa);
+
+ return 0;
}
static int
if (!sfc_rx_check_scatter(pdu, sa->rxq_ctrl[i].buf_size,
encp->enc_rx_prefix_size,
- scatter_enabled, &error)) {
+ scatter_enabled,
+ encp->enc_rx_scatter_max, &error)) {
sfc_err(sa, "MTU check for RxQ %u failed: %s", i,
error);
return EINVAL;
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
struct sfc_rss *rss = &sfc_sa2shared(sa)->rss;
unsigned int efx_hash_types;
+ uint32_t contexts[] = {EFX_RSS_CONTEXT_DEFAULT, rss->dummy_rss_context};
+ unsigned int n_contexts;
+ unsigned int mode_i = 0;
+ unsigned int key_i = 0;
+ unsigned int i = 0;
int rc = 0;
+ n_contexts = rss->dummy_rss_context == EFX_RSS_CONTEXT_DEFAULT ? 1 : 2;
+
if (sfc_sa2shared(sa)->isolated)
return -ENOTSUP;
if (rc != 0)
goto fail_rx_hf_rte_to_efx;
- rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT,
- rss->hash_alg, efx_hash_types, B_TRUE);
- if (rc != 0)
- goto fail_scale_mode_set;
+ for (mode_i = 0; mode_i < n_contexts; mode_i++) {
+ rc = efx_rx_scale_mode_set(sa->nic, contexts[mode_i],
+ rss->hash_alg, efx_hash_types,
+ B_TRUE);
+ if (rc != 0)
+ goto fail_scale_mode_set;
+ }
if (rss_conf->rss_key != NULL) {
if (sa->state == SFC_ADAPTER_STARTED) {
- rc = efx_rx_scale_key_set(sa->nic,
- EFX_RSS_CONTEXT_DEFAULT,
- rss_conf->rss_key,
- sizeof(rss->key));
- if (rc != 0)
- goto fail_scale_key_set;
+ for (key_i = 0; key_i < n_contexts; key_i++) {
+ rc = efx_rx_scale_key_set(sa->nic,
+ contexts[key_i],
+ rss_conf->rss_key,
+ sizeof(rss->key));
+ if (rc != 0)
+ goto fail_scale_key_set;
+ }
}
rte_memcpy(rss->key, rss_conf->rss_key, sizeof(rss->key));
return 0;
fail_scale_key_set:
- if (efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT,
- EFX_RX_HASHALG_TOEPLITZ,
- rss->hash_types, B_TRUE) != 0)
- sfc_err(sa, "failed to restore RSS mode");
+ for (i = 0; i < key_i; i++) {
+ if (efx_rx_scale_key_set(sa->nic, contexts[i], rss->key,
+ sizeof(rss->key)) != 0)
+ sfc_err(sa, "failed to restore RSS key");
+ }
fail_scale_mode_set:
+ for (i = 0; i < mode_i; i++) {
+ if (efx_rx_scale_mode_set(sa->nic, contexts[i],
+ EFX_RX_HASHALG_TOEPLITZ,
+ rss->hash_types, B_TRUE) != 0)
+ sfc_err(sa, "failed to restore RSS mode");
+ }
+
fail_rx_hf_rte_to_efx:
sfc_adapter_unlock(sa);
return -rc;
case EFX_FAMILY_MEDFORD:
case EFX_FAMILY_MEDFORD2:
avail_caps |= SFC_DP_HW_FW_CAP_EF10;
+ avail_caps |= SFC_DP_HW_FW_CAP_RX_EFX;
+ avail_caps |= SFC_DP_HW_FW_CAP_TX_EFX;
+ break;
+ case EFX_FAMILY_RIVERHEAD:
+ avail_caps |= SFC_DP_HW_FW_CAP_EF100;
break;
default:
break;
return rc;
}
-static void
-sfc_eth_dev_secondary_clear_ops(struct rte_eth_dev *dev)
-{
- free(dev->process_private);
- dev->process_private = NULL;
- dev->dev_ops = NULL;
- dev->tx_pkt_prepare = NULL;
- dev->tx_pkt_burst = NULL;
- dev->rx_pkt_burst = NULL;
-}
-
static void
sfc_register_dp(void)
{
/* Register once */
if (TAILQ_EMPTY(&sfc_dp_head)) {
/* Prefer EF10 datapath */
+ sfc_dp_register(&sfc_dp_head, &sfc_ef100_rx.dp);
sfc_dp_register(&sfc_dp_head, &sfc_ef10_essb_rx.dp);
sfc_dp_register(&sfc_dp_head, &sfc_ef10_rx.dp);
sfc_dp_register(&sfc_dp_head, &sfc_efx_rx.dp);
+ sfc_dp_register(&sfc_dp_head, &sfc_ef100_tx.dp);
sfc_dp_register(&sfc_dp_head, &sfc_ef10_tx.dp);
sfc_dp_register(&sfc_dp_head, &sfc_efx_tx.dp);
sfc_dp_register(&sfc_dp_head, &sfc_ef10_simple_tx.dp);
int rc;
const efx_nic_cfg_t *encp;
const struct rte_ether_addr *from;
+ int ret;
sfc_register_dp();
return -sfc_eth_dev_secondary_init(dev, logtype_main);
/* Required for logging */
+ ret = snprintf(sas->log_prefix, sizeof(sas->log_prefix),
+ "PMD: sfc_efx " PCI_PRI_FMT " #%" PRIu16 ": ",
+ pci_dev->addr.domain, pci_dev->addr.bus,
+ pci_dev->addr.devid, pci_dev->addr.function,
+ dev->data->port_id);
+ if (ret < 0 || ret >= (int)sizeof(sas->log_prefix)) {
+ SFC_GENERIC_LOG(ERR,
+ "reserved log prefix is too short for " PCI_PRI_FMT,
+ pci_dev->addr.domain, pci_dev->addr.bus,
+ pci_dev->addr.devid, pci_dev->addr.function);
+ return -EINVAL;
+ }
sas->pci_addr = pci_dev->addr;
sas->port_id = dev->data->port_id;
/* Copy PCI device info to the dev->data */
rte_eth_copy_pci_info(dev, pci_dev);
+ dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
rc = sfc_kvargs_parse(sa);
if (rc != 0)
sfc_log_init(sa, "entry");
- dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
-
dev->data->mac_addrs = rte_zmalloc("sfc", RTE_ETHER_ADDR_LEN, 0);
if (dev->data->mac_addrs == NULL) {
rc = ENOMEM;
static int
sfc_eth_dev_uninit(struct rte_eth_dev *dev)
{
- if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
- sfc_eth_dev_secondary_clear_ops(dev);
- return 0;
- }
-
sfc_dev_close(dev);
return 0;
{ RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD_VF) },
{ RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD2) },
{ RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD2_VF) },
+ { RTE_PCI_DEVICE(EFX_PCI_VENID_XILINX, EFX_PCI_DEVID_RIVERHEAD) },
{ .vendor_id = 0 /* sentinel */ }
};