From: Igor Romanov <igor.roma...@oktetlabs.ru> Support probing the device multiple times so that additional port representors can be created with hotplug EAL API. To hotplug a representor, the PF must be hotplugged with different representor device argument.
Signed-off-by: Igor Romanov <igor.roma...@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <andrew.rybche...@oktetlabs.ru> Reviewed-by: Andy Moreton <amore...@xilinx.com> Reviewed-by: Ivan Malov <ivan.ma...@oktetlabs.ru> --- drivers/net/sfc/sfc_ethdev.c | 55 ++++++++++++++++++++++++------------ drivers/net/sfc/sfc_repr.c | 35 +++++++++++++---------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 8578ba0765..8f9afb2c67 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2432,31 +2432,40 @@ sfc_parse_rte_devargs(const char *args, struct rte_eth_devargs *devargs) } static int -sfc_eth_dev_create(struct rte_pci_device *pci_dev, - struct sfc_ethdev_init_data *init_data, - struct rte_eth_dev **devp) +sfc_eth_dev_find_or_create(struct rte_pci_device *pci_dev, + struct sfc_ethdev_init_data *init_data, + struct rte_eth_dev **devp, + bool *dev_created) { struct rte_eth_dev *dev; + bool created = false; int rc; - rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, - sizeof(struct sfc_adapter_shared), - eth_dev_pci_specific_init, pci_dev, - sfc_eth_dev_init, init_data); - if (rc != 0) { - SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", - pci_dev->device.name); - return rc; - } - dev = rte_eth_dev_allocated(pci_dev->device.name); if (dev == NULL) { - SFC_GENERIC_LOG(ERR, "Failed to find allocated sfc ethdev '%s'", + rc = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, + sizeof(struct sfc_adapter_shared), + eth_dev_pci_specific_init, pci_dev, + sfc_eth_dev_init, init_data); + if (rc != 0) { + SFC_GENERIC_LOG(ERR, "Failed to create sfc ethdev '%s'", + pci_dev->device.name); + return rc; + } + + created = true; + + dev = rte_eth_dev_allocated(pci_dev->device.name); + if (dev == NULL) { + SFC_GENERIC_LOG(ERR, + "Failed to find allocated sfc ethdev '%s'", pci_dev->device.name); - return -ENODEV; + return -ENODEV; + } } *devp = dev; + *dev_created = created; return 0; } @@ -2517,6 +2526,7 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct sfc_ethdev_init_data init_data; struct rte_eth_devargs eth_da; struct rte_eth_dev *dev; + bool dev_created; int rc; if (pci_dev->device.devargs != NULL) { @@ -2538,13 +2548,21 @@ static int sfc_eth_dev_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, return -ENOTSUP; } - rc = sfc_eth_dev_create(pci_dev, &init_data, &dev); + /* + * Driver supports RTE_PCI_DRV_PROBE_AGAIN. Hence create device only + * if it does not already exist. Re-probing an existing device is + * expected to allow additional representors to be configured. + */ + rc = sfc_eth_dev_find_or_create(pci_dev, &init_data, &dev, + &dev_created); if (rc != 0) return rc; rc = sfc_eth_dev_create_representors(dev, ð_da); if (rc != 0) { - (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + if (dev_created) + (void)rte_eth_dev_destroy(dev, sfc_eth_dev_uninit); + return rc; } @@ -2560,7 +2578,8 @@ static struct rte_pci_driver sfc_efx_pmd = { .id_table = pci_id_sfc_efx_map, .drv_flags = RTE_PCI_DRV_INTR_LSC | - RTE_PCI_DRV_NEED_MAPPING, + RTE_PCI_DRV_NEED_MAPPING | + RTE_PCI_DRV_PROBE_AGAIN, .probe = sfc_eth_dev_pci_probe, .remove = sfc_eth_dev_pci_remove, }; diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c index 207e7c77a0..7a34a0a904 100644 --- a/drivers/net/sfc/sfc_repr.c +++ b/drivers/net/sfc/sfc_repr.c @@ -930,6 +930,7 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, struct sfc_repr_init_data repr_data; char name[RTE_ETH_NAME_MAX_LEN]; int ret; + struct rte_eth_dev *dev; if (snprintf(name, sizeof(name), "net_%s_representor_%u", parent->device->name, representor_id) >= @@ -938,20 +939,24 @@ sfc_repr_create(struct rte_eth_dev *parent, uint16_t representor_id, return -ENAMETOOLONG; } - memset(&repr_data, 0, sizeof(repr_data)); - repr_data.pf_port_id = parent->data->port_id; - repr_data.repr_id = representor_id; - repr_data.switch_domain_id = switch_domain_id; - repr_data.mport_sel = *mport_sel; - - ret = rte_eth_dev_create(parent->device, name, - sizeof(struct sfc_repr_shared), - NULL, NULL, - sfc_repr_eth_dev_init, &repr_data); - if (ret != 0) - SFC_GENERIC_LOG(ERR, "%s() failed to create device", __func__); - - SFC_GENERIC_LOG(INFO, "%s() done: %s", __func__, rte_strerror(-ret)); + dev = rte_eth_dev_allocated(name); + if (dev == NULL) { + memset(&repr_data, 0, sizeof(repr_data)); + repr_data.pf_port_id = parent->data->port_id; + repr_data.repr_id = representor_id; + repr_data.switch_domain_id = switch_domain_id; + repr_data.mport_sel = *mport_sel; + + ret = rte_eth_dev_create(parent->device, name, + sizeof(struct sfc_repr_shared), + NULL, NULL, + sfc_repr_eth_dev_init, &repr_data); + if (ret != 0) { + SFC_GENERIC_LOG(ERR, "%s() failed to create device", + __func__); + return ret; + } + } - return ret; + return 0; } -- 2.30.2