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

Reply via email to