[v2,04/19] net/mlx5: add port to metadata conversion

Message ID 20221006150325.660-5-valex@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Raslan Darawsheh
Headers
Series net/mlx5: Add HW steering low level support |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Alex Vesker Oct. 6, 2022, 3:03 p.m. UTC
  From: Dariusz Sosnowski <dsosnowski@nvidia.com>

This patch initial version of functions used to:

- convert between ethdev port_id and internal tag/mask value,
- convert between IB context and internal tag/mask value.

Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c |  2 ++
 drivers/net/mlx5/mlx5.c          |  1 +
 drivers/net/mlx5/mlx5_flow.c     |  6 ++++
 drivers/net/mlx5/mlx5_flow.h     | 50 ++++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c  | 29 ++++++++++++++++++
 5 files changed, 88 insertions(+)
  

Patch

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 60677eb8d7..1036b870de 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1541,6 +1541,8 @@  mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (!priv->hrxqs)
 		goto error;
 	rte_rwlock_init(&priv->ind_tbls_lock);
+	if (priv->vport_meta_mask)
+		flow_hw_set_port_info(eth_dev);
 	if (priv->sh->config.dv_flow_en == 2)
 		return eth_dev;
 	/* Port representor shares the same max priority with pf port. */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 752b60d769..ad561bd86d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1945,6 +1945,7 @@  mlx5_dev_close(struct rte_eth_dev *dev)
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
 	flow_hw_resource_release(dev);
 #endif
+	flow_hw_clear_port_info(dev);
 	if (priv->rxq_privs != NULL) {
 		/* XXX race condition if mlx5_rx_burst() is still running. */
 		rte_delay_us_sleep(1000);
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index e4744b0a67..acf1467bf6 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -33,6 +33,12 @@ 
 #include "mlx5_common_os.h"
 #include "rte_pmd_mlx5.h"
 
+/*
+ * Shared array for quick translation between port_id and vport mask/values
+ * used for HWS rules.
+ */
+struct flow_hw_port_info mlx5_flow_hw_port_infos[RTE_MAX_ETHPORTS];
+
 struct tunnel_default_miss_ctx {
 	uint16_t *queue;
 	__extension__
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 86a08074dc..2eb2b46060 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1320,6 +1320,56 @@  struct mlx5_flow_split_info {
 	uint64_t prefix_layers; /**< Prefix subflow layers. */
 };
 
+struct flow_hw_port_info {
+	uint32_t regc_mask;
+	uint32_t regc_value;
+	uint32_t is_wire:1;
+};
+
+extern struct flow_hw_port_info mlx5_flow_hw_port_infos[RTE_MAX_ETHPORTS];
+
+/*
+ * Get metadata match tag and mask for given rte_eth_dev port.
+ * Used in HWS rule creation.
+ */
+static __rte_always_inline const struct flow_hw_port_info *
+flow_hw_conv_port_id(const uint16_t port_id)
+{
+	struct flow_hw_port_info *port_info;
+
+	if (port_id >= RTE_MAX_ETHPORTS)
+		return NULL;
+	port_info = &mlx5_flow_hw_port_infos[port_id];
+	return !!port_info->regc_mask ? port_info : NULL;
+}
+
+/*
+ * Get metadata match tag and mask for the uplink port represented
+ * by given IB context. Used in HWS context creation.
+ */
+static __rte_always_inline const struct flow_hw_port_info *
+flow_hw_get_wire_port(struct ibv_context *ibctx)
+{
+	struct ibv_device *ibdev = ibctx->device;
+	uint16_t port_id;
+
+	MLX5_ETH_FOREACH_DEV(port_id, NULL) {
+		const struct mlx5_priv *priv =
+				rte_eth_devices[port_id].data->dev_private;
+
+		if (priv && priv->master) {
+			struct ibv_context *port_ibctx = priv->sh->cdev->ctx;
+
+			if (port_ibctx->device == ibdev)
+				return flow_hw_conv_port_id(port_id);
+		}
+	}
+	return NULL;
+}
+
+void flow_hw_set_port_info(struct rte_eth_dev *dev);
+void flow_hw_clear_port_info(struct rte_eth_dev *dev);
+
 typedef int (*mlx5_flow_validate_t)(struct rte_eth_dev *dev,
 				    const struct rte_flow_attr *attr,
 				    const struct rte_flow_item items[],
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 12498794a5..fe809a83b9 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2208,6 +2208,35 @@  flow_hw_resource_release(struct rte_eth_dev *dev)
 	priv->nb_queue = 0;
 }
 
+/* Sets vport tag and mask, for given port, used in HWS rules. */
+void
+flow_hw_set_port_info(struct rte_eth_dev *dev)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	uint16_t port_id = dev->data->port_id;
+	struct flow_hw_port_info *info;
+
+	MLX5_ASSERT(port_id < RTE_MAX_ETHPORTS);
+	info = &mlx5_flow_hw_port_infos[port_id];
+	info->regc_mask = priv->vport_meta_mask;
+	info->regc_value = priv->vport_meta_tag;
+	info->is_wire = priv->master;
+}
+
+/* Clears vport tag and mask used for HWS rules. */
+void
+flow_hw_clear_port_info(struct rte_eth_dev *dev)
+{
+	uint16_t port_id = dev->data->port_id;
+	struct flow_hw_port_info *info;
+
+	MLX5_ASSERT(port_id < RTE_MAX_ETHPORTS);
+	info = &mlx5_flow_hw_port_infos[port_id];
+	info->regc_mask = 0;
+	info->regc_value = 0;
+	info->is_wire = 0;
+}
+
 /**
  * Create shared action.
  *