If multiple ports share the same hardware device (rte_device),
they are siblings and can be found thanks to the new function
and loop macro.

The ownership is not checked because siblings may have
different owners.

Signed-off-by: Thomas Monjalon <tho...@monjalon.net>
---
 lib/librte_ethdev/rte_ethdev.c           | 15 +++++++++++++++
 lib/librte_ethdev/rte_ethdev.h           | 23 +++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_version.map |  1 +
 3 files changed, 39 insertions(+)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 5f858174b..11e0ade6e 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -341,6 +341,21 @@ rte_eth_find_next(uint16_t port_id)
        return port_id;
 }
 
+uint16_t __rte_experimental
+rte_eth_find_next_sibling(uint16_t port_id, uint16_t ref)
+{
+       while (port_id < RTE_MAX_ETHPORTS &&
+                       rte_eth_devices[port_id].state == RTE_ETH_DEV_UNUSED &&
+                       rte_eth_devices[port_id].device !=
+                               rte_eth_devices[ref].device)
+               port_id++;
+
+       if (port_id >= RTE_MAX_ETHPORTS)
+               return RTE_MAX_ETHPORTS;
+
+       return port_id;
+}
+
 static void
 rte_eth_dev_shared_data_prepare(void)
 {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 1960f3a2d..647e6634d 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1383,6 +1383,29 @@ uint16_t rte_eth_find_next(uint16_t port_id);
 #define RTE_ETH_FOREACH_DEV(p) \
        RTE_ETH_FOREACH_DEV_OWNED_BY(p, RTE_ETH_DEV_NO_OWNER)
 
+/**
+ * Iterates over sibling ethdev ports (i.e. sharing the same rte_device).
+ *
+ * @param port_id_start
+ *   The id of the next possible valid sibling port.
+ * @param ref
+ *   The id of a reference port to compare rte_device with.
+ * @return
+ *   Next sibling port id (or ref itself), RTE_MAX_ETHPORTS if there is none.
+ */
+__rte_experimental
+uint16_t rte_eth_find_next_sibling(uint16_t port_id_start, uint16_t ref);
+
+/**
+ * Macro to iterate over all ethdev ports sharing the same rte_device
+ * as the specified port.
+ * Note: the specified port is part of the loop iterations.
+ */
+#define RTE_ETH_FOREACH_DEV_SIBLING(p, ref) \
+       for (p = rte_eth_find_next_sibling(0, ref); \
+               p < RTE_MAX_ETHPORTS; \
+               p = rte_eth_find_next_sibling(p + 1, ref))
+
 
 /**
  * @warning
diff --git a/lib/librte_ethdev/rte_ethdev_version.map 
b/lib/librte_ethdev/rte_ethdev_version.map
index 92ac3de25..a0c930d04 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -245,6 +245,7 @@ EXPERIMENTAL {
        rte_eth_dev_owner_set;
        rte_eth_dev_owner_unset;
        rte_eth_dev_rx_intr_ctl_q_get_fd;
+       rte_eth_find_next_sibling;
        rte_eth_switch_domain_alloc;
        rte_eth_switch_domain_free;
        rte_flow_conv;
-- 
2.19.0

Reply via email to