[v1,04/19] net/mlx5: add port to metadata conversion
Checks
Commit Message
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(+)
@@ -1540,6 +1540,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. */
@@ -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);
@@ -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__
@@ -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[],
@@ -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.
*