net/mlx5: update metadata register ID query
authorViacheslav Ovsiienko <viacheslavo@mellanox.com>
Thu, 7 Nov 2019 17:09:57 +0000 (17:09 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 11 Nov 2019 13:23:02 +0000 (14:23 +0100)
The NIC might support up to 8 extensive metadata registers.
These registers are supposed to be used by multiple features.
There is register id query routine to allow determine which
register is actually used by specified feature.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
drivers/net/mlx5/mlx5_flow.c
drivers/net/mlx5/mlx5_flow.h

index d54537a..9d011d4 100644 (file)
@@ -320,12 +320,6 @@ static struct mlx5_flow_tunnel_info tunnels_info[] = {
        },
 };
 
-enum mlx5_feature_name {
-       MLX5_HAIRPIN_RX,
-       MLX5_HAIRPIN_TX,
-       MLX5_APPLICATION,
-};
-
 /**
  * Translate tag ID to register.
  *
@@ -342,37 +336,70 @@ enum mlx5_feature_name {
  *   The request register on success, a negative errno
  *   value otherwise and rte_errno is set.
  */
-__rte_unused
-static enum modify_reg flow_get_reg_id(struct rte_eth_dev *dev,
-                                      enum mlx5_feature_name feature,
-                                      uint32_t id,
-                                      struct rte_flow_error *error)
+enum modify_reg
+mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
+                    enum mlx5_feature_name feature,
+                    uint32_t id,
+                    struct rte_flow_error *error)
 {
-       static enum modify_reg id2reg[] = {
-               [0] = REG_A,
-               [1] = REG_C_2,
-               [2] = REG_C_3,
-               [3] = REG_C_4,
-               [4] = REG_B,};
-
-       dev = (void *)dev;
+       struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_dev_config *config = &priv->config;
+
        switch (feature) {
        case MLX5_HAIRPIN_RX:
                return REG_B;
        case MLX5_HAIRPIN_TX:
                return REG_A;
-       case MLX5_APPLICATION:
-               if (id > 4)
-                       return rte_flow_error_set(error, EINVAL,
-                                                 RTE_FLOW_ERROR_TYPE_ITEM,
-                                                 NULL, "invalid tag id");
-               return id2reg[id];
+       case MLX5_METADATA_RX:
+               switch (config->dv_xmeta_en) {
+               case MLX5_XMETA_MODE_LEGACY:
+                       return REG_B;
+               case MLX5_XMETA_MODE_META16:
+                       return REG_C_0;
+               case MLX5_XMETA_MODE_META32:
+                       return REG_C_1;
+               }
+               break;
+       case MLX5_METADATA_TX:
+               return REG_A;
+       case MLX5_METADATA_FDB:
+               return REG_C_0;
+       case MLX5_FLOW_MARK:
+               switch (config->dv_xmeta_en) {
+               case MLX5_XMETA_MODE_LEGACY:
+                       return REG_NONE;
+               case MLX5_XMETA_MODE_META16:
+                       return REG_C_1;
+               case MLX5_XMETA_MODE_META32:
+                       return REG_C_0;
+               }
+               break;
+       case MLX5_COPY_MARK:
+               return REG_C_3;
+       case MLX5_APP_TAG:
+               /*
+                * Suppose engaging reg_c_2 .. reg_c_7 registers.
+                * reg_c_2 is reserved for coloring by meters.
+                * reg_c_3 is reserved for split flows TAG.
+                */
+               if (id > (REG_C_7 - REG_C_4))
+                       return rte_flow_error_set
+                                       (error, EINVAL,
+                                        RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                        NULL, "invalid tag id");
+               if (config->flow_mreg_c[id + REG_C_4 - REG_C_0] == REG_NONE)
+                       return rte_flow_error_set
+                                       (error, ENOTSUP,
+                                        RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                        NULL, "unsupported tag id");
+               return config->flow_mreg_c[id + REG_C_4 - REG_C_0];
        }
-       return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
+       assert(false);
+       return rte_flow_error_set(error, EINVAL,
+                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
                                  NULL, "invalid feature name");
 }
 
