From 26d1c2339d0cc633b3817a78303eff6635a5fe88 Mon Sep 17 00:00:00 2001
From: Chengchang Tang <tangchengchang@huawei.com>
Date: Mon, 30 Oct 2023 16:59:16 +0800
Subject: [PATCH 2/8] libhns: Support query HW ID by hnsdv_query_device()

driver inclusion
category: feature
bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I8C6X4

---------------------------------------------------------------

Supports obtaining hardware-related ID through hnsdv_query_device()

Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
---
 providers/hns/hns_roce_u.c       | 43 ++++++++++++++++++++++----------
 providers/hns/hns_roce_u.h       |  1 +
 providers/hns/hns_roce_u_abi.h   |  3 +++
 providers/hns/hns_roce_u_verbs.c | 32 ++++++++++++++++++------
 providers/hns/hnsdv.h            | 11 ++++++++
 5 files changed, 70 insertions(+), 20 deletions(-)

diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index cef64ec..1085b85 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -313,6 +313,35 @@ static void ucontext_set_cmd(struct hns_roce_alloc_ucontext *cmd,
 	}
 }
 
+static void set_default_hw_id(struct hns_roce_context *context)
+{
+	context->hw_id.chip_id = HNSDV_INVALID_HW_ID;
+	context->hw_id.die_id = HNSDV_INVALID_HW_ID;
+	context->hw_id.func_id = HNSDV_INVALID_HW_ID;
+}
+
+static int query_dev_attr(struct hns_roce_context *context,
+			  struct hns_roce_device *hr_dev)
+{
+	struct ibv_device_attr_ex attrx = {};
+	struct ibv_device_attr *dev_attrs = &attrx.orig_attr;
+
+	set_default_hw_id(context);
+
+	if (hns_roce_u_query_device(&context->ibv_ctx.context, NULL, &attrx,
+				    sizeof(attrx)))
+		return EINVAL;
+
+	hr_dev->hw_version = dev_attrs->hw_ver;
+	context->max_qp_wr = dev_attrs->max_qp_wr;
+	context->max_sge = dev_attrs->max_sge;
+	context->max_cqe = dev_attrs->max_cqe;
+	context->max_srq_wr = dev_attrs->max_srq_wr;
+	context->max_srq_sge = dev_attrs->max_srq_sge;
+
+	return 0;
+}
+
 static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
 						    int cmd_fd,
 						    void *private_data)
@@ -321,7 +350,6 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
 	struct hns_roce_device *hr_dev = to_hr_dev(ibdev);
 	struct hns_roce_alloc_ucontext_resp resp = {};
 	struct hns_roce_alloc_ucontext cmd = {};
-	struct ibv_device_attr dev_attrs;
 	struct hns_roce_context *context;
 	int i;
 
