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