common/mlx5: query vDPA DevX capabilities
authorMatan Azrad <matan@mellanox.com>
Wed, 29 Jan 2020 12:38:32 +0000 (12:38 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 5 Feb 2020 08:51:20 +0000 (09:51 +0100)
Add the DevX capabilities for vDPA configuration and information of
Mellanox devices.

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

index 4d94f92..3a10ff0 100644 (file)
@@ -284,6 +284,91 @@ error:
        return rc;
 }
 
+/**
+ * Query NIC vDPA attributes.
+ *
+ * @param[in] ctx
+ *   ibv contexts returned from mlx5dv_open_device.
+ * @param[out] vdpa_attr
+ *   vDPA Attributes structure to fill.
+ */
+static void
+mlx5_devx_cmd_query_hca_vdpa_attr(struct ibv_context *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;
+
+       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);
+               vdpa_attr->valid = 0;
+       } else {
+               vdpa_attr->valid = 1;
+               vdpa_attr->desc_tunnel_offload_type =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                desc_tunnel_offload_type);
+               vdpa_attr->eth_frame_offload_type =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                eth_frame_offload_type);
+               vdpa_attr->virtio_version_1_0 =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                virtio_version_1_0);
+               vdpa_attr->tso_ipv4 = MLX5_GET(virtio_emulation_cap, hcattr,
+                                              tso_ipv4);
+               vdpa_attr->tso_ipv6 = MLX5_GET(virtio_emulation_cap, hcattr,
+                                              tso_ipv6);
+               vdpa_attr->tx_csum = MLX5_GET(virtio_emulation_cap, hcattr,
+                                             tx_csum);
+               vdpa_attr->rx_csum = MLX5_GET(virtio_emulation_cap, hcattr,
+                                             rx_csum);
+               vdpa_attr->event_mode = MLX5_GET(virtio_emulation_cap, hcattr,
+                                                event_mode);
+               vdpa_attr->virtio_queue_type =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                virtio_queue_type);
+               vdpa_attr->log_doorbell_stride =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                log_doorbell_stride);
+               vdpa_attr->log_doorbell_bar_size =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                log_doorbell_bar_size);
+               vdpa_attr->doorbell_bar_offset =
+                       MLX5_GET64(virtio_emulation_cap, hcattr,
+                                  doorbell_bar_offset);
+               vdpa_attr->max_num_virtio_queues =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                max_num_virtio_queues);
+               vdpa_attr->umem_1_buffer_param_a =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                umem_1_buffer_param_a);
+               vdpa_attr->umem_1_buffer_param_b =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                umem_1_buffer_param_b);
+               vdpa_attr->umem_2_buffer_param_a =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                umem_2_buffer_param_a);
+               vdpa_attr->umem_2_buffer_param_b =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                umem_2_buffer_param_a);
+               vdpa_attr->umem_3_buffer_param_a =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                umem_3_buffer_param_a);
+               vdpa_attr->umem_3_buffer_param_b =
+                       MLX5_GET(virtio_emulation_cap, hcattr,
+                                umem_3_buffer_param_b);
+       }
+}
+
 /**
  * Query HCA attributes.
  * Using those attributes we can check on run time if the device
@@ -343,6 +428,9 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx,
        attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr,
                                               flex_parser_protocols);
        attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos);
+       attr->vdpa.valid = !!(MLX5_GET64(cmd_hca_cap, hcattr,
+                                        general_obj_types) &
+                             MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q);
        if (attr->qos.sup) {
                MLX5_SET(query_hca_cap_in, in, op_mod,
                         MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP |
@@ -367,6 +455,8 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx,
                attr->qos.flow_meter_reg_share =
                        MLX5_GET(qos_cap, hcattr, flow_meter_reg_share);
        }
+       if (attr->vdpa.valid)
+               mlx5_devx_cmd_query_hca_vdpa_attr(ctx, &attr->vdpa);
        if (!attr->eth_net_offloads)
                return 0;
 
index 2d58d96..c1c9e99 100644 (file)
@@ -34,6 +34,29 @@ struct mlx5_hca_qos_attr {
 
 };
 
+struct mlx5_hca_vdpa_attr {
+       uint8_t virtio_queue_type;
+       uint32_t valid:1;
+       uint32_t desc_tunnel_offload_type:1;
+       uint32_t eth_frame_offload_type:1;
+       uint32_t virtio_version_1_0:1;
+       uint32_t tso_ipv4:1;
+       uint32_t tso_ipv6:1;
+       uint32_t tx_csum:1;
+       uint32_t rx_csum:1;
+       uint32_t event_mode:3;
+       uint32_t log_doorbell_stride:5;
+       uint32_t log_doorbell_bar_size:5;
+       uint32_t max_num_virtio_queues;
+       uint32_t umem_1_buffer_param_a;
+       uint32_t umem_1_buffer_param_b;
+       uint32_t umem_2_buffer_param_a;
+       uint32_t umem_2_buffer_param_b;
+       uint32_t umem_3_buffer_param_a;
+       uint32_t umem_3_buffer_param_b;
+       uint64_t doorbell_bar_offset;
+};
+
 /* HCA supports this number of time periods for LRO. */
 #define MLX5_LRO_NUM_SUPP_PERIODS 4
 