@@ -362,23 +390,12 @@ static struct verbs_context *hns_roce_alloc_context(struct ibv_device *ibdev,
 	for (i = 0; i < HNS_ROCE_SRQ_TABLE_SIZE; ++i)
 		context->srq_table[i].refcnt = 0;
 
-	if (hns_roce_u_query_device(&context->ibv_ctx.context, NULL,
-				    container_of(&dev_attrs,
-						 struct ibv_device_attr_ex,
-						 orig_attr),
-				    sizeof(dev_attrs)))
+	if (query_dev_attr(context, hr_dev))
 		goto err_free;
 
-	hr_dev->hw_version = dev_attrs.hw_ver;
 	if (get_link_type(dev_attrs.vendor_part_id, &hr_dev->link_type))
 		hr_dev->link_type = resp.mac_type;
 
-	context->max_qp_wr = dev_attrs.max_qp_wr;
-	context->max_sge = dev_attrs.max_sge;
-	context->max_cqe = dev_attrs.max_cqe;
-	context->max_srq_wr = dev_attrs.max_srq_wr;
-	context->max_srq_sge = dev_attrs.max_srq_sge;
-
 	if (init_dca_context(context, cmd_fd,
 			     &resp, ctx_attr, hr_dev->page_size))
 		goto err_free;
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index 662eb8a..323d2f9 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -280,6 +280,7 @@ struct hns_roce_context {
 	unsigned int			max_inline_data;
 
 	struct hns_roce_dca_ctx		dca_ctx;
+	struct hnsdv_hw_id hw_id;
 
 	bool use_new_reset_flag;
 	bool reseted;
diff --git a/providers/hns/hns_roce_u_abi.h b/providers/hns/hns_roce_u_abi.h
index 1eaf62d..c73a30d 100644
--- a/providers/hns/hns_roce_u_abi.h
+++ b/providers/hns/hns_roce_u_abi.h
@@ -68,4 +68,7 @@ DECLARE_DRV_CMD(hns_roce_create_srq_ex, IB_USER_VERBS_CMD_CREATE_XSRQ,
 DECLARE_DRV_CMD(hns_roce_modify_qp_ex, IB_USER_VERBS_EX_CMD_MODIFY_QP,
 		empty, hns_roce_ib_modify_qp_resp);
 
+DECLARE_DRV_CMD(hns_roce_query_device_ex, IB_USER_VERBS_EX_CMD_QUERY_DEVICE,
+		empty, hns_roce_ib_query_device_resp);
+
 #endif /* _HNS_ROCE_U_ABI_H */
diff --git a/providers/hns/hns_roce_u_verbs.c b/providers/hns/hns_roce_u_verbs.c
index c3b01a0..5b86077 100644
--- a/providers/hns/hns_roce_u_verbs.c
+++ b/providers/hns/hns_roce_u_verbs.c
@@ -84,22 +84,27 @@ void hns_roce_init_qp_indices(struct hns_roce_qp *qp)
 	qp->next_sge = 0;
 }
 
+#define HNSDV_CONVERT_HW_ID(val) \
+	((val) == HNS_IB_INVALID_ID ? HNSDV_INVALID_HW_ID : (val))
+
 int hns_roce_u_query_device(struct ibv_context *context,
 			    const struct ibv_query_device_ex_input *input,
 			    struct ibv_device_attr_ex *attr, size_t attr_size)
 {
-	struct ib_uverbs_ex_query_device_resp resp;
+	struct hns_roce_context *ctx = to_hr_ctx(context);
+	struct hns_roce_query_device_ex_resp resp = {};
 	unsigned int major, minor, sub_minor;
 	size_t resp_size = sizeof(resp);
 	uint64_t raw_fw_ver;
 	int ret;
 
-	ret = ibv_cmd_query_device_any(context, input, attr, attr_size, &resp,
-				       &resp_size);
+	ctx = container_of(context, struct hns_roce_context, ibv_ctx.context);
+	ret = ibv_cmd_query_device_any(context, input, attr, attr_size,
+				       &resp.ibv_resp, &resp_size);
 	if (ret)
 		return ret;
 
-	raw_fw_ver = resp.base.fw_ver;
+	raw_fw_ver = resp.ibv_resp.base.fw_ver;
 	major = (raw_fw_ver >> 32) & 0xffff;
 	minor = (raw_fw_ver >> 16) & 0xffff;
 	sub_minor = raw_fw_ver & 0xffff;
@@ -107,27 +112,40 @@ int hns_roce_u_query_device(struct ibv_context *context,
 	snprintf(attr->orig_attr.fw_ver, sizeof(attr->orig_attr.fw_ver),
 		 "%u.%u.%03u", major, minor, sub_minor);
 
+	if (resp.len >= offsetofend(typeof(resp.drv_payload), hw_id)) {
+		ctx->hw_id.chip_id = HNSDV_CONVERT_HW_ID(resp.hw_id.chip_id);
+		ctx->hw_id.die_id = HNSDV_CONVERT_HW_ID(resp.hw_id.die_id);
+		ctx->hw_id.func_id = HNSDV_CONVERT_HW_ID(resp.hw_id.func_id);
+	}
+
 	return 0;
 }
 
 int hnsdv_query_device(struct ibv_context *context,
 		       struct hnsdv_context *attrs_out)
 {
+	struct hns_roce_context *ctx = context ? to_hr_ctx(context) : NULL;
 	struct hns_roce_device *hr_dev = to_hr_dev(context->device);
 
+	if (!ctx || !attrs_out)
+		return EINVAL;
+
 	if (!hr_dev) {
 		verbs_err(verbs_get_ctx(context), "not a HNS RoCE device!\n");
 		return EOPNOTSUPP;
 	}
 
-	if (!attrs_out)
-		return EINVAL;
-
 	memset(attrs_out, 0, sizeof(*attrs_out));
 
 	attrs_out->comp_mask |= HNSDV_CONTEXT_MASK_CONGEST_TYPE;
 	attrs_out->congest_type = hr_dev->congest_type;
 
+	if (ctx->hw_id.chip_id != HNSDV_INVALID_HW_ID) {
+		attrs_out->comp_mask |= HNSDV_CONTEXT_MASK_HW_ID;
+		memcpy(&attrs_out->hw_id, &ctx->hw_id,
+		       sizeof(struct hnsdv_hw_id));
+	}
+
 	return 0;
 }
 
diff --git a/providers/hns/hnsdv.h b/providers/hns/hnsdv.h
index 365c314..159edb8 100644
--- a/providers/hns/hnsdv.h
+++ b/providers/hns/hnsdv.h
@@ -70,12 +70,23 @@ struct ibv_qp *hnsdv_create_qp(struct ibv_context *context,
 
 enum hnsdv_query_context_comp_mask {
 	HNSDV_CONTEXT_MASK_CONGEST_TYPE = 1 << 0,
+	HNSDV_CONTEXT_MASK_HW_ID = 1 << 1,
+};
+
+#define HNSDV_INVALID_HW_ID -1
+struct hnsdv_hw_id {
+	int32_t chip_id;
+	int32_t die_id;
+	int32_t func_id;
+	int32_t reserved;
 };
 
 struct hnsdv_context {
 	uint64_t comp_mask; /* use enum hnsdv_query_context_comp_mask */
 	uint64_t flags;
 	uint8_t congest_type; /* Use enum hnsdv_qp_congest_ctrl_type */
+	uint8_t rsv[7];
+	struct hnsdv_hw_id hw_id;
 };
 
 int hnsdv_query_device(struct ibv_context *ctx_in,
-- 
2.25.1

