* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include <sys/ioctl.h>
#include "dms_user_common.h"
#include "devdrv_user_common.h"
#include "dms/dms_soc_interface.h"
#include "devmng_user_common.h"
#include "devdrv_ioctl.h"
#include "dms/dms_devdrv_info_comm.h"
#include "ascend_dev_num.h"
#include "dms_soc.h"
#include "dms_device_info.h"
drvError_t DmsGetBoardId(unsigned int dev_id, unsigned int *board_id)
{
struct dms_ioctl_arg ioarg = {0};
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (board_id == NULL)) {
DMS_ERR("Invalid dev_id or board_id is NULL. (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_GET_BOARD_ID_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)board_id;
ioarg.output_len = sizeof(unsigned int);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get board id failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get board id success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetPcbId(unsigned int dev_id, unsigned int *pcb_id)
{
struct dms_ioctl_arg ioarg = {0};
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (pcb_id == NULL)) {
DMS_ERR("Invalid dev_id or pcb_id is NULL. (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_MAIN_CMD_SOC;
ioarg.sub_cmd = DMS_SUBCMD_GET_PCB_ID;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)pcb_id;
ioarg.output_len = sizeof(unsigned int);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get pcb id failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get pcb id success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetBomId(unsigned int dev_id, unsigned int *bom_id)
{
struct dms_ioctl_arg ioarg = {0};
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (bom_id == NULL)) {
DMS_ERR("Invalid dev_id or bom_id is NULL. (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_MAIN_CMD_SOC;
ioarg.sub_cmd = DMS_SUBCMD_GET_BOM_ID;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)bom_id;
ioarg.output_len = sizeof(unsigned int);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get bom id failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get bom id success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetSlotId(unsigned int dev_id, unsigned int *slot_id)
{
struct dms_ioctl_arg ioarg = {0};
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (slot_id == NULL)) {
DMS_ERR("Invalid dev_id or slot_id is NULL. (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_MAIN_CMD_SOC;
ioarg.sub_cmd = DMS_SUBCMD_GET_SLOT_ID;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)slot_id;
ioarg.output_len = sizeof(unsigned int);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get slot id failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get slot id success.\n");
return DRV_ERROR_NONE;
}
static int dms_virt_get_pcie_id_info(unsigned int dev_id, dms_pcie_id_info_t *pcie_idinfo)
{
int ret;
pcie_idinfo->davinci_id = dev_id;
ret = dmanage_common_ioctl(DEVDRV_MANAGER_GET_PCIE_ID_INFO, pcie_idinfo);
if (ret != 0) {
DMS_ERR("Dms virt get pcie info ioctl failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
return DRV_ERROR_NONE;
}
static int dms_phy_get_pcie_id_info(unsigned int dev_id, dms_pcie_id_info_t *pcie_idinfo)
{
struct dms_ioctl_arg ioarg = {0};
int ret;
ioarg.main_cmd = DMS_MAIN_CMD_BASIC;
ioarg.sub_cmd = DMS_SUBCMD_GET_PCIE_INFO;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)pcie_idinfo;
ioarg.output_len = sizeof(dms_pcie_id_info_t);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Dms phy get pcie info failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
}
return ret;
}
drvError_t DmsGetPcieIdInfo(unsigned int dev_id, dms_pcie_id_info_t *pcie_idinfo)
{
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (pcie_idinfo == NULL)) {
DMS_ERR("Invalid dev_id or pcie_idinfo is NULL. (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
ret = DMS_VIRT_ADAPT_FUNC(dms_virt_get_pcie_id_info, dms_phy_get_pcie_id_info)(dev_id, pcie_idinfo);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get pcie info failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get pcie info success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetCpuInfo(unsigned int dev_id, drvCpuInfo_t *cpu_info)
{
struct dms_ioctl_arg ioarg = {0};
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (cpu_info == NULL)) {
DMS_ERR("Invalid dev_id or cpu_info is NULL. (dev_id=%u)\n", dev_id);
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_MAIN_CMD_SOC;
ioarg.sub_cmd = DMS_SUBCMD_GET_CPU_INFO;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)cpu_info;
ioarg.output_len = sizeof(drvCpuInfo_t);
ret = errno_to_user_errno(DmsIoctl(DMS_GET_CPU_INFO, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get cpu info failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get cpu info success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetSocDieId(dms_soc_die_id_t *soc_die_id)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
if (soc_die_id == NULL) {
DMS_ERR("Soc die id is NULL.\n");
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_GET_GET_DIE_ID_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)soc_die_id;
ioarg.input_len = sizeof(dms_soc_die_id_t);
ioarg.output = (void *)soc_die_id;
ioarg.output_len = sizeof(dms_soc_die_id_t);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Dms get soc die id failed. (dev_id=%u; ret=%d)\n",
soc_die_id->dev_id, ret);
return ret;
}
DMS_DEBUG("Get soc die id success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetSocDieIdV2(dms_soc_die_id_v2_t *soc_die_id)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
if (soc_die_id == NULL) {
DMS_ERR("Soc die id is NULL.\n");
return DRV_ERROR_PARA_ERROR;
}
ioarg.main_cmd = DMS_GET_GET_DIE_ID_V2_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)soc_die_id;
ioarg.input_len = sizeof(dms_soc_die_id_v2_t);
ioarg.output = (void *)soc_die_id;
ioarg.output_len = sizeof(dms_soc_die_id_v2_t);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Dms get soc die id failed. (dev_id=%u; ret=%d)\n",
soc_die_id->dev_id, ret);
return ret;
}
DMS_DEBUG("Get soc die id success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetChipVersion(u32 devid, u8 *chip_version)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
ioarg.main_cmd = DMS_GET_CHIP_EXPAND_VERSION_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)&devid;
ioarg.input_len = sizeof(u32);
ioarg.output = (void *)chip_version;
ioarg.output_len = sizeof(u8);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
if (ret != DRV_ERROR_NOT_SUPPORT) {
DMS_ERR("Ioctl failed for chip version. (dev_id=%u; ret=%d)\n", devid, ret);
}
return ret;
}
DMS_DEBUG("Get chip version success.\n");
return DRV_ERROR_NONE;
}
#ifndef CFG_FEATURE_SRIOV
static int dms_virt_get_chip_info(dms_query_chip_info_t *chip_info)
{
int ret;
ret = dmanage_common_ioctl(DEVDRV_MANAGER_GET_CHIP_INFO, chip_info);
if (ret != 0) {
DMS_ERR("Ioctl failed. (ret=%d, errno=%d)\n", ret, errno);
return ret;
}
return DRV_ERROR_NONE;
}
#endif
drvError_t DmsGetChipInfo(dms_query_chip_info_t *chip_info)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
unsigned int dev_id;
if (chip_info == NULL) {
DMS_ERR("Chip info is null.\n");
return DRV_ERROR_PARA_ERROR;
}
if (chip_info->dev_id >= ASCEND_DEV_MAX_NUM) {
DMS_ERR("Device id is invalid. (dev_id=%u)\n", chip_info->dev_id);
return DRV_ERROR_PARA_ERROR;
}
#ifndef CFG_FEATURE_SRIOV
if (DmsGetVirtFlag() != 0) {
ret = dms_virt_get_chip_info(chip_info);
if (ret != 0) {
DMS_ERR("Get chip info failed. (dev_id=%u; ret=%d)\n", chip_info->dev_id, ret);
}
return ret;
}
#endif
dev_id = chip_info->dev_id;
ioarg.main_cmd = DMS_MAIN_CMD_BASIC;
ioarg.sub_cmd = DMS_SUBCMD_GET_CHIP_INFO;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)chip_info;
ioarg.output_len = sizeof(dms_query_chip_info_t);
ret = errno_to_user_errno(DmsIoctl(DMS_GET_CHIP_INFO, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Get chip info failed. (dev_id=%u; ret=%d)\n",
chip_info->dev_id, ret);
return ret;
}
return DRV_ERROR_NONE;
}
drvError_t dms_user_get_reboot_reason(unsigned int dev_id, void *reboot_reason, unsigned int len)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
(void)len;
ioarg.main_cmd = DMS_GET_GET_REBOOT_REASON_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = (unsigned int)sizeof(unsigned int);
ioarg.output = reboot_reason;
ioarg.output_len = (unsigned int)sizeof(struct dsmi_reboot_reason);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Dms get soc reboot reason failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_DEBUG("Get soc reboot reason success.\n");
return DRV_ERROR_NONE;
}
drvError_t halGetDeviceSplitMode(unsigned int dev_id, unsigned int *mode)
{
int ret;
unsigned int hostflag;
struct dms_ioctl_arg ioarg = {0};
if (mode == NULL) {
DMS_ERR("mode is null.\n");
return DRV_ERROR_PARA_ERROR;
}
ret = drvGetHostPhyMachFlag(dev_id, &hostflag);
if (ret != 0) {
DMS_ERR("Get host flag failed. (dev_id=%u; ret=%d).\n", dev_id, ret);
return DRV_ERROR_PARA_ERROR;
}
if (hostflag == DEVDRV_HOST_VM_MACH_FLAG) {
*mode = VMNG_VIRTUAL_SPLIT_MODE;
return DRV_ERROR_NONE;
}
ioarg.main_cmd = DMS_MAIN_CMD_BASIC;
ioarg.sub_cmd = DMS_SUBCMD_GET_DEV_SPLIT_MODE;
ioarg.filter_len = 0;
ioarg.input = (void *)&dev_id;
ioarg.input_len = sizeof(unsigned int);
ioarg.output = (void *)mode;
ioarg.output_len = sizeof(unsigned int);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "IOCTL failed. (ret=%d)\n", ret);
return ret;
}
return DRV_ERROR_NONE;
}
drvError_t drvGetDeviceSplitMode(unsigned int dev_id, unsigned int *mode)
{
return halGetDeviceSplitMode(dev_id, mode);
}
drvError_t DmsSetBistInfo(unsigned int dev_id, unsigned int cmd, unsigned char *in_buf, unsigned int buf_len)
{
int ret;
struct dms_set_bist_info_in bist_info;
struct dms_ioctl_arg ioarg = {0};
bist_info.dev_id = dev_id;
bist_info.buff = in_buf;
bist_info.buff_size = buf_len;
ioarg.main_cmd = DMS_SET_BIST_INFO_CMD;
ioarg.sub_cmd = cmd;
ioarg.filter_len = 0;
ioarg.input = (void *)&bist_info;
ioarg.input_len = sizeof(struct dms_set_bist_info_in);
ioarg.output = NULL;
ioarg.output_len = 0;
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Dms set bist info failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
DMS_INFO("Set bist info success.\n");
return DRV_ERROR_NONE;
}
drvError_t DmsGetBistInfo(unsigned int dev_id, unsigned int cmd, unsigned char *buf, unsigned int *len)
{
int ret;
struct dms_get_bist_info_in bist_info_in;
struct dms_get_bist_info_out bist_info_out;
struct dms_ioctl_arg ioarg = {0};
bist_info_in.dev_id = dev_id;
bist_info_in.sub_cmd = cmd;
bist_info_in.buff = buf;
bist_info_in.size = *len;
ioarg.main_cmd = DMS_GET_BIST_INFO_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)&bist_info_in;
ioarg.input_len = sizeof(struct dms_get_bist_info_in);
ioarg.output = &bist_info_out;
ioarg.output_len = sizeof(struct dms_get_bist_info_out);
ret = errno_to_user_errno(DmsIoctl(DMS_IOCTL_CMD, &ioarg));
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Dms get bist info failed, dev_id=%u ret=%d.\n", dev_id, ret);
return ret;
}
*len = bist_info_out.size;
DMS_DEBUG("Get bist info success.\n");
return DRV_ERROR_NONE;
}
#ifdef CFG_FEATURE_BIST
drvError_t DmsSetBistInfoMultiCmd(unsigned int dev_id, unsigned int cmd, unsigned char *in_buf, unsigned int buf_len)
{
int ret;
struct urd_cmd urd_cmd_data = {0};
struct urd_cmd_para urd_cmd_para_data = {0};
struct dms_set_bist_info_multi_cmd_in bist_info;
bist_info.sub_cmd = cmd;
bist_info.dev_id = dev_id;
bist_info.buff = in_buf;
bist_info.buff_size = buf_len;
urd_usr_cmd_fill(&urd_cmd_data, DMS_SET_BIST_INFO_CMD, ZERO_CMD, NULL, 0);
urd_usr_cmd_para_fill(&urd_cmd_para_data, (void *)&bist_info, sizeof(struct dms_set_bist_info_multi_cmd_in), NULL, 0);
ret = urd_dev_usr_cmd(dev_id, &urd_cmd_data, &urd_cmd_para_data);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Ioctl failed. (ret=%d; dev_id=%u)\n", ret, dev_id);
return ret;
}
DMS_INFO("Set bist info success. (dev_id=0x%x, cmd=0x%x)\n", dev_id, cmd);
return DRV_ERROR_NONE;
}
#endif
drvError_t DmsCtrlDeviceNode(unsigned int dev_id, struct dsmi_dtm_node_s dtm_node,
DSMI_DTM_OPCODE opcode, IN_OUT_BUF buf)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
struct dms_ctrl_device_node_in ctrl_device_node_in;
ctrl_device_node_in.dev_id = dev_id;
ctrl_device_node_in.node_type = dtm_node.node_type;
ctrl_device_node_in.node_id = dtm_node.node_id;
ctrl_device_node_in.sub_cmd = opcode;
ctrl_device_node_in.in_buf = buf.in_buf;
ctrl_device_node_in.in_size = buf.in_size;
ioarg.main_cmd = DMS_CTRL_DEVICE_NODE_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)&(ctrl_device_node_in);
ioarg.input_len = sizeof(struct dms_ctrl_device_node_in);
ioarg.output = NULL;
ioarg.output_len = 0;
ret = DmsIoctl(DMS_IOCTL_CMD, &ioarg);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "DmsCtrlDeviceNode failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
ret = errno_to_user_errno(ret);
return ret;
}
return DRV_ERROR_NONE;
}
drvError_t DmsGetAllDeviceNode(unsigned int dev_id, DEV_DTM_CAP capability,
struct dsmi_dtm_node_s node_info[], unsigned int *size)
{
int ret;
struct dms_ioctl_arg ioarg = {0};
struct dms_get_all_device_node_in get_all_device_node_in;
struct dms_get_all_device_node_out get_all_device_node_out = {0};
get_all_device_node_in.dev_id = dev_id;
get_all_device_node_in.capability = capability;
get_all_device_node_in.size = *size;
get_all_device_node_in.node_info = node_info;
ioarg.main_cmd = DMS_GET_ALL_DEVICE_NODE_CMD;
ioarg.sub_cmd = ZERO_CMD;
ioarg.filter_len = 0;
ioarg.input = (void *)&(get_all_device_node_in);
ioarg.input_len = sizeof(struct dms_get_all_device_node_in);
ioarg.output = (void *)&get_all_device_node_out;
ioarg.output_len = sizeof(struct dms_get_all_device_node_out);
ret = DmsIoctl(DMS_IOCTL_CMD, &ioarg);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "DmsGetAllDeviceNode failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
ret = errno_to_user_errno(ret);
return ret;
}
*size = get_all_device_node_out.out_size;
return DRV_ERROR_NONE;
}
#ifdef CFG_FEATURE_GET_DEV_INDEX_IN_GROUP
drvError_t DmsGetIndexInGroup(unsigned int dev_id, unsigned int main_cmd, unsigned int sub_cmd,
void *buf, unsigned int *size)
{
int ret = 0;
ret = DmsGetDeviceInfoEx(dev_id, main_cmd, sub_cmd, buf, size);
if (ret != 0) {
DMS_EX_NOTSUPPORT_ERR(ret, "Failed to obtain the device information. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
return DRV_ERROR_NONE;
}
#endif