@@ -62,6 +85,7 @@ struct mlx5_hca_attr {
        uint32_t log_max_hairpin_num_packets:5;
        uint32_t vhca_id:16;
        struct mlx5_hca_qos_attr qos;
+       struct mlx5_hca_vdpa_attr vdpa;
 };
 
 struct mlx5_devx_wq_attr {
index 5730ad1..efd6ad4 100644 (file)
@@ -881,6 +881,11 @@ enum {
        MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE = 0x0 << 1,
        MLX5_GET_HCA_CAP_OP_MOD_ETHERNET_OFFLOAD_CAPS = 0x1 << 1,
        MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP = 0xc << 1,
+       MLX5_GET_HCA_CAP_OP_MOD_VDPA_EMULATION = 0x13 << 1,
+};
+
+enum {
+       MLX5_GENERAL_OBJ_TYPES_CAP_VIRTQ_NET_Q = (1ULL << 0xd),
 };
 
 enum {
@@ -1256,11 +1261,51 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
        u8 reserved_at_200[0x600];
 };
 
+enum {
+       MLX5_VIRTQ_TYPE_SPLIT = 0,
+       MLX5_VIRTQ_TYPE_PACKED = 1,
+};
+
+enum {
+       MLX5_VIRTQ_EVENT_MODE_NO_MSIX = 0,
+       MLX5_VIRTQ_EVENT_MODE_QP = 1,
+       MLX5_VIRTQ_EVENT_MODE_MSIX = 2,
+};
+
+struct mlx5_ifc_virtio_emulation_cap_bits {
+       u8 desc_tunnel_offload_type[0x1];
+       u8 eth_frame_offload_type[0x1];
+       u8 virtio_version_1_0[0x1];
+       u8 tso_ipv4[0x1];
+       u8 tso_ipv6[0x1];
+       u8 tx_csum[0x1];
+       u8 rx_csum[0x1];
+       u8 reserved_at_7[0x1][0x9];
+       u8 event_mode[0x8];
+       u8 virtio_queue_type[0x8];
+       u8 reserved_at_20[0x13];
+       u8 log_doorbell_stride[0x5];
+       u8 reserved_at_3b[0x3];
+       u8 log_doorbell_bar_size[0x5];
+       u8 doorbell_bar_offset[0x40];
+       u8 reserved_at_80[0x8];
+       u8 max_num_virtio_queues[0x18];
+       u8 reserved_at_a0[0x60];
+       u8 umem_1_buffer_param_a[0x20];
+       u8 umem_1_buffer_param_b[0x20];
+       u8 umem_2_buffer_param_a[0x20];
+       u8 umem_2_buffer_param_b[0x20];
+       u8 umem_3_buffer_param_a[0x20];
+       u8 umem_3_buffer_param_b[0x20];
+       u8 reserved_at_1c0[0x620];
+};
+
 union mlx5_ifc_hca_cap_union_bits {
        struct mlx5_ifc_cmd_hca_cap_bits cmd_hca_cap;
        struct mlx5_ifc_per_protocol_networking_offload_caps_bits
               per_protocol_networking_offload_caps;
        struct mlx5_ifc_qos_cap_bits qos_cap;
+       struct mlx5_ifc_virtio_emulation_cap_bits vdpa_caps;
        u8 reserved_at_0[0x8000];
 };