This patch supports users to query HW ID. The driver will obtain the HW ID from the firmware during initialization. The user-mode driver can request the kernel-mode driver to read this information through the query_device_ex().
Signed-off-by: Chengchang Tang tangchengchang@huawei.com --- drivers/infiniband/hw/hns/hns_roce_device.h | 4 ++++ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 35 +++++++++++++++++++++++++++++ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 10 +++++++++ drivers/infiniband/hw/hns/hns_roce_main.c | 28 ++++++++++++++++++++++- include/uapi/rdma/hns-abi.h | 13 +++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 453c088..5d48990 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1091,6 +1091,10 @@ struct hns_roce_dev { u32 vendor_id; u32 vendor_part_id; u32 hw_rev; + u16 chip_id; + u16 die_id; + u16 mac_id; + u16 func_id; void __iomem *priv_addr;
struct hns_roce_cmdq cmd; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 8a1b971..8f4b236 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1570,6 +1570,39 @@ static int hns_roce_cmq_query_hw_info(struct hns_roce_dev *hr_dev) return 0; }
+static void hns_roce_cmq_query_hw_id(struct hns_roce_dev *hr_dev) +{ + struct hns_roce_hw_id_query_cmq *resp; + struct hns_roce_cmq_desc desc; + int ret; + + if (hr_dev->is_vf) + goto invalid_val; + + hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_QUERY_HW_ID, true); + ret = hns_roce_cmq_send(hr_dev, &desc, 1); + if (ret) { + if (desc.retval != CMD_NOT_EXIST) + ibdev_warn(&hr_dev->ib_dev, + "failed to query hw id, ret = %d.\n", ret); + + goto invalid_val; + } + + resp = (struct hns_roce_hw_id_query_cmq *)desc.data; + hr_dev->chip_id = resp->chip_id; + hr_dev->die_id = resp->die_id; + hr_dev->mac_id = resp->mac_id; + hr_dev->func_id = (u16)le32_to_cpu(resp->func_id); + return; + +invalid_val: + hr_dev->func_id = HNS_IB_INVALID_ID; + hr_dev->mac_id = HNS_IB_INVALID_ID; + hr_dev->die_id = HNS_IB_INVALID_ID; + hr_dev->chip_id = HNS_IB_INVALID_ID; +} + static void func_clr_hw_resetting_state(struct hns_roce_dev *hr_dev, struct hnae3_handle *handle) { @@ -2586,6 +2619,8 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev) return ret; }
+ hns_roce_cmq_query_hw_id(hr_dev); + hr_dev->vendor_part_id = hr_dev->pci_dev->device; hr_dev->sys_image_guid = be64_to_cpu(hr_dev->ib_dev.node_guid);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h index cbcd0f6..e6a9140 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -200,6 +200,7 @@ enum hns_roce_opcode_type { HNS_ROCE_OPC_CFG_LDCP_PARAM = 0x1A81, HNS_ROCE_OPC_CFG_HC3_PARAM = 0x1A82, HNS_ROCE_OPC_CFG_DIP_PARAM = 0x1A83, + HNS_ROCE_OPC_QUERY_HW_ID = 0x7032, HNS_ROCE_OPC_QUERY_HW_VER = 0x8000, HNS_ROCE_OPC_CFG_GLOBAL_PARAM = 0x8001, HNS_ROCE_OPC_ALLOC_PF_RES = 0x8004, @@ -939,6 +940,15 @@ struct hns_roce_v2_wqe_data_seg { __le64 addr; };
+struct hns_roce_hw_id_query_cmq { + __u8 chip_id; + __u8 die_id; + __u8 mac_id; + __u8 reserved; + __le32 func_id; + __le32 rsv[4]; +}; + struct hns_roce_query_version { __le16 rocee_vendor_id; __le16 rocee_hw_version; diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 51628ab..142a562 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -234,6 +234,32 @@ static int hns_roce_setup_mtu_mac(struct hns_roce_dev *hr_dev) return 0; }
+static int set_attrx(struct hns_roce_dev *hr_dev, struct ib_udata *uhw) +{ + struct hns_roce_ib_query_device_resp resp = {}; + size_t uhw_outlen; + + if (!uhw || !uhw->outlen) + return 0; + + uhw_outlen = uhw->outlen; + resp.len = sizeof(resp.comp_mask) + sizeof(resp.len); + if (uhw_outlen < resp.len) + return -EINVAL; + + if (uhw->inlen && !ib_is_udata_cleared(uhw, 0, uhw->inlen)) + return -EINVAL; + + if (uhw_outlen >= offsetofend(typeof(resp), hw_id)) { + resp.len += sizeof(resp.hw_id); + resp.hw_id.chip_id = hr_dev->chip_id; + resp.hw_id.die_id = hr_dev->die_id; + resp.hw_id.func_id = hr_dev->func_id; + } + + return ib_copy_to_udata(uhw, &resp, resp.len); +} + static int hns_roce_query_device(struct ib_device *ib_dev, struct ib_device_attr *props, struct ib_udata *uhw) @@ -281,7 +307,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev, if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC) props->device_cap_flags |= IB_DEVICE_XRC;
- return 0; + return set_attrx(hr_dev, uhw); }
static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num, diff --git a/include/uapi/rdma/hns-abi.h b/include/uapi/rdma/hns-abi.h index a95b1d0..9d18a69 100644 --- a/include/uapi/rdma/hns-abi.h +++ b/include/uapi/rdma/hns-abi.h @@ -232,4 +232,17 @@ enum hns_ib_dca_mem_query_attrs { HNS_IB_ATTR_DCA_MEM_QUERY_OUT_PAGE_COUNT, };
+#define HNS_IB_INVALID_ID 0XFFFF +struct hns_roce_ib_hw_id { + __u16 chip_id; + __u16 die_id; + __u16 func_id; + __u16 reserved; +}; + +struct hns_roce_ib_query_device_resp { + __u32 comp_mask; + __u32 len; + struct hns_roce_ib_hw_id hw_id; +}; #endif /* HNS_ABI_USER_H */