common/mlx5: introduce user index field in completion
[dpdk.git] / drivers / common / mlx5 / mlx5_devx_cmds.c
index fb7c8e9..0c03c20 100644 (file)
 #include "mlx5_common_log.h"
 #include "mlx5_malloc.h"
 
+static void *
+mlx5_devx_get_hca_cap(void *ctx, uint32_t *in, uint32_t *out,
+                     int *err, uint32_t flags)
+{
+       const size_t size_in = MLX5_ST_SZ_DW(query_hca_cap_in) * sizeof(int);
+       const size_t size_out = MLX5_ST_SZ_DW(query_hca_cap_out) * sizeof(int);
+       int status, syndrome, rc;
+
+       if (err)
+               *err = 0;
+       memset(in, 0, size_in);
+       memset(out, 0, size_out);
+       MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
+       MLX5_SET(query_hca_cap_in, in, op_mod, flags);
+       rc = mlx5_glue->devx_general_cmd(ctx, in, size_in, out, size_out);
+       if (rc) {
+               DRV_LOG(ERR,
+                       "Failed to query devx HCA capabilities func %#02x",
+                       flags >> 1);
+               if (err)
+                       *err = rc > 0 ? -rc : rc;
+               return NULL;
+       }
+       status = MLX5_GET(query_hca_cap_out, out, status);
+       syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
+       if (status) {
+               DRV_LOG(ERR,
+                       "Failed to query devx HCA capabilities func %#02x status %x, syndrome = %x",
+                       flags >> 1, status, syndrome);
+               if (err)
+                       *err = -1;
+               return NULL;
+       }
+       return MLX5_ADDR_OF(query_hca_cap_out, out, capability);
+}
+
 /**
  * Perform read access to the registers. Reads data from register
  * and writes ones to the specified buffer.
@@ -472,21 +508,15 @@ static void
 mlx5_devx_cmd_query_hca_vdpa_attr(void *ctx,
                                  struct mlx5_hca_vdpa_attr *vdpa_attr)
 {
-       uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
-       uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
-       void *hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
-       int status, syndrome, rc;
+       uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)];
+       uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)];
+       void *hcattr;
 
-       MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
-       MLX5_SET(query_hca_cap_in, in, op_mod,
-                MLX5_GET_HCA_CAP_OP_MOD_VDPA_EMULATION |
-                MLX5_HCA_CAP_OPMOD_GET_CUR);
-       rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
-       status = MLX5_GET(query_hca_cap_out, out, status);
-       syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
-       if (rc || status) {
-               RTE_LOG(DEBUG, PMD, "Failed to query devx VDPA capabilities,"
-                       " status %x, syndrome = %x", status, syndrome);
+       hcattr = mlx5_devx_get_hca_cap(ctx, in, out, NULL,
+                       MLX5_GET_HCA_CAP_OP_MOD_VDPA_EMULATION |
+                       MLX5_HCA_CAP_OPMOD_GET_CUR);
+       if (!hcattr) {
+               RTE_LOG(DEBUG, PMD, "Failed to query devx VDPA capabilities");
                vdpa_attr->valid = 0;
        } else {
                vdpa_attr->valid = 1;
@@ -590,10 +620,9 @@ mlx5_devx_cmd_query_parse_samples(struct mlx5_devx_obj *flex_obj,
        return ret;
 }
 
-
 struct mlx5_devx_obj *
 mlx5_devx_cmd_create_flex_parser(void *ctx,
-                             struct mlx5_devx_graph_node_attr *data)
+                                struct mlx5_devx_graph_node_attr *data)
 {
        uint32_t in[MLX5_ST_SZ_DW(create_flex_parser_in)] = {0};
        uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0};
@@ -617,12 +646,18 @@ mlx5_devx_cmd_create_flex_parser(void *ctx,
                 MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH);
        MLX5_SET(parse_graph_flex, flex, header_length_mode,
                 data->header_length_mode);
+       MLX5_SET64(parse_graph_flex, flex, modify_field_select,
+                  data->modify_field_select);
        MLX5_SET(parse_graph_flex, flex, header_length_base_value,
                 data->header_length_base_value);
        MLX5_SET(parse_graph_flex, flex, header_length_field_offset,
                 data->header_length_field_offset);
        MLX5_SET(parse_graph_flex, flex, header_length_field_shift,
                 data->header_length_field_shift);
+       MLX5_SET(parse_graph_flex, flex, next_header_field_offset,
+                data->next_header_field_offset);
+       MLX5_SET(parse_graph_flex, flex, next_header_field_size,
+                data->next_header_field_size);
        MLX5_SET(parse_graph_flex, flex, header_length_field_mask,
                 data->header_length_field_mask);
        for (i = 0; i < MLX5_GRAPH_NODE_SAMPLE_NUM; i++) {
@@ -699,6 +734,53 @@ mlx5_devx_cmd_create_flex_parser(void *ctx,
        return parse_flex_obj;
 }
 
+static int
+mlx5_devx_cmd_query_hca_parse_graph_node_cap
+       (void *ctx, struct mlx5_hca_flex_attr *attr)
+{
+       uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)];
+       uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)];
+       void *hcattr;
+       int rc;
+
+       hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                       MLX5_GET_HCA_CAP_OP_MOD_PARSE_GRAPH_NODE_CAP |
+                       MLX5_HCA_CAP_OPMOD_GET_CUR);
+       if (!hcattr)
+               return rc;
+       attr->node_in = MLX5_GET(parse_graph_node_cap, hcattr, node_in);
+       attr->node_out = MLX5_GET(parse_graph_node_cap, hcattr, node_out);
+       attr->header_length_mode = MLX5_GET(parse_graph_node_cap, hcattr,
+                                           header_length_mode);
+       attr->sample_offset_mode = MLX5_GET(parse_graph_node_cap, hcattr,
+                                           sample_offset_mode);
+       attr->max_num_arc_in = MLX5_GET(parse_graph_node_cap, hcattr,
+                                       max_num_arc_in);
+       attr->max_num_arc_out = MLX5_GET(parse_graph_node_cap, hcattr,
+                                        max_num_arc_out);
+       attr->max_num_sample = MLX5_GET(parse_graph_node_cap, hcattr,
+                                       max_num_sample);
+       attr->sample_id_in_out = MLX5_GET(parse_graph_node_cap, hcattr,
+                                         sample_id_in_out);
+       attr->max_base_header_length = MLX5_GET(parse_graph_node_cap, hcattr,
+                                               max_base_header_length);
+       attr->max_sample_base_offset = MLX5_GET(parse_graph_node_cap, hcattr,
+                                               max_sample_base_offset);
+       attr->max_next_header_offset = MLX5_GET(parse_graph_node_cap, hcattr,
+                                               max_next_header_offset);
+       attr->header_length_mask_width = MLX5_GET(parse_graph_node_cap, hcattr,
+                                                 header_length_mask_width);
+       /* Get the max supported samples from HCA CAP 2 */
+       hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                       MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 |
+                       MLX5_HCA_CAP_OPMOD_GET_CUR);
+       if (!hcattr)
+               return rc;
+       attr->max_num_prog_sample =
+               MLX5_GET(cmd_hca_cap_2, hcattr, max_num_prog_sample_field);
+       return 0;
+}
+
 static int
 mlx5_devx_query_pkt_integrity_match(void *hcattr)
 {
@@ -741,27 +823,15 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
 {
        uint32_t in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0};
        uint32_t out[MLX5_ST_SZ_DW(query_hca_cap_out)] = {0};
-       void *hcattr;
-       int status, syndrome, rc, i;
        uint64_t general_obj_types_supported = 0;
+       void *hcattr;
+       int rc, i;
 
-       MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
-       MLX5_SET(query_hca_cap_in, in, op_mod,
-                MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE |
-                MLX5_HCA_CAP_OPMOD_GET_CUR);
-
-       rc = mlx5_glue->devx_general_cmd(ctx,
-                                        in, sizeof(in), out, sizeof(out));
-       if (rc)
-               goto error;
-       status = MLX5_GET(query_hca_cap_out, out, status);
-       syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
-       if (status) {
-               DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, "
-                       "status %x, syndrome = %x", status, syndrome);
-               return -1;
-       }
-       hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
+       hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                       MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE |
+                       MLX5_HCA_CAP_OPMOD_GET_CUR);
+       if (!hcattr)
+               return rc;
        attr->flow_counter_bulk_alloc_bitmap =
                        MLX5_GET(cmd_hca_cap, hcattr, flow_counter_bulk_alloc);
        attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr,
