diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 1b2f86f..e93f069 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -927,7 +927,7 @@ struct mlx5_dev_spawn_data {
 		unsigned int c = 0;
 		uint16_t port_id;
 
-		RTE_ETH_FOREACH_DEV_OF(port_id, dev->device) {
+		MLX5_ETH_FOREACH_DEV(port_id) {
 			struct mlx5_priv *opriv =
 				rte_eth_devices[port_id].data->dev_private;
 
@@ -936,6 +936,7 @@ struct mlx5_dev_spawn_data {
 			    &rte_eth_devices[port_id] == dev)
 				continue;
 			++c;
+			break;
 		}
 		if (!c)
 			claim_zero(rte_eth_switch_domain_free(priv->domain_id));
@@ -1855,11 +1856,12 @@ struct mlx5_dev_spawn_data {
 	 * Look for sibling devices in order to reuse their switch domain
 	 * if any, otherwise allocate one.
 	 */
-	RTE_ETH_FOREACH_DEV_OF(port_id, dpdk_dev) {
+	MLX5_ETH_FOREACH_DEV(port_id) {
 		const struct mlx5_priv *opriv =
 			rte_eth_devices[port_id].data->dev_private;
 
 		if (!opriv ||
+		    opriv->sh != priv->sh ||
 			opriv->domain_id ==
 			RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID)
 			continue;
@@ -2732,6 +2734,25 @@ struct mlx5_dev_spawn_data {
 	return ret;
 }
 
+uint16_t
+mlx5_eth_find_next(uint16_t port_id)
+{
+	while (port_id < RTE_MAX_ETHPORTS) {
+		struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+
+		if (dev->state != RTE_ETH_DEV_UNUSED &&
+		    dev->device &&
+		    dev->device->driver &&
+		    dev->device->driver->name &&
+		    !strcmp(dev->device->driver->name, MLX5_DRIVER_NAME))
+			break;
+		port_id++;
+	}
+	if (port_id >= RTE_MAX_ETHPORTS)
+		return RTE_MAX_ETHPORTS;
+	return port_id;
+}
+
 /**
  * DPDK callback to remove a PCI device.
  *
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 87e0549..60bd204 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -681,6 +681,13 @@ int32_t mlx5_release_dbr(struct rte_eth_dev *dev, uint32_t umem_id,
 			 uint64_t offset);
 int mlx5_udp_tunnel_port_add(struct rte_eth_dev *dev,
 			      struct rte_eth_udp_tunnel *udp_tunnel);
+uint16_t mlx5_eth_find_next(uint16_t port_id);
+
+/* Macro to iterate over all valid ports for mlx5 driver. */
+#define MLX5_ETH_FOREACH_DEV(port_id) \
+	for (port_id = mlx5_eth_find_next(0); \
+	     port_id < RTE_MAX_ETHPORTS; \
+	     port_id = mlx5_eth_find_next(port_id + 1))
 
 /* mlx5_ethdev.c */
 
@@ -715,9 +722,6 @@ int mlx5_dev_to_pci_addr(const char *dev_path,
 int mlx5_is_removed(struct rte_eth_dev *dev);
 eth_tx_burst_t mlx5_select_tx_function(struct rte_eth_dev *dev);
 eth_rx_burst_t mlx5_select_rx_function(struct rte_eth_dev *dev);
-unsigned int mlx5_dev_to_port_id(const struct rte_device *dev,
-				 uint16_t *port_list,
-				 unsigned int port_list_n);
 struct mlx5_priv *mlx5_port_to_eswitch_info(uint16_t port);
 struct mlx5_priv *mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev);
 int mlx5_sysfs_switch_info(unsigned int ifindex,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 27372f1..751247d 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -580,16 +580,15 @@ struct ethtool_link_settings {
 	info->switch_info.domain_id = priv->domain_id;
 	info->switch_info.port_id = priv->representor_id;
 	if (priv->representor) {
-		unsigned int i = mlx5_dev_to_port_id(dev->device, NULL, 0);
-		uint16_t port_id[i];
+		uint16_t port_id;
 
-		i = RTE_MIN(mlx5_dev_to_port_id(dev->device, port_id, i), i);
-		while (i--) {
+		MLX5_ETH_FOREACH_DEV(port_id) {
 			struct mlx5_priv *opriv =
-				rte_eth_devices[port_id[i]].data->dev_private;
+				rte_eth_devices[port_id].data->dev_private;
 
 			if (!opriv ||
 			    opriv->representor ||
+			    opriv->sh != priv->sh ||
 			    opriv->domain_id != priv->domain_id)
 				continue;
 			/*
@@ -600,7 +599,6 @@ struct ethtool_link_settings {
 			break;
 		}
 	}
-
 	return 0;
 }
 
@@ -717,11 +715,13 @@ int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
 	priv = dev->data->dev_private;
 	domain_id = priv->domain_id;
 	assert(priv->representor);
-	RTE_ETH_FOREACH_DEV_OF(port_id, dev->device) {
-		priv = rte_eth_devices[port_id].data->dev_private;
-		if (priv &&
-		    priv->master &&
-		    priv->domain_id == domain_id)
+	MLX5_ETH_FOREACH_DEV(port_id) {
+		struct mlx5_priv *opriv =
+			rte_eth_devices[port_id].data->dev_private;
+		if (opriv &&
+		    opriv->master &&
+		    opriv->domain_id == domain_id &&
+		    opriv->sh == priv->sh)
 			return &rte_eth_devices[port_id];
 	}
 	return NULL;
@@ -1630,36 +1630,6 @@ int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
 }
 
 /**
- * Get port ID list of mlx5 instances sharing a common device.
- *
- * @param[in] dev
- *   Device to look for.
- * @param[out] port_list
- *   Result buffer for collected port IDs.
- * @param port_list_n
- *   Maximum number of entries in result buffer. If 0, @p port_list can be
- *   NULL.
- *
- * @return
- *   Number of matching instances regardless of the @p port_list_n
- *   parameter, 0 if none were found.
- */
-unsigned int
-mlx5_dev_to_port_id(const struct rte_device *dev, uint16_t *port_list,
-		    unsigned int port_list_n)
-{
-	uint16_t id;
-	unsigned int n = 0;
-
-	RTE_ETH_FOREACH_DEV_OF(id, dev) {
-		if (n < port_list_n)
-			port_list[n] = id;
-		n++;
-	}
-	return n;
-}
-
-/**
  * Get the E-Switch parameters by port id.
  *
  * @param[in] port
