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, &eth_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

Reply via email to