Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "product_card.h"
12 : #include <string.h>
13 : #include <stdlib.h>
14 : #include <syslog.h>
15 : #include "securec.h"
16 : #include "rank_info_types.h"
17 : #include "hal.h"
18 : #include "topo.h"
19 : #include "eid_util.h"
20 :
21 : #define MAX_CARD_ROOTINFO_LEN (2048)
22 : #define MAX_MESH_PORT_ID (9)
23 : #define CARD_4P_MESH_NUM (4)
24 : #define CARD_2P_MESH_NUM (2)
25 :
26 1 : int GetCardRankInfoLen(size_t* len)
27 : {
28 1 : (*len) = MAX_CARD_ROOTINFO_LEN;
29 1 : return 0;
30 : }
31 :
32 : /**
33 : *
34 : */
35 33 : static int ProcessLayerMesh(int npu_id, NetLayer* layer, dcmi_urma_eid_info_t* eid_list, size_t eid_cnt)
36 : {
37 : (void)npu_id;
38 33 : if (eid_cnt == 0) {
39 32 : return -1;
40 : }
41 1 : char server_id[MAX_INSTANCE_ID_LEN] = {0};
42 1 : char net_instance_id[MAX_INSTANCE_ID_LEN] = {0};
43 1 : get_server_id(server_id, sizeof(server_id));
44 : // 标卡没4个NPU一组, 可分多组, 标卡机头无单独的server id,因此使用mac地址作为server id
45 : // 和组ID组合起来作为mesh域的ID
46 1 : int ret = sprintf_s(net_instance_id, sizeof(net_instance_id), "%s", server_id);
47 1 : if (ret < 0) {
48 0 : return -1;
49 : }
50 1 : NetLayerInit(layer, 0, net_instance_id);
51 1 : NetLayerSetNetType(layer, NET_TYPE_MESH);
52 5 : for (size_t i = 0; i < eid_cnt; i++) {
53 4 : int portId = UrmaEidGetPortIdForCard(&eid_list[i].eid);
54 4 : if (portId > MAX_MESH_PORT_ID) {
55 1 : continue;
56 : }
57 3 : int dieId = UrmaEidGetDieIdForCard(&eid_list[i].eid);
58 : Addr addr;
59 3 : memset_s(&addr, sizeof(Addr), 0x00, sizeof(Addr));
60 3 : AddrSetEID(&addr, &eid_list[i].eid);
61 3 : char port[MAX_PORT_LEN] = {0};
62 3 : char planeId[MAX_PLANE_ID_LEN] = {0};
63 3 : int ret1 = sprintf_s(port, MAX_PORT_LEN, "%d/%d", dieId, portId);
64 3 : int ret2 = sprintf_s(planeId, MAX_PORT_LEN, "plane_%d", dieId);
65 3 : if (ret1 < 0 || ret2 < 0) {
66 : break;
67 : }
68 3 : AddrAddPort(&addr, port);
69 3 : AddrSetPlaneId(&addr, planeId);
70 3 : NetLayerAddAddr(layer, &addr);
71 : }
72 1 : return 0;
73 : }
74 :
75 33 : static int ProcessLayerMesh2P(int npu_id, NetLayer* layer, dcmi_urma_eid_info_t* eid_list, size_t eid_cnt)
76 : {
77 33 : if (eid_cnt == 0) {
78 32 : return -1;
79 : }
80 1 : char server_id[MAX_INSTANCE_ID_LEN] = {0};
81 1 : char net_instance_id[MAX_INSTANCE_ID_LEN] = {0};
82 1 : get_server_id(server_id, sizeof(server_id));
83 : // 2p标卡每2个NPU一组, 可分多组, 标卡机头无单独的server id,因此使用mac地址作为server id
84 : // 和组ID组合起来作为mesh域的ID
85 1 : int ret = sprintf_s(net_instance_id, sizeof(net_instance_id), "%s_%d", server_id, (npu_id / CARD_2P_MESH_NUM));
86 1 : if (ret < 0) {
87 0 : return -1;
88 : }
89 1 : NetLayerInit(layer, 0, net_instance_id);
90 1 : NetLayerSetNetType(layer, NET_TYPE_MESH);
91 5 : for (size_t i = 0; i < eid_cnt; i++) {
92 4 : int portId = UrmaEidGetPortIdForCard(&eid_list[i].eid);
93 : // 2P互联使用PortGroup EID
94 4 : if (portId <= MAX_MESH_PORT_ID) {
95 3 : continue;
96 : }
97 : Addr addr;
98 1 : memset_s(&addr, sizeof(Addr), 0x00, sizeof(Addr));
99 1 : AddrSetEID(&addr, &eid_list[i].eid);
100 1 : const int ports[] = {4, 5, 6, 8}; // 2P互联固定使用4568端口
101 5 : for (int j = 0; j < 4; ++j) {
102 4 : char port[MAX_PORT_LEN] = {0};
103 4 : sprintf_s(port, MAX_PORT_LEN, "0/%d", ports[j]);
104 4 : AddrAddPort(&addr, port);
105 : }
106 1 : AddrSetPlaneId(&addr, "plane_0");
107 1 : NetLayerAddAddr(layer, &addr);
108 : }
109 1 : return 0;
110 : }
111 :
112 99 : int GetCardRankInfo(int phyId, unsigned int mainboardId, void* buf, size_t* len)
113 : {
114 99 : if (buf == NULL || len == NULL) {
115 0 : return RET_NOK;
116 : }
117 : RootInfo rootinfo;
118 : Rank rank;
119 : NetLayer layer_mesh;
120 : NetLayer layer_roce;
121 99 : RootInfoInit(&rootinfo);
122 99 : RankInit(&rank, phyId, phyId);
123 99 : TopoGetFilePath(mainboardId, TOPO_TYPE_IGNORE, rootinfo.topo_file_path, MAX_TOPO_PATH_LEN);
124 :
125 99 : dcmi_urma_eid_info_t eid_list[MAX_EID_NUM] = {0};
126 99 : size_t eid_cnt = MAX_EID_NUM;
127 99 : hal_get_eid_list_by_phy_id(phyId, eid_list, &eid_cnt);
128 99 : int result = -1;
129 99 : if (mainboardId == MAIN_BOARD_ID_CARD_4PMESH) {
130 33 : result = ProcessLayerMesh(phyId, &layer_mesh, eid_list, eid_cnt);
131 : }
132 99 : if (mainboardId == MAIN_BOARD_ID_CARD_2PMESH) {
133 33 : result = ProcessLayerMesh2P(phyId, &layer_mesh, eid_list, eid_cnt);
134 : }
135 99 : if (result == 0) { // 无UB互联的标卡无0层
136 2 : RankAddNetLayer(&rank, &layer_mesh);
137 : }
138 99 : if (ProcessLayerRoce(phyId, &layer_roce) == 0) {
139 67 : RankAddNetLayer(&rank, &layer_roce);
140 : }
141 :
142 99 : RootInfoAddRank(&rootinfo, &rank);
143 99 : char* rootinfo_buf = RootInfoToString(&rootinfo);
144 99 : if (rootinfo_buf == NULL) {
145 0 : return -1;
146 : }
147 99 : if (*len < strlen(rootinfo_buf)) {
148 0 : *len = strlen(rootinfo_buf);
149 0 : free(rootinfo_buf);
150 0 : return -1;
151 : }
152 99 : errno_t ret = strcpy_s(buf, *len, rootinfo_buf);
153 99 : (*len) = strlen(buf);
154 99 : free(rootinfo_buf);
155 99 : return ret;
156 : }
|