From: Dariusz Sosnowski <dsosnow...@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 <dsosnow...@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c | 10 +++++-
 drivers/net/mlx5/mlx5.c          |  1 +
 drivers/net/mlx5/mlx5_flow.c     |  6 ++++
 drivers/net/mlx5/mlx5_flow.h     | 52 ++++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_flow_hw.c  | 29 ++++++++++++++++++
 5 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 3e505d8f4c..d1e7bcce57 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1554,8 +1554,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
        if (!priv->hrxqs)
                goto error;
        rte_rwlock_init(&priv->ind_tbls_lock);
-       if (priv->sh->config.dv_flow_en == 2)
+       if (priv->sh->config.dv_flow_en == 2) {
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+               if (priv->vport_meta_mask)
+                       flow_hw_set_port_info(eth_dev);
                return eth_dev;
+#else
+               DRV_LOG(ERR, "DV support is missing for HWS.");
+               goto error;
+#endif
+       }
        /* Port representor shares the same max priority with pf port. */
        if (!priv->sh->flow_priority_check_flag) {
                /* Supported Verbs flow priority number detection. */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 752b60d769..1d10932619 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1944,6 +1944,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
        mlx5_flex_item_port_cleanup(dev);
 #if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
        flow_hw_resource_release(dev);
+       flow_hw_clear_port_info(dev);
 #endif
        if (priv->rxq_privs != NULL) {
                /* XXX race condition if mlx5_rx_burst() is still running. */
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 026d77b01f..72f4374c07 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 3537eb3d66..c0c719dd8b 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1326,6 +1326,58 @@ 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;
+}
+
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+/*
+ * 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;
+}
+#endif
+
+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 b168ff9e7e..765e5164cb 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -2211,6 +2211,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.
  *
-- 
2.18.1

Reply via email to