-
 /**
  * Check extensive flow metadata register support.
  *
@@ -2685,7 +2712,6 @@ flow_hairpin_split(struct rte_eth_dev *dev,
        struct mlx5_rte_flow_item_tag *tag_item;
        struct rte_flow_item *item;
        char *addr;
-       struct rte_flow_error error;
        int encap = 0;
 
        mlx5_flow_id_get(priv->sh->flow_id_pool, flow_id);
@@ -2751,7 +2777,8 @@ flow_hairpin_split(struct rte_eth_dev *dev,
        rte_memcpy(actions_rx, actions, sizeof(struct rte_flow_action));
        actions_rx++;
        set_tag = (void *)actions_rx;
-       set_tag->id = flow_get_reg_id(dev, MLX5_HAIRPIN_RX, 0, &error);
+       set_tag->id = mlx5_flow_get_reg_id(dev, MLX5_HAIRPIN_RX, 0, NULL);
+       assert(set_tag->id > REG_NONE);
        set_tag->data = *flow_id;
        tag_action->conf = set_tag;
        /* Create Tx item list. */
@@ -2761,7 +2788,8 @@ flow_hairpin_split(struct rte_eth_dev *dev,
        item->type = MLX5_RTE_FLOW_ITEM_TYPE_TAG;
        tag_item = (void *)addr;
        tag_item->data = *flow_id;
-       tag_item->id = flow_get_reg_id(dev, MLX5_HAIRPIN_TX, 0, NULL);
+       tag_item->id = mlx5_flow_get_reg_id(dev, MLX5_HAIRPIN_TX, 0, NULL);
+       assert(set_tag->id > REG_NONE);
        item->spec = tag_item;
        addr += sizeof(struct mlx5_rte_flow_item_tag);
        tag_item = (void *)addr;
index a8f4e5c..d716b44 100644 (file)
@@ -63,6 +63,18 @@ struct mlx5_rte_flow_item_tx_queue {
        uint32_t queue;
 };
 
+/* Feature name to allocate metadata register. */
+enum mlx5_feature_name {
+       MLX5_HAIRPIN_RX,
+       MLX5_HAIRPIN_TX,
+       MLX5_METADATA_RX,
+       MLX5_METADATA_TX,
+       MLX5_METADATA_FDB,
+       MLX5_FLOW_MARK,
+       MLX5_APP_TAG,
+       MLX5_COPY_MARK,
+};
+
 /* Pattern outer Layer bits. */
 #define MLX5_FLOW_LAYER_OUTER_L2 (1u << 0)
 #define MLX5_FLOW_LAYER_OUTER_L3_IPV4 (1u << 1)
@@ -534,6 +546,7 @@ struct mlx5_flow_driver_ops {
        mlx5_flow_query_t query;
 };
 
+
 #define MLX5_CNT_CONTAINER(sh, batch, thread) (&(sh)->cmng.ccont \
        [(((sh)->cmng.mhi[batch] >> (thread)) & 0x1) * 2 + (batch)])
 #define MLX5_CNT_CONTAINER_UNUSED(sh, batch, thread) (&(sh)->cmng.ccont \
@@ -554,6 +567,10 @@ uint64_t mlx5_flow_hashfields_adjust(struct mlx5_flow *dev_flow, int tunnel,
                                     uint64_t hash_fields);
 uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,
                                   uint32_t subpriority);
+enum modify_reg mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
+                                    enum mlx5_feature_name feature,
+                                    uint32_t id,
+                                    struct rte_flow_error *error);
 const struct rte_flow_action *mlx5_flow_find_action
                                        (const struct rte_flow_action *actions,
                                         enum rte_flow_action_type action);