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 <stdlib.h>
12 : #include <sys/types.h>
13 : #include <urma_opcode.h>
14 : #include <udma_u_ctl.h>
15 : #include "securec.h"
16 : #include "user_log.h"
17 : #include "dl_urma_function.h"
18 : #include "ra_rs_err.h"
19 : #include "rs_ctx_inner.h"
20 : #include "rs_ub.h"
21 : #include "rs_ub_dfx.h"
22 :
23 : urma_cr_t gCrBuf[RS_WC_NUM];
24 :
25 2 : STATIC int RsUbCtxGetCqeAuxInfo(struct RsUbDevCb *devCb, struct HccpAuxInfoIn *infoIn,
26 : struct HccpAuxInfoOut *infoOut)
27 : {
28 2 : struct udma_u_cqe_aux_info_out cqeInfoOut = {0};
29 2 : struct udma_u_cqe_info_in cqeInfoIn = {0};
30 2 : urma_user_ctl_out_t out = {0};
31 2 : urma_user_ctl_in_t in = {0};
32 2 : int ret = 0;
33 :
34 2 : cqeInfoOut.aux_info_num = AUX_INFO_NUM_MAX;
35 2 : cqeInfoOut.aux_info_type = infoOut->auxInfoType;
36 2 : cqeInfoOut.aux_info_value = infoOut->auxInfoValue;
37 2 : cqeInfoIn.status = infoIn->cqe.status;
38 2 : cqeInfoIn.s_r = infoIn->cqe.sR;
39 2 : in.addr = (uint64_t)(uintptr_t)&cqeInfoIn;
40 2 : in.len = (uint32_t)sizeof(struct udma_u_cqe_info_in);
41 2 : in.opcode = UDMA_U_USER_CTL_QUERY_CQE_AUX_INFO;
42 2 : out.addr = (uint64_t)(uintptr_t)&cqeInfoOut;
43 2 : out.len = (uint32_t)sizeof(struct udma_u_cqe_aux_info_out);
44 2 : ret = RsUrmaUserCtl(devCb->urmaCtx, &in, &out);
45 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_urma_user_ctl query cqe aux info failed, ret:%d errno:%d", ret, errno),
46 : -EOPENSRC);
47 :
48 1 : infoOut->auxInfoNum = cqeInfoOut.aux_info_num;
49 1 : return ret;
50 : }
51 :
52 2 : STATIC int RsUbCtxGetAeAuxInfo(struct RsUbDevCb *devCb, struct HccpAuxInfoIn *infoIn,
53 : struct HccpAuxInfoOut *infoOut)
54 : {
55 2 : struct udma_u_ae_aux_info_out aeInfoOut = {0};
56 2 : struct udma_u_ae_info_in aeInfoIn = {0};
57 2 : urma_user_ctl_out_t out = {0};
58 2 : urma_user_ctl_in_t in = {0};
59 2 : int ret = 0;
60 :
61 2 : aeInfoOut.aux_info_num = AUX_INFO_NUM_MAX;
62 2 : aeInfoOut.aux_info_type = infoOut->auxInfoType;
63 2 : aeInfoOut.aux_info_value = infoOut->auxInfoValue;
64 2 : aeInfoIn.event_type = infoIn->ae.eventType;
65 2 : in.addr = (uint64_t)(uintptr_t)&aeInfoIn;
66 2 : in.len = (uint32_t)sizeof(struct udma_u_ae_info_in);
67 2 : in.opcode = UDMA_U_USER_CTL_QUERY_AE_AUX_INFO;
68 2 : out.addr = (uint64_t)(uintptr_t)&aeInfoOut;
69 2 : out.len = (uint32_t)sizeof(struct udma_u_ae_aux_info_out);
70 2 : ret = RsUrmaUserCtl(devCb->urmaCtx, &in, &out);
71 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_urma_user_ctl query ae aux info failed, ret:%d errno:%d", ret, errno),
72 : -EOPENSRC);
73 :
74 1 : infoOut->auxInfoNum = aeInfoOut.aux_info_num;
75 1 : return ret;
76 : }
77 :
78 5 : int RsUbCtxGetAuxInfo(struct RsUbDevCb *devCb, struct HccpAuxInfoIn *infoIn, struct HccpAuxInfoOut *infoOut)
79 : {
80 5 : int ret = 0;
81 :
82 5 : if (infoIn->type == AUX_INFO_IN_TYPE_CQE) {
83 2 : ret = RsUbCtxGetCqeAuxInfo(devCb, infoIn, infoOut);
84 3 : } else if (infoIn->type == AUX_INFO_IN_TYPE_AE) {
85 2 : ret = RsUbCtxGetAeAuxInfo(devCb, infoIn, infoOut);
86 : } else {
87 1 : hccp_err("invalid info_in->type[%d]", infoIn->type);
88 1 : ret = -EINVAL;
89 : }
90 :
91 5 : return ret;
92 : }
93 :
94 1 : STATIC void RsUdmaRetryTimeoutExceptionCheck(struct SensorNode *sensorNode, urma_cr_t *cr)
95 : {
96 1 : int ret = 0;
97 :
98 1 : if (cr->status != URMA_CR_RNR_RETRY_CNT_EXC_ERR) {
99 0 : return;
100 : }
101 :
102 1 : ret = RsRetryTimeoutExceptionCheck(sensorNode);
103 :
104 1 : hccp_warn("update sensor state logic_devid(%u), jettyId(%u), sensor_update_cnt(%d), ret(%d)\n",
105 : sensorNode->logicDevid, cr->local_id, sensorNode->sensorUpdateCnt, ret);
106 : }
107 :
108 1 : STATIC void RsUdmaSaveCqeErrInfo(uint32_t status, struct RsCtxJettyCb *jettyCb)
109 : {
110 1 : RS_PTHREAD_MUTEX_LOCK(&jettyCb->crErrInfo.mutex);
111 1 : if (jettyCb->crErrInfo.info.status != 0) {
112 0 : RS_PTHREAD_MUTEX_ULOCK(&jettyCb->crErrInfo.mutex);
113 0 : return;
114 : }
115 1 : jettyCb->crErrInfo.info.status = status;
116 1 : jettyCb->crErrInfo.info.jettyId = jettyCb->jetty->jetty_id.id;
117 1 : RsGetCurTime(&jettyCb->crErrInfo.info.time);
118 1 : RS_PTHREAD_MUTEX_ULOCK(&jettyCb->crErrInfo.mutex);
119 :
120 1 : RS_PTHREAD_MUTEX_LOCK(&jettyCb->devCb->cqeErrCntMutex);
121 1 : jettyCb->devCb->cqeErrCnt++;
122 1 : RS_PTHREAD_MUTEX_ULOCK(&jettyCb->devCb->cqeErrCntMutex);
123 : }
124 :
125 1 : STATIC void RsJfcCallbackProcess(struct RsCtxJettyCb *jettyCb, urma_cr_t *cr, urma_jfc_t *jfc)
126 : {
127 1 : if (cr->status != URMA_CR_SUCCESS) {
128 1 : RsUdmaSaveCqeErrInfo(cr->status, jettyCb);
129 1 : RsUdmaRetryTimeoutExceptionCheck(&jettyCb->devCb->rscb->sensorNode, cr);
130 : }
131 1 : }
132 :
133 0 : STATIC int RsHandleEpollPollJfc(struct RsUbDevCb *devCb, urma_jfce_t *jfce)
134 : {
135 0 : struct RsCtxJettyCb *jettyCb = NULL;
136 0 : urma_jfc_t *evJfc = NULL;
137 0 : uint32_t jettyId = 0;
138 0 : uint32_t ackCnt = 1;
139 : int polledCnt, i;
140 0 : int waitCnt = 0;
141 0 : int retTmp = 0;
142 0 : int ret = 0;
143 :
144 0 : waitCnt = RsUrmaWaitJfc(jfce, 1, 0, &evJfc);
145 0 : if (waitCnt == 0) {
146 0 : return -EAGAIN;
147 : }
148 0 : if (waitCnt != 1) {
149 0 : hccp_run_warn("rs_urma_wait_jfc failed, ret:%d errno:%d", waitCnt, errno);
150 0 : return -EOPENSRC;
151 : }
152 0 : RsUrmaAckJfc((urma_jfc_t **)&evJfc, &ackCnt, 1);
153 :
154 0 : polledCnt = RsUrmaPollJfc(evJfc, RS_WC_NUM, gCrBuf);
155 0 : if (polledCnt > RS_WC_NUM || polledCnt < 0) {
156 0 : hccp_run_warn("rs_urma_poll_jfc failed, ret:%d errno:%d", polledCnt, errno);
157 0 : ret = -EOPENSRC;
158 0 : goto rearm_jfc;
159 : }
160 :
161 0 : for (i = 0; i < polledCnt; i++) {
162 0 : jettyId = gCrBuf[i].local_id;
163 0 : RS_PTHREAD_MUTEX_LOCK(&devCb->mutex);
164 0 : ret = RsUbGetJettyCb(devCb, jettyId, &jettyCb);
165 0 : if (ret != 0) {
166 0 : hccp_err("get jetty_cb failed, ret:%d, jettyId[%u]:%u", ret, i, jettyId);
167 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->mutex);
168 0 : break;
169 : }
170 0 : jettyCb->qpShareInfoAddr->ciVal += 1;
171 0 : RsJfcCallbackProcess(jettyCb, &(gCrBuf[i]), evJfc);
172 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->mutex);
173 : }
174 :
175 0 : rearm_jfc:
176 0 : retTmp = RsUrmaRearmJfc(evJfc, false);
177 0 : CHK_PRT_RETURN(retTmp != 0, hccp_err("rs_urma_rearm_jfc failed, retTmp:%d errno:%d", retTmp, errno), -EOPENSRC);
178 0 : return ret;
179 : }
180 :
181 0 : STATIC int RsHandleJfcEpollEvent(struct RsUbDevCb *devCb, int fd)
182 : {
183 0 : struct RsCtxJfceCb *jfceCbCurr = NULL;
184 0 : struct RsCtxJfceCb *jfceCbNext = NULL;
185 0 : urma_jfce_t *jfceTmp = NULL;
186 :
187 0 : RS_LIST_GET_HEAD_ENTRY(jfceCbCurr, jfceCbNext, &devCb->jfceList, list, struct RsCtxJfceCb);
188 0 : for (; (&jfceCbCurr->list) != &devCb->jfceList;
189 0 : jfceCbCurr = jfceCbNext, jfceCbNext = list_entry(jfceCbNext->list.next, struct RsCtxJfceCb, list)) {
190 0 : jfceTmp = (urma_jfce_t *)(uintptr_t)jfceCbCurr->jfceAddr;
191 0 : if (jfceTmp->fd == fd) {
192 0 : return RsHandleEpollPollJfc(devCb, jfceTmp);
193 : }
194 : }
195 :
196 0 : return -ENODEV;
197 : }
198 :
199 0 : int RsEpollEventJfcInHandle(struct rs_cb *rsCb, int fd)
200 : {
201 0 : struct RsUbDevCb *devCbCurr = NULL;
202 0 : struct RsUbDevCb *devCbNext = NULL;
203 0 : int ret = 0;
204 :
205 0 : if (rsCb->protocol != PROTOCOL_UDMA) {
206 0 : return -ENODEV;
207 : }
208 :
209 0 : RS_LIST_GET_HEAD_ENTRY(devCbCurr, devCbNext, &rsCb->udevList, list, struct RsUbDevCb);
210 0 : for (; (&devCbCurr->list) != &rsCb->udevList;
211 0 : devCbCurr = devCbNext, devCbNext = list_entry(devCbNext->list.next, struct RsUbDevCb, list)) {
212 0 : ret = RsHandleJfcEpollEvent(devCbCurr, fd);
213 0 : if (ret == -ENODEV) {
214 0 : continue;
215 : }
216 0 : return ret;
217 : }
218 :
219 0 : return -ENODEV;
220 : }
221 :
222 0 : STATIC int RsUbFillAsyncEventCb(urma_async_event_t *event, struct RsUbDevCb *devCb,
223 : struct RsCtxAsyncEventCb *asyncEventCb)
224 : {
225 0 : int ret = 0;
226 :
227 0 : switch (event->event_type) {
228 0 : case URMA_EVENT_JFC_ERR:
229 0 : asyncEventCb->resId = event->element.jfc->jfc_id.id;
230 0 : ret = RsUrmaGetJfcOpt(event->element.jfc, URMA_JFC_FULL_CTX, asyncEventCb->context,
231 : JFC_CONTEXT_LEN);
232 0 : CHK_PRT_RETURN(ret != 0, hccp_err("RsUrmaGetJfcOpt failed, ret:%d, jfcId:%u devIndex:0x%0x", ret,
233 : event->element.jfc->jfc_id.id, devCb->index), -EOPENSRC);
234 0 : asyncEventCb->len = JFC_CONTEXT_LEN;
235 0 : break;
236 0 : case URMA_EVENT_JFS_ERR:
237 0 : asyncEventCb->resId = event->element.jfs->jfs_id.id;
238 0 : break;
239 0 : case URMA_EVENT_JFR_ERR:
240 : case URMA_EVENT_JFR_LIMIT:
241 0 : asyncEventCb->resId = event->element.jfr->jfr_id.id;
242 0 : break;
243 0 : case URMA_EVENT_JETTY_ERR:
244 : case URMA_EVENT_JETTY_LIMIT:
245 0 : asyncEventCb->resId = event->element.jetty->jetty_id.id;
246 0 : ret = RsUrmaGetJettyOpt(event->element.jetty, URMA_JETTY_FULL_CTX, asyncEventCb->context,
247 : JETTY_CONTEXT_LEN);
248 0 : CHK_PRT_RETURN(ret != 0, hccp_err("RsUrmaGetJettyOpt failed, ret:%d, jettyId:%u devIndex:0x%0x", ret,
249 : event->element.jetty->jetty_id.id, devCb->index), -EOPENSRC);
250 0 : asyncEventCb->len = JETTY_CONTEXT_LEN;
251 0 : break;
252 0 : case URMA_EVENT_JETTY_GRP_ERR:
253 0 : asyncEventCb->resId = event->element.jetty_grp->jetty_grp_id.id;
254 0 : break;
255 0 : case URMA_EVENT_PORT_ACTIVE:
256 : case URMA_EVENT_PORT_DOWN:
257 0 : asyncEventCb->resId = event->element.port_id;
258 0 : break;
259 0 : case URMA_EVENT_EID_CHANGE:
260 0 : asyncEventCb->resId = event->element.eid_idx;
261 0 : break;
262 0 : case URMA_EVENT_DEV_FATAL:
263 : case URMA_EVENT_ELR_ERR:
264 : case URMA_EVENT_ELR_DONE:
265 0 : asyncEventCb->resId = devCb->index;
266 0 : break;
267 0 : default:
268 0 : hccp_warn("invalid event_type:%d devIndex:0x%x", event->event_type, devCb->index);
269 0 : break;
270 : }
271 0 : return ret;
272 : }
273 :
274 0 : STATIC int RsUbGetSaveAsyncEvent(struct RsUbDevCb *devCb)
275 : {
276 0 : struct RsCtxAsyncEventCb *asyncEventCb = NULL;
277 0 : urma_async_event_t *event = NULL;
278 0 : int ret = 0;
279 :
280 0 : asyncEventCb = calloc(1, sizeof(struct RsCtxAsyncEventCb));
281 0 : CHK_PRT_RETURN(asyncEventCb == NULL, hccp_err("calloc asyncEventCb failed"), -ENOMEM);
282 0 : asyncEventCb->devCb = devCb;
283 0 : event = &asyncEventCb->asyncEvent;
284 :
285 0 : ret = RsUrmaGetAsyncEvent(devCb->urmaCtx, event);
286 0 : if (ret != 0) {
287 0 : hccp_err("RsUrmaGetAsyncEvent failed, ret:%d errno:%d devIndex:0x%x", ret, errno, devCb->index);
288 0 : ret = -EOPENSRC;
289 0 : goto free_event_cb;
290 : }
291 0 : RsUrmaAckAsyncEvent(event);
292 :
293 0 : ret = RsUbFillAsyncEventCb(event, devCb, asyncEventCb);
294 0 : if (ret != 0) {
295 0 : hccp_err("RsUbFillAsyncEventCb failed, ret:%d devIndex:0x%x", ret, devCb->index);
296 0 : goto free_event_cb;
297 : }
298 :
299 0 : RsListAddTail(&asyncEventCb->list, &devCb->asyncEventList);
300 0 : devCb->asyncEventCnt++;
301 :
302 0 : return ret;
303 :
304 0 : free_event_cb:
305 0 : free(asyncEventCb);
306 0 : asyncEventCb = NULL;
307 0 : return ret;
308 : }
309 :
310 0 : int RsEpollEventUrmaAsyncEventInHandle(struct rs_cb *rsCb, int fd)
311 : {
312 0 : struct RsUbDevCb *devCbCurr = NULL;
313 0 : struct RsUbDevCb *devCbNext = NULL;
314 0 : int ret = 0;
315 :
316 0 : if (rsCb->protocol != PROTOCOL_UDMA) {
317 0 : return -ENODEV;
318 : }
319 :
320 0 : RS_LIST_GET_HEAD_ENTRY(devCbCurr, devCbNext, &rsCb->udevList, list, struct RsUbDevCb);
321 0 : for (; (&devCbCurr->list) != &rsCb->udevList;
322 0 : devCbCurr = devCbNext, devCbNext = list_entry(devCbNext->list.next, struct RsUbDevCb, list)) {
323 0 : RS_PTHREAD_MUTEX_LOCK(&devCbCurr->mutex);
324 0 : if (devCbCurr->urmaCtx != NULL && devCbCurr->urmaCtx->async_fd == fd) {
325 0 : ret = RsUbGetSaveAsyncEvent(devCbCurr);
326 0 : if (ret != 0) {
327 0 : hccp_err("rs_ub_get_save_async_event failed, ret:%d devIndex:0x%x", ret, devCbCurr->index);
328 : }
329 0 : RS_PTHREAD_MUTEX_ULOCK(&devCbCurr->mutex);
330 0 : return ret;
331 : }
332 0 : RS_PTHREAD_MUTEX_ULOCK(&devCbCurr->mutex);
333 : }
334 :
335 0 : return -ENODEV;
336 : }
337 :
338 0 : STATIC int RsUbCtxFillAsyncEvent(struct RsCtxAsyncEventCb *eventCb, struct AsyncEvent *asyncEvent)
339 : {
340 0 : int ret = 0;
341 :
342 0 : asyncEvent->resId = eventCb->resId;
343 0 : asyncEvent->eventType = eventCb->asyncEvent.event_type;
344 0 : asyncEvent->len = eventCb->len;
345 :
346 0 : ret = memcpy_s(asyncEvent->context, CONTEXT_MAX_LEN, eventCb->context, eventCb->len);
347 0 : CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s failed, ret:%d asyncEvent len:%u eventCb len:%u", ret,
348 : CONTEXT_MAX_LEN, eventCb->len), -ESAFEFUNC);
349 :
350 0 : return ret;
351 : }
352 :
353 0 : void RsUbCtxGetAsyncEvents(struct RsUbDevCb *devCb, struct AsyncEvent asyncEvents[], unsigned int *num)
354 : {
355 0 : struct RsCtxAsyncEventCb *eventCbCurr = NULL;
356 0 : struct RsCtxAsyncEventCb *eventCbNext = NULL;
357 0 : unsigned int expectedNum = *num;
358 0 : int ret = 0;
359 :
360 0 : *num = 0;
361 0 : if (RsListEmpty(&devCb->asyncEventList)) {
362 0 : return;
363 : }
364 :
365 0 : RS_PTHREAD_MUTEX_LOCK(&devCb->mutex);
366 0 : RS_LIST_GET_HEAD_ENTRY(eventCbCurr, eventCbNext, &devCb->asyncEventList, list, struct RsCtxAsyncEventCb);
367 0 : for (; (&eventCbCurr->list) != &devCb->asyncEventList; eventCbCurr = eventCbNext,
368 0 : eventCbNext = list_entry(eventCbNext->list.next, struct RsCtxAsyncEventCb, list)) {
369 0 : ret = RsUbCtxFillAsyncEvent(eventCbCurr, &asyncEvents[*num]);
370 0 : if (ret != 0) {
371 0 : hccp_err("RsUbCtxFillAsyncEvent failed, ret:%d devIndex:0x%x", ret, devCb->index);
372 0 : RsUbFreeAsyncEventCb(devCb, eventCbCurr);
373 0 : break;
374 : }
375 0 : (*num)++;
376 0 : RsUbFreeAsyncEventCb(devCb, eventCbCurr);
377 0 : if (*num == expectedNum) {
378 0 : break;
379 : }
380 : }
381 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->mutex);
382 : }
383 :
384 0 : int RsUbGetJettyContext(struct RsUbDevCb *devCb, unsigned int id, uint8_t context[], unsigned int *len)
385 : {
386 0 : struct RsCtxJettyCb *jettyCb = NULL;
387 0 : int ret = 0;
388 :
389 0 : ret = RsUbGetJettyCb(devCb, id, &jettyCb);
390 0 : CHK_PRT_RETURN(ret != 0, hccp_err("get jettyCb failed, ret:%d, jettyId:%u", ret, id), ret);
391 :
392 0 : ret = RsUrmaGetJettyOpt(jettyCb->jetty, URMA_JETTY_FULL_CTX, (void *)context, JETTY_CONTEXT_LEN);
393 0 : CHK_PRT_RETURN(ret != 0, hccp_err("RsUrmaGetJettyOpt failed, ret:%d, jettyId:%u", ret, id), -EOPENSRC);
394 :
395 0 : *len = JETTY_CONTEXT_LEN;
396 0 : return ret;
397 : }
|