Allow running mlx5 PMD on top of a device with switchdev enabled,
where vport metadata is disabled (esw_port_metadata devlink parameter
is set to false). This requires:
- Preceding patches introducing source vport match capabilities
in HWS layer.
- Removing the check for vport metadata during port probing
(it previously was one of the requirements).
- Modify Tx representor matching flow rules logic when vport metadata
is not available - instead of metadata, match on vport ID.
- vport ID is enough, because any shared FDB use case
required vport metadata to be enabled.
- Disable internal usage of unified FDB, when vport metadata
is not available.
- Force internal usage of source_vport match on root flow rules,
when vport metadata is not available.
Signed-off-by: Dariusz Sosnowski <[email protected]>
---
drivers/net/mlx5/linux/mlx5_os.c | 34 +++++++-------------------------
drivers/net/mlx5/mlx5.h | 1 +
drivers/net/mlx5/mlx5_flow_dv.c | 3 +++
drivers/net/mlx5/mlx5_flow_hw.c | 28 +++++++++-----------------
4 files changed, 20 insertions(+), 46 deletions(-)
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 75a2936023..a9dd0be055 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1866,7 +1866,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
* 3. with unsupported FW
* 4. all representors in HWS
*/
- priv->unified_fdb_en = !!priv->master &&
sh->cdev->config.hca_attr.fdb_unified_en;
+ priv->unified_fdb_en = sh->cdev->config.hca_attr.fdb_unified_en
&&
+ priv->master &&
+ priv->vport_meta_mask != 0;
/* Jump FDB Rx works only with unified FDB enabled. */
if (priv->unified_fdb_en)
priv->jump_fdb_rx_en =
sh->cdev->config.hca_attr.jump_fdb_rx_en;
@@ -1874,32 +1876,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
eth_dev->data->port_id,
priv->unified_fdb_en ? "is" : "isn't",
priv->jump_fdb_rx_en ? "is" : "isn't");
- if (priv->sh->config.dv_esw_en) {
- uint32_t usable_bits;
- uint32_t required_bits;
-
- if (priv->sh->dv_regc0_mask == UINT32_MAX) {
- DRV_LOG(ERR, "E-Switch port metadata is
required when using HWS "
- "but it is disabled (configure it
through devlink)");
- err = ENOTSUP;
- goto error;
- }
- if (priv->sh->dv_regc0_mask == 0) {
- DRV_LOG(ERR, "E-Switch with HWS is not
supported "
- "(no available bits in reg_c[0])");
- err = ENOTSUP;
- goto error;
- }
- usable_bits = rte_popcount32(priv->sh->dv_regc0_mask);
- required_bits = rte_popcount32(priv->vport_meta_mask);
- if (usable_bits < required_bits) {
- DRV_LOG(ERR, "Not enough bits available in
reg_c[0] to provide "
- "representor matching.");
- err = ENOTSUP;
- goto error;
- }
- }
- if (priv->vport_meta_mask)
+ /* Without vport metadata, PMD must rely on source_vport match.
*/
+ if (priv->sh->config.dv_esw_en && priv->vport_meta_mask == 0)
+ priv->vport_match = 1;
+ if (priv->sh->config.dv_esw_en)
mlx5_flow_hw_set_port_info(eth_dev);
if (priv->sh->config.dv_esw_en &&
priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 8cd6562633..7e8ef1d467 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -2003,6 +2003,7 @@ struct mlx5_priv {
uint32_t tunnel_enabled:1; /* If tunnel offloading is enabled on rxqs.
*/
uint32_t unified_fdb_en:1; /* Unified FDB flag per port. */
uint32_t jump_fdb_rx_en:1; /* Jump from FDB Tx to FDB Rx flag per port.
*/
+ uint32_t vport_match:1; /* True if source_vport match is used instead
of metadata */
uint16_t domain_id; /* Switch domain identifier. */
uint16_t vport_id; /* Associated VF vport index (if any). */
uint16_t vport_vhca_id; /* VHCA ID of the associated vport (if any). */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 32e75b063f..c2a2874913 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -11050,6 +11050,9 @@ flow_dv_translate_item_represented_port(struct
rte_eth_dev *dev, void *key,
#ifndef HAVE_IBV_DEVICE_ATTR_ESW_MGR_REG_C0
if (priv->sh->config.dv_flow_en == 2)
vport_match = true;
+#else
+ if (priv->sh->config.dv_flow_en == 2)
+ vport_match = !!priv->vport_match;
#endif
if (!pid_m && !pid_v)
return 0;
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 4871594c35..b6bb9f12a6 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -9939,33 +9939,23 @@ static __rte_always_inline uint32_t
flow_hw_tx_tag_regc_mask(struct rte_eth_dev *dev)
{
struct mlx5_priv *priv = dev->data->dev_private;
- uint32_t mask = priv->sh->dv_regc0_mask;
- /* Mask is verified during device initialization. Sanity checking here.
*/
- MLX5_ASSERT(mask != 0);
- /*
- * Availability of sufficient number of bits in REG_C_0 is verified on
initialization.
- * Sanity checking here.
- */
- MLX5_ASSERT(rte_popcount32(mask) >=
rte_popcount32(priv->vport_meta_mask));
- return mask;
+ if (priv->vport_meta_mask != 0)
+ return priv->sh->dv_regc0_mask;
+ else
+ return UINT32_MAX;
}
static __rte_always_inline uint32_t
flow_hw_tx_tag_regc_value(struct rte_eth_dev *dev)
{
struct mlx5_priv *priv = dev->data->dev_private;
- uint32_t tag;
- /* Mask is verified during device initialization. Sanity checking here.
*/
- MLX5_ASSERT(priv->vport_meta_mask != 0);
- tag = priv->vport_meta_tag >> (rte_bsf32(priv->vport_meta_mask));
- /*
- * Availability of sufficient number of bits in REG_C_0 is verified on
initialization.
- * Sanity checking here.
- */
- MLX5_ASSERT((tag & priv->sh->dv_regc0_mask) == tag);
- return tag;
+ if (priv->vport_meta_mask != 0)
+ return priv->vport_meta_tag >>
(rte_bsf32(priv->vport_meta_mask));
+
+ /* Without REG_C match value available, resort to matching vport ID. */
+ return priv->vport_id | (priv->sh->cdev->config.hca_attr.vhca_id << 16);
}
static void
--
2.47.3