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 : (void)jfc;
126 1 : if (cr->status != URMA_CR_SUCCESS) {
127 1 : RsUdmaSaveCqeErrInfo(cr->status, jettyCb);
128 1 : RsUdmaRetryTimeoutExceptionCheck(&jettyCb->devCb->rscb->sensorNode, cr);
129 : }
130 1 : }
131 :
132 0 : STATIC int RsHandleEpollPollJfc(struct RsUbDevCb *devCb, urma_jfce_t *jfce)
133 : {
134 0 : struct RsCtxJettyCb *jettyCb = NULL;
135 0 : urma_jfc_t *evJfc = NULL;
136 0 : uint32_t jettyId = 0;
137 0 : uint32_t ackCnt = 1;
138 : int polledCnt, i;
139 0 : int waitCnt = 0;
140 0 : int retTmp = 0;
141 0 : int ret = 0;
142 :
143 0 : waitCnt = RsUrmaWaitJfc(jfce, 1, 0, &evJfc);
144 0 : if (waitCnt == 0) {
145 0 : return -EAGAIN;
146 : }
147 0 : if (waitCnt != 1) {
148 0 : hccp_run_warn("rs_urma_wait_jfc failed, ret:%d errno:%d", waitCnt, errno);
149 0 : return -EOPENSRC;
150 : }
151 0 : RsUrmaAckJfc((urma_jfc_t **)&evJfc, &ackCnt, 1);
152 :
153 0 : polledCnt = RsUrmaPollJfc(evJfc, RS_WC_NUM, gCrBuf);
154 0 : if (polledCnt > RS_WC_NUM || polledCnt < 0) {
155 0 : hccp_run_warn("rs_urma_poll_jfc failed, ret:%d errno:%d", polledCnt, errno);
156 0 : ret = -EOPENSRC;
157 0 : goto rearm_jfc;
158 : }
159 :
160 0 : for (i = 0; i < polledCnt; i++) {
161 0 : jettyId = gCrBuf[i].local_id;
162 0 : RS_PTHREAD_MUTEX_LOCK(&devCb->mutex);
163 0 : ret = RsUbGetJettyCb(devCb, jettyId, &jettyCb);
164 0 : if (ret != 0) {
165 0 : hccp_err("get jetty_cb failed, ret:%d, jettyId[%u]:%u", ret, i, jettyId);
166 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->mutex);
167 0 : break;
168 : }
169 0 : jettyCb->qpShareInfoAddr->ciVal += 1;
170 0 : RsJfcCallbackProcess(jettyCb, &(gCrBuf[i]), evJfc);
171 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->mutex);
172 : }
173 :
174 0 : rearm_jfc:
175 0 : retTmp = RsUrmaRearmJfc(evJfc, false);
176 0 : CHK_PRT_RETURN(retTmp != 0, hccp_err("rs_urma_rearm_jfc failed, retTmp:%d errno:%d", retTmp, errno), -EOPENSRC);
177 0 : return ret;
178 : }
179 :
180 0 : STATIC int RsHandleJfcEpollEvent(struct RsUbDevCb *devCb, int fd)
181 : {
182 0 : struct RsCtxJfceCb *jfceCbCurr = NULL;
183 0 : struct RsCtxJfceCb *jfceCbNext = NULL;
184 0 : urma_jfce_t *jfceTmp = NULL;
185 :
186 0 : RS_LIST_GET_HEAD_ENTRY(jfceCbCurr, jfceCbNext, &devCb->jfceList, list, struct RsCtxJfceCb);
187 0 : for (; (&jfceCbCurr->list) != &devCb->jfceList;
188 0 : jfceCbCurr = jfceCbNext, jfceCbNext = list_entry(jfceCbNext->list.next, struct RsCtxJfceCb, list)) {
189 0 : jfceTmp = (urma_jfce_t *)(uintptr_t)jfceCbCurr->jfceAddr;
190 0 : if (jfceTmp->fd == fd) {
191 0 : return RsHandleEpollPollJfc(devCb, jfceTmp);
192 : }
193 : }
194 :
195 0 : return -ENODEV;
196 : }
197 :
198 0 : int RsEpollEventJfcInHandle(struct rs_cb *rsCb, int fd)
199 : {
200 0 : struct RsUbDevCb *devCbCurr = NULL;
201 0 : struct RsUbDevCb *devCbNext = NULL;
202 0 : int ret = 0;
203 :
204 0 : if (rsCb->protocol != PROTOCOL_UDMA) {
205 0 : return -ENODEV;
206 : }
207 :
208 0 : RS_LIST_GET_HEAD_ENTRY(devCbCurr, devCbNext, &rsCb->udevList, list, struct RsUbDevCb);
209 0 : for (; (&devCbCurr->list) != &rsCb->udevList;
210 0 : devCbCurr = devCbNext, devCbNext = list_entry(devCbNext->list.next, struct RsUbDevCb, list)) {
211 0 : ret = RsHandleJfcEpollEvent(devCbCurr, fd);
212 0 : if (ret == -ENODEV) {
213 0 : continue;
214 : }
215 0 : return ret;
216 : }
217 :
218 0 : return -ENODEV;
219 : }
220 :
221 0 : STATIC int RsUbFillAsyncEventCb(urma_async_event_t *event, struct RsUbDevCb *devCb,
222 : struct RsCtxAsyncEventCb *asyncEventCb)
223 : {
224 0 : int ret = 0;
225 :
226 0 : switch (event->event_type) {
227 0 : case URMA_EVENT_JFC_ERR:
228 0 : asyncEventCb->resId = event->element.jfc->jfc_id.id;
229 0 : ret = RsUrmaGetJfcOpt(event->element.jfc, URMA_JFC_FULL_CTX, asyncEventCb->context, JFC_CONTEXT_LEN);
230 0 : CHK_PRT_RETURN(ret != 0,
231 : hccp_err("RsUrmaGetJfcOpt failed, ret:%d, jfcId:%u devIndex:0x%0x", ret, event->element.jfc->jfc_id.id,
232 : devCb->index),
233 : -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,
249 : hccp_err("RsUrmaGetJettyOpt failed, ret:%d, jettyId:%u devIndex:0x%0x", ret,
250 : event->element.jetty->jetty_id.id, devCb->index),
251 : -EOPENSRC);
252 0 : asyncEventCb->len = JETTY_CONTEXT_LEN;
253 0 : break;
254 0 : case URMA_EVENT_JETTY_GRP_ERR:
255 0 : asyncEventCb->resId = event->element.jetty_grp->jetty_grp_id.id;
256 0 : break;
257 0 : case URMA_EVENT_PORT_ACTIVE:
258 : case URMA_EVENT_PORT_DOWN:
259 0 : asyncEventCb->resId = event->element.port_id;
260 0 : break;
261 0 : case URMA_EVENT_EID_CHANGE:
262 0 : asyncEventCb->resId = event->element.eid_idx;
263 0 : break;
264 0 : case URMA_EVENT_DEV_FATAL:
265 : case URMA_EVENT_ELR_ERR:
266 : case URMA_EVENT_ELR_DONE:
267 0 : asyncEventCb->resId = devCb->index;
268 0 : break;
269 0 : default:
270 0 : hccp_warn("invalid event_type:%d devIndex:0x%x", event->event_type, devCb->index);
271 0 : break;
272 : }
273 0 : return ret;
274 : }
275 :
276 0 : STATIC int RsUbGetSaveAsyncEvent(struct RsUbDevCb *devCb)
277 : {
278 0 : struct RsCtxAsyncEventCb *asyncEventCb = NULL;
279 0 : urma_async_event_t *event = NULL;
280 0 : int ret = 0;
281 :
282 0 : asyncEventCb = calloc(1, sizeof(struct RsCtxAsyncEventCb));
283 0 : CHK_PRT_RETURN(asyncEventCb == NULL, hccp_err("calloc asyncEventCb failed"), -ENOMEM);
284 0 : asyncEventCb->devCb = devCb;
285 0 : event = &asyncEventCb->asyncEvent;
286 :
287 0 : ret = RsUrmaGetAsyncEvent(devCb->urmaCtx, event);
288 0 : if (ret != 0) {
289 0 : hccp_err("RsUrmaGetAsyncEvent failed, ret:%d errno:%d devIndex:0x%x", ret, errno, devCb->index);
290 0 : ret = -EOPENSRC;
291 0 : goto free_event_cb;
292 : }
293 0 : RsUrmaAckAsyncEvent(event);
294 :
295 0 : ret = RsUbFillAsyncEventCb(event, devCb, asyncEventCb);
296 0 : if (ret != 0) {
297 0 : hccp_err("RsUbFillAsyncEventCb failed, ret:%d devIndex:0x%x", ret, devCb->index);
298 0 : goto free_event_cb;
299 : }
300 :
301 0 : hccp_run_info("get async event, event_type:%d resId:%d devIndex:0x%x", asyncEventCb->asyncEvent.event_type,
302 : asyncEventCb->resId, asyncEventCb->devCb->index);
303 0 : RsListAddTail(&asyncEventCb->list, &devCb->asyncEventList);
304 0 : devCb->asyncEventCnt++;
305 :
306 0 : return ret;
307 :
308 0 : free_event_cb:
309 0 : free(asyncEventCb);
310 0 : asyncEventCb = NULL;
311 0 : return ret;
312 : }
313 :
314 0 : int RsEpollEventUrmaAsyncEventInHandle(struct rs_cb *rsCb, int fd)
315 : {
316 0 : struct RsUbDevCb *devCbCurr = NULL;
317 0 : struct RsUbDevCb *devCbNext = NULL;
318 0 : int ret = 0;
319 :
320 0 : if (rsCb->protocol != PROTOCOL_UDMA) {
321 0 : return -ENODEV;
322 : }
323 :
324 0 : RS_LIST_GET_HEAD_ENTRY(devCbCurr, devCbNext, &rsCb->udevList, list, struct RsUbDevCb);
325 0 : for (; (&devCbCurr->list) != &rsCb->udevList;
326 0 : devCbCurr = devCbNext, devCbNext = list_entry(devCbNext->list.next, struct RsUbDevCb, list)) {
327 0 : RS_PTHREAD_MUTEX_LOCK(&devCbCurr->mutex);
328 0 : if (devCbCurr->urmaCtx != NULL && devCbCurr->urmaCtx->async_fd == fd) {
329 0 : ret = RsUbGetSaveAsyncEvent(devCbCurr);
330 0 : if (ret != 0) {
331 0 : hccp_err("rs_ub_get_save_async_event failed, ret:%d devIndex:0x%x", ret, devCbCurr->index);
332 : }
333 0 : RS_PTHREAD_MUTEX_ULOCK(&devCbCurr->mutex);
334 0 : return ret;
335 : }
336 0 : RS_PTHREAD_MUTEX_ULOCK(&devCbCurr->mutex);
337 : }
338 :
339 0 : return -ENODEV;
340 : }
341 :
342 0 : STATIC int RsUbCtxFillAsyncEvent(struct RsCtxAsyncEventCb *eventCb, struct AsyncEvent *asyncEvent)
343 : {
344 0 : int ret = 0;
345 :
346 0 : asyncEvent->resId = eventCb->resId;
347 0 : asyncEvent->eventType = eventCb->asyncEvent.event_type;
348 0 : asyncEvent->len = eventCb->len;
349 :
350 0 : ret = memcpy_s(asyncEvent->context, CONTEXT_MAX_LEN, eventCb->context, eventCb->len);
351 0 : CHK_PRT_RETURN(ret != 0,
352 : hccp_err("memcpy_s failed, ret:%d asyncEvent len:%u eventCb len:%u", ret, CONTEXT_MAX_LEN, eventCb->len),
353 : -ESAFEFUNC);
354 :
355 0 : return ret;
356 : }
357 :
358 0 : void RsUbCtxGetAsyncEvents(struct RsUbDevCb *devCb, struct AsyncEvent asyncEvents[], unsigned int *num)
359 : {
360 0 : struct RsCtxAsyncEventCb *eventCbCurr = NULL;
361 0 : struct RsCtxAsyncEventCb *eventCbNext = NULL;
362 0 : unsigned int expectedNum = *num;
363 0 : int ret = 0;
364 :
365 0 : *num = 0;
366 0 : if (RsListEmpty(&devCb->asyncEventList)) {
367 0 : return;
368 : }
369 :
370 0 : RS_PTHREAD_MUTEX_LOCK(&devCb->mutex);
371 0 : RS_LIST_GET_HEAD_ENTRY(eventCbCurr, eventCbNext, &devCb->asyncEventList, list, struct RsCtxAsyncEventCb);
372 0 : for (; (&eventCbCurr->list) != &devCb->asyncEventList;
373 0 : eventCbCurr = eventCbNext, eventCbNext = list_entry(eventCbNext->list.next, struct RsCtxAsyncEventCb, list)) {
374 0 : ret = RsUbCtxFillAsyncEvent(eventCbCurr, &asyncEvents[*num]);
375 0 : if (ret != 0) {
376 0 : hccp_err("RsUbCtxFillAsyncEvent failed, ret:%d devIndex:0x%x", ret, devCb->index);
377 0 : RsUbFreeAsyncEventCb(devCb, eventCbCurr);
378 0 : break;
379 : }
380 0 : (*num)++;
381 0 : RsUbFreeAsyncEventCb(devCb, eventCbCurr);
382 0 : if (*num == expectedNum) {
383 0 : break;
384 : }
385 : }
386 0 : RS_PTHREAD_MUTEX_ULOCK(&devCb->mutex);
387 : }
388 :
389 0 : int RsUbGetJettyContext(struct RsUbDevCb *devCb, unsigned int id, uint8_t context[], unsigned int *len)
390 : {
391 0 : struct RsCtxJettyCb *jettyCb = NULL;
392 0 : int ret = 0;
393 :
394 0 : ret = RsUbGetJettyCb(devCb, id, &jettyCb);
395 0 : CHK_PRT_RETURN(ret != 0, hccp_err("get jettyCb failed, ret:%d, jettyId:%u", ret, id), ret);
396 :
397 0 : ret = RsUrmaGetJettyOpt(jettyCb->jetty, URMA_JETTY_FULL_CTX, (void *)context, JETTY_CONTEXT_LEN);
398 0 : CHK_PRT_RETURN(ret != 0, hccp_err("RsUrmaGetJettyOpt failed, ret:%d, jettyId:%u", ret, id), -EOPENSRC);
399 :
400 0 : *len = JETTY_CONTEXT_LEN;
401 0 : return ret;
402 : }
|