@@ -821,7 +891,8 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
        attr->sq_ts_format = MLX5_GET(cmd_hca_cap, hcattr, sq_ts_format);
        attr->steering_format_version =
                MLX5_GET(cmd_hca_cap, hcattr, steering_format_version);
-       attr->regex = MLX5_GET(cmd_hca_cap, hcattr, regexp);
+       attr->regexp_params = MLX5_GET(cmd_hca_cap, hcattr, regexp_params);
+       attr->regexp_version = MLX5_GET(cmd_hca_cap, hcattr, regexp_version);
        attr->regexp_num_of_engines = MLX5_GET(cmd_hca_cap, hcattr,
                                               regexp_num_of_engines);
        /* Read the general_obj_types bitmap and extract the relevant bits. */
@@ -893,19 +964,13 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
                                         general_obj_types) &
                              MLX5_GENERAL_OBJ_TYPES_CAP_CONN_TRACK_OFFLOAD);
        if (attr->qos.sup) {
-               MLX5_SET(query_hca_cap_in, in, op_mod,
-                        MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
-                        MLX5_HCA_CAP_OPMOD_GET_CUR);
-               rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in),
-                                                out, sizeof(out));
-               if (rc)
-                       goto error;
-               if (status) {
-                       DRV_LOG(DEBUG, "Failed to query devx QOS capabilities,"
-                               " status %x, syndrome = %x", status, syndrome);
-                       return -1;
+               hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                               MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
+                               MLX5_HCA_CAP_OPMOD_GET_CUR);
+               if (!hcattr) {
+                       DRV_LOG(DEBUG, "Failed to query devx QOS capabilities");
+                       return rc;
                }
