From 5bd0e3e671c4caec6f70426f164ea383fbf2b7d8 Mon Sep 17 00:00:00 2001 From: Dariusz Sosnowski Date: Thu, 20 Oct 2022 18:57:34 +0300 Subject: [PATCH] net/mlx5: add port to metadata conversion This adds conversion functions between both ethdev port_id and IB context to internal corresponding tag/mask values. Signed-off-by: Dariusz Sosnowski --- 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 fce30cbeb6..8a04d8640b 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 ab88c1e66a..fb82ab5aba 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. *