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 "eid_util.h"
12 : #include <stdio.h>
13 : #include <stdlib.h>
14 : #include <ctype.h>
15 : #include "securec.h"
16 :
17 : #define UE_ID_POS (14)
18 : #define HEX_BASE (16)
19 : #define PORT_POS (30)
20 : #define DIE_POS (39)
21 : #define DIE_OFFSET (3)
22 :
23 0 : static int Char2Int(char c, unsigned char * i)
24 : {
25 0 : if (!isxdigit(c)) {
26 0 : return -1;
27 : }
28 0 : if (!isdigit(c)) {
29 0 : return -1;
30 : }
31 0 : *i = toupper(c) - '0';
32 0 : return 0;
33 : }
34 :
35 0 : int EidGetFeId(const char *eidhexstr)
36 : {
37 0 : char fe = eidhexstr[UE_ID_POS];
38 0 : int fe_id = (int)strtol(&fe, NULL, HEX_BASE) >> 1;
39 0 : return fe_id;
40 : }
41 :
42 12 : int EidGetPortId(const char *eidhexstr, int *port_id)
43 : {
44 12 : unsigned char end = (unsigned char)strtoul(&eidhexstr[PORT_POS], NULL, HEX_BASE);
45 12 : unsigned int flag = 0x80;
46 12 : unsigned int tmp = (~flag & end);
47 12 : unsigned int port = tmp >> 3;
48 12 : *port_id = (int)port;
49 12 : return 0;
50 : }
51 :
52 0 : int EidGetDieId(const char* eidhexstr, int *die_id)
53 : {
54 0 : unsigned char d = 0;
55 0 : Char2Int(eidhexstr[DIE_POS], &d);
56 0 : *die_id = (int)((8 & d) >> DIE_OFFSET);
57 0 : return 0;
58 : }
59 :
60 : // 标卡
61 3 : int UrmaEidGetDieIdForCard(dcmi_urma_eid_t *eid)
62 : {
63 3 : unsigned char last = eid->raw[DCMI_URMA_EID_SIZE - 1];
64 3 : int die_id = (4 & last) == 0 ? 0 : 1;
65 3 : return die_id;
66 : }
67 :
68 8 : int UrmaEidGetPortIdForCard(dcmi_urma_eid_t *eid)
69 : {
70 : #define EID_PORT_LEFT_OFFSET (1)
71 : #define EID_PORT_RIGHT_OFFSET (4)
72 8 : unsigned char last = eid->raw[DCMI_URMA_EID_SIZE - 1];
73 8 : last = last << EID_PORT_LEFT_OFFSET;
74 8 : last = last >> EID_PORT_RIGHT_OFFSET;
75 8 : return (int)last;
76 : }
77 :
78 :
79 : // 服务器和PoD
80 45 : int UrmaEidGetFeId(const dcmi_urma_eid_t *eid)
81 : {
82 : #define FE_POS (6)
83 45 : unsigned char fe = eid->raw[FE_POS];
84 45 : const unsigned char mask = 0x7f; // fe使用7bit
85 45 : fe = fe & mask;
86 45 : return (int)fe;
87 : }
88 :
89 : #define RAW_PORT_AND_DIE_POS (5)
90 : #define RAW_PORT_BIT_LEN (6)
91 : /**
92 : * @brief 获取URMA eid中的portID
93 : * port_id和die id 在同一个unsigned char中
94 : * |0|1|2|3|4|5|6|7|
95 : * |die| port_id |
96 : * @param eid URMA eid结构体指针
97 : * @return int portID
98 : */
99 233 : int UrmaEidGetPortId(const dcmi_urma_eid_t *eid)
100 : {
101 233 : unsigned char dieAndPort = eid->raw[RAW_PORT_AND_DIE_POS];
102 233 : const unsigned char mask = 0x3F;
103 233 : unsigned char port = dieAndPort & mask;
104 233 : return (int)port;
105 : }
106 :
107 103 : int UrmaEidGetDieId(const dcmi_urma_eid_t *eid)
108 : {
109 103 : unsigned char dieAndPort = eid->raw[RAW_PORT_AND_DIE_POS];
110 103 : unsigned char dieId = dieAndPort >> RAW_PORT_BIT_LEN;
111 103 : return (int)dieId;
112 : }
113 :
114 0 : int GetMaxFeId(const dcmi_urma_eid_info_t *eidList, size_t eidCnt)
115 : {
116 0 : int maxFeId = -1;
117 0 : for (size_t i = 0; i < eidCnt; ++i) {
118 0 : int feId = UrmaEidGetFeId(&eidList[i].eid);
119 0 : if (feId > maxFeId) {
120 0 : maxFeId = feId;
121 : }
122 : }
123 0 : return maxFeId;
124 : }
125 :
126 : /**
127 : * @brief 判断是否为portgroup
128 : * 判断依据:portID为0x3F时,为portgroup
129 : * @param eid URMA eid结构体指针
130 : * @return int 1为portgroup,0为物理ID
131 : */
132 126 : int UrmaEidIsPortGroup(const dcmi_urma_eid_t *eid)
133 : {
134 126 : const int pgPortId = 0x3F;
135 126 : int port = UrmaEidGetPortId(eid);
136 126 : if (port == pgPortId) {
137 25 : return 1;
138 : }
139 101 : return 0;
140 : }
141 :
142 : /**
143 : * 判断是否是UBOE
144 : * 在第7 btye位置上
145 : * 11000000 为UBOE, 使用0xc0判断
146 : * 10000000 为UBOE, 使用0x80判断
147 : * @param eid URMA eid结构体指针
148 : * @return int 1为UBOE,0为不是UBOE
149 : */
150 55 : int UrmaEidIsUBOE(const dcmi_urma_eid_t *eid)
151 : {
152 55 : const int uboeMask = 0xc0;
153 55 : const int flagPos = 7; // UBOE和UBG标志位的位置
154 55 : unsigned char flag = eid->raw[flagPos];
155 55 : if ((uboeMask & flag) == uboeMask) {
156 7 : return 1;
157 : }
158 48 : return 0;
159 : }
160 :
161 : /**
162 : * 判断是否是UBG, 判断原理见UrmaEidIsUBOE
163 : * @param eid URMA eid结构体指针
164 : * @return int 1为UBG,0为不是UBG
165 : */
166 3 : int UrmaEidIsUBG(const dcmi_urma_eid_t *eid)
167 : {
168 3 : const unsigned char bitMask = 0xc0;
169 3 : const unsigned char ubgFlag = 0x80; // UBG的flag
170 3 : const int flagPos = 7; // UBOE和UBG标志位的位置
171 3 : unsigned char flag = eid->raw[flagPos];
172 3 : int bit = (flag & bitMask); //
173 3 : if (bit == ubgFlag) {
174 1 : return 1;
175 : }
176 2 : return 0;
177 : }
178 :
179 5 : int UrmaEid2CNA(const dcmi_urma_eid_t *eid, char *cna, size_t cnaSize)
180 : {
181 5 : if (cna == NULL || cnaSize == 0) {
182 0 : return -1;
183 : }
184 5 : const int ipPos1 = 6; // ip 第一个字节位置
185 5 : const int ipPos2 = 12;
186 5 : const int ipPos3 = 13;
187 5 : const int ipPos4 = 14;
188 5 : unsigned char ip1 = eid->raw[ipPos1];
189 5 : unsigned char ip2 = eid->raw[ipPos2];
190 5 : unsigned char ip3 = eid->raw[ipPos3];
191 5 : unsigned char ip4 = eid->raw[ipPos4];
192 5 : return sprintf_s(cna, cnaSize, "%u.%u.%u.%u", ip1, ip2, ip3,ip4);
193 : }
194 :
195 42 : int UBEntityGetId(const UBEntity *ue)
196 : {
197 42 : if (ue->eidNum == 0) {
198 0 : return -1;
199 : }
200 42 : return UrmaEidGetFeId(&ue->eidList[0].eid);
201 : }
202 :
203 8 : int UBEntityGetDieId(const UBEntity *ue)
204 : {
205 8 : if (ue->eidNum == 0) {
206 0 : return -1;
207 : }
208 8 : return UrmaEidGetDieId(&ue->eidList[0].eid);
209 : }
210 :
211 9 : int UBEntityGetPortGroupIdx(const UBEntity *ue)
212 : {
213 20 : for (int i = 0; i < (int)ue->eidNum; ++i) {
214 20 : if (UrmaEidIsPortGroup(&ue->eidList[i].eid)) {
215 9 : return i;
216 : }
217 : }
218 : // 没有找到
219 0 : return -1;
220 : }
221 :
222 65 : int UBGetMaxEntityId(const UEList *ueList, int dieId)
223 : {
224 65 : int maxId = -1;
225 69 : for (unsigned int i = 0; i < ueList->ueNum; ++i) {
226 4 : if (ueList->ueList[i].eidNum == 0 || UBEntityGetDieId(&ueList->ueList[i]) != dieId) {
227 2 : continue;
228 : }
229 : // 一个UBEntity下的所有eid的Entity ID相同
230 2 : int id = UrmaEidGetFeId(&ueList->ueList[i].eidList[0].eid);
231 2 : if (id > maxId) {
232 2 : maxId = id;
233 : }
234 : }
235 65 : return maxId;
236 : }
|