-               hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
                attr->qos.flow_meter_old =
                                MLX5_GET(qos_cap, hcattr, flow_meter_old);
                attr->qos.log_max_flow_meter =
@@ -930,31 +995,28 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
                                        log_max_num_meter_aso);
                }
        }
+       /*
+        * Flex item support needs max_num_prog_sample_field
+        * from the Capabilities 2 table for PARSE_GRAPH_NODE
+        */
+       if (attr->parse_graph_flex_node) {
+               rc = mlx5_devx_cmd_query_hca_parse_graph_node_cap
+                       (ctx, &attr->flex);
+               if (rc)
+                       return -1;
+       }
        if (attr->vdpa.valid)
                mlx5_devx_cmd_query_hca_vdpa_attr(ctx, &attr->vdpa);
        if (!attr->eth_net_offloads)
                return 0;
-
        /* Query Flow Sampler Capability From FLow Table Properties Layout. */
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
-       MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
-       MLX5_SET(query_hca_cap_in, in, op_mod,
-                MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
-                MLX5_HCA_CAP_OPMOD_GET_CUR);
-
-       rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
-       if (rc)
-               goto error;
-       status = MLX5_GET(query_hca_cap_out, out, status);
-       syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
-       if (status) {
-               DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, "
-                       "status %x, syndrome = %x", status, syndrome);
+       hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                       MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
+                       MLX5_HCA_CAP_OPMOD_GET_CUR);
+       if (!hcattr) {
                attr->log_max_ft_sampler_num = 0;
-               return -1;
+               return rc;
        }
-       hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
        attr->log_max_ft_sampler_num = MLX5_GET
                (flow_table_nic_cap, hcattr,
                 flow_table_properties_nic_receive.log_max_ft_sampler_num);
@@ -969,27 +1031,13 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
                (flow_table_nic_cap, hcattr,
                 ft_field_support_2_nic_receive.outer_ipv4_ihl);
        /* Query HCA offloads for Ethernet protocol. */
-       memset(in, 0, sizeof(in));
-       memset(out, 0, sizeof(out));
-       MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
-       MLX5_SET(query_hca_cap_in, in, op_mod,
-                MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS |
-                MLX5_HCA_CAP_OPMOD_GET_CUR);
-
-       rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
-       if (rc) {
+       hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                       MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS |
+                       MLX5_HCA_CAP_OPMOD_GET_CUR);
+       if (!hcattr) {
                attr->eth_net_offloads = 0;
-               goto error;
+               return rc;
        }
-       status = MLX5_GET(query_hca_cap_out, out, status);
-       syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
-       if (status) {
-               DRV_LOG(DEBUG, "Failed to query devx HCA capabilities, "
-                       "status %x, syndrome = %x", status, syndrome);
-               attr->eth_net_offloads = 0;
-               return -1;
-       }
-       hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
        attr->wqe_vlan_insert = MLX5_GET(per_protocol_networking_offload_caps,
                                         hcattr, wqe_vlan_insert);
        attr->csum_cap = MLX5_GET(per_protocol_networking_offload_caps,
@@ -1044,26 +1092,14 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
                                         hcattr, rss_ind_tbl_cap);
        /* Query HCA attribute for ROCE. */
        if (attr->roce) {
-               memset(in, 0, sizeof(in));
-               memset(out, 0, sizeof(out));
-               MLX5_SET(query_hca_cap_in, in, opcode,
-                        MLX5_CMD_OP_QUERY_HCA_CAP);
-               MLX5_SET(query_hca_cap_in, in, op_mod,
-                        MLX5_GET_HCA_CAP_OP_MOD_ROCE |
-                        MLX5_HCA_CAP_OPMOD_GET_CUR);
-               rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in),
-                                                out, sizeof(out));
-               if (rc)
-                       goto error;
-               status = MLX5_GET(query_hca_cap_out, out, status);
-               syndrome = MLX5_GET(query_hca_cap_out, out, syndrome);
-               if (status) {
+               hcattr = mlx5_devx_get_hca_cap(ctx, in, out, &rc,
+                               MLX5_GET_HCA_CAP_OP_MOD_ROCE |
+                               MLX5_HCA_CAP_OPMOD_GET_CUR);
+               if (!hcattr) {
                        DRV_LOG(DEBUG,
-                               "Failed to query devx HCA ROCE capabilities, "
-                               "status %x, syndrome = %x", status, syndrome);
-                       return -1;
+                               "Failed to query devx HCA ROCE capabilities");
+                       return rc;
                }
-               hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
                attr->qp_ts_format = MLX5_GET(roce_caps, hcattr, qp_ts_format);
        }
        if (attr->eth_virt &&