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 : #include "product_card.h"
11 : #include <string.h>
12 : #include <stdlib.h>
13 : #include <syslog.h>
14 : #include "securec.h"
15 : #include "rank_info_types.h"
16 : #include "hal.h"
17 : #include "topo.h"
18 : #include "eid_util.h"
19 :
20 : #define MAX_CARD_ROOTINFO_LEN (2048)
21 : #define MAX_MESH_PORT_ID (9)
22 : #define CARD_4P_MESH_NUM (4)
23 : #define CARD_2P_MESH_NUM (2)
24 :
25 1 : int GetCardRankInfoLen(size_t *len)
26 : {
27 1 : (*len) = MAX_CARD_ROOTINFO_LEN;
28 1 : return 0;
29 : }
30 :
31 : /**
32 : *
33 : */
34 33 : static int ProcessLayerMesh(int npu_id, NetLayer *layer, dcmi_urma_eid_info_t *eid_list, size_t eid_cnt)
35 : {
36 33 : if (eid_cnt == 0) {
37 32 : return -1;
38 : }
39 1 : char server_id[MAX_INSTANCE_ID_LEN] = {0};
40 1 : char net_instance_id[MAX_INSTANCE_ID_LEN] = {0};
41 1 : get_server_id(server_id, sizeof(server_id));
42 : // 标卡没4个NPU一组, 可分多组, 标卡机头无单独的server id,因此使用mac地址作为server id
43 : // 和组ID组合起来作为mesh域的ID
44 1 : int ret = sprintf_s(net_instance_id, sizeof(net_instance_id), "%s", server_id);
45 1 : if (ret < 0) {
46 0 : return -1;
47 : }
48 1 : NetLayerInit(layer, 0, net_instance_id);
49 1 : NetLayerSetNetType(layer, NET_TYPE_MESH);
50 5 : for (size_t i = 0; i < eid_cnt; i++) {
51 4 : int portId = UrmaEidGetPortIdForCard(&eid_list[i].eid);
52 4 : if (portId > MAX_MESH_PORT_ID) {
53 1 : continue;
54 : }
55 3 : int dieId = UrmaEidGetDieIdForCard(&eid_list[i].eid);
56 : Addr addr;
57 3 : memset_s(&addr, sizeof(Addr), 0x00, sizeof(Addr));
58 3 : AddrSetEID(&addr, &eid_list[i].eid);
59 3 : char port[MAX_PORT_LEN] = {0};
60 3 : char planeId[MAX_PLANE_ID_LEN] = {0};
61 3 : int ret1 = sprintf_s(port, MAX_PORT_LEN, "%d/%d", dieId, portId);
62 3 : int ret2 = sprintf_s(planeId, MAX_PORT_LEN, "plane_%d", dieId);
63 3 : if (ret1 < 0 || ret2 < 0) {
64 : break;
65 : }
66 3 : AddrAddPort(&addr, port);
67 3 : AddrSetPlaneId(&addr, planeId);
68 3 : NetLayerAddAddr(layer, &addr);
69 : }
70 1 : return 0;
71 : }
72 :
73 33 : static int ProcessLayerMesh2P(int npu_id, NetLayer *layer, dcmi_urma_eid_info_t *eid_list, size_t eid_cnt)
74 : {
75 33 : if (eid_cnt == 0) {
76 32 : return -1;
77 : }
78 1 : char server_id[MAX_INSTANCE_ID_LEN] = {0};
79 1 : char net_instance_id[MAX_INSTANCE_ID_LEN] = {0};
80 1 : get_server_id(server_id, sizeof(server_id));
81 : // 2p标卡每2个NPU一组, 可分多组, 标卡机头无单独的server id,因此使用mac地址作为server id
82 : // 和组ID组合起来作为mesh域的ID
83 1 : int ret = sprintf_s(net_instance_id, sizeof(net_instance_id), "%s_%d", server_id, (npu_id / CARD_2P_MESH_NUM));
84 1 : if (ret < 0) {
85 0 : return -1;
86 : }
87 1 : NetLayerInit(layer, 0, net_instance_id);
88 1 : NetLayerSetNetType(layer, NET_TYPE_MESH);
89 5 : for (size_t i = 0; i < eid_cnt; i++) {
90 4 : int portId = UrmaEidGetPortIdForCard(&eid_list[i].eid);
91 : // 2P互联使用PortGroup EID
92 4 : if (portId <= MAX_MESH_PORT_ID) {
93 3 : continue;
94 : }
95 : Addr addr;
96 1 : memset_s(&addr, sizeof(Addr), 0x00, sizeof(Addr));
97 1 : AddrSetEID(&addr, &eid_list[i].eid);
98 1 : const int ports[] = {4, 5, 6, 8}; // 2P互联固定使用4568端口
99 5 : for (int j = 0; j < 4; ++j) {
100 4 : char port[MAX_PORT_LEN] = {0};
101 4 : sprintf_s(port, MAX_PORT_LEN, "0/%d", ports[j]);
102 4 : AddrAddPort(&addr, port);
103 : }
104 1 : AddrSetPlaneId(&addr, "plane_0");
105 1 : NetLayerAddAddr(layer, &addr);
106 : }
107 1 : return 0;
108 : }
109 :
110 99 : int GetCardRankInfo(int phyId, unsigned int mainboardId, void *buf, size_t *len)
111 : {
112 99 : if (buf == NULL || len == NULL) {
113 0 : return RET_NOK;
114 : }
115 : RootInfo rootinfo;
116 : Rank rank;
117 : NetLayer layer_mesh;
118 : NetLayer layer_roce;
119 99 : RootInfoInit(&rootinfo);
120 99 : RankInit(&rank, phyId, phyId);
121 99 : TopoGetFilePath(mainboardId, TOPO_TYPE_IGNORE, rootinfo.topo_file_path, MAX_TOPO_PATH_LEN);
122 :
123 99 : dcmi_urma_eid_info_t eid_list[MAX_EID_NUM] = {0};
124 99 : size_t eid_cnt = MAX_EID_NUM;
125 99 : hal_get_eid_list_by_phy_id(phyId, eid_list, &eid_cnt);
126 99 : int result = -1;
127 99 : if (mainboardId == MAIN_BOARD_ID_CARD_4PMESH) {
128 33 : result = ProcessLayerMesh(phyId, &layer_mesh, eid_list, eid_cnt);
129 : }
130 99 : if (mainboardId == MAIN_BOARD_ID_CARD_2PMESH) {
131 33 : result = ProcessLayerMesh2P(phyId, &layer_mesh, eid_list, eid_cnt);
132 : }
133 99 : if (result == 0) { // 无UB互联的标卡无0层
134 2 : RankAddNetLayer(&rank, &layer_mesh);
135 : }
136 99 : if (ProcessLayerRoce(phyId, &layer_roce) == 0) {
137 67 : RankAddNetLayer(&rank, &layer_roce);
138 : }
139 :
140 99 : RootInfoAddRank(&rootinfo, &rank);
141 99 : char *rootinfo_buf = RootInfoToString(&rootinfo);
142 99 : if (rootinfo_buf == NULL) {
143 0 : return -1;
144 : }
145 99 : if (*len < strlen(rootinfo_buf)) {
146 0 : *len = strlen(rootinfo_buf);
147 0 : free(rootinfo_buf);
148 0 : return -1;
149 : }
150 99 : errno_t ret = strcpy_s(buf, *len, rootinfo_buf);
151 99 : (*len) = strlen(buf);
152 99 : free(rootinfo_buf);
153 99 : return ret;
154 : }
|