LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_service - rs_rdma.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 76.3 % 1998 1525
Test Date: 2026-08-17 10:19:35 Functions: 89.4 % 113 101

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 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              : #define _GNU_SOURCE
      12              : #include <unistd.h>
      13              : #include <stdlib.h>
      14              : #include <netinet/in.h>
      15              : #include <arpa/inet.h>
      16              : #include <dlfcn.h>
      17              : #include <sys/types.h>
      18              : #include <sys/stat.h>
      19              : #include <sys/epoll.h>
      20              : #include <sys/eventfd.h>
      21              : #include <sys/socket.h>
      22              : #include <errno.h>
      23              : #include "securec.h"
      24              : #include "rs.h"
      25              : #include "ra_rs_err.h"
      26              : #include "rs_common_inner.h"
      27              : #include "rs_inner.h"
      28              : #include "rs_rdma_inner.h"
      29              : #include "rs_epoll.h"
      30              : #include "dl_hal_function.h"
      31              : #include "dl_ibverbs_function.h"
      32              : #include "dl_ibv_extend_function.h"
      33              : #include "rs_drv_socket.h"
      34              : #include "rs_drv_rdma.h"
      35              : #include "rs_rdma.h"
      36              : 
      37              : unsigned int gRsSendWrNum = 0;
      38              : 
      39              : STATIC struct RsListHead gRsTypicalCqList;
      40              : STATIC pthread_mutex_t gRsTypicalCqMutex = PTHREAD_MUTEX_INITIALIZER;
      41              : 
      42            2 : STATIC void RsBufPrint(char *addr, int len)
      43              : {
      44              :     int i;
      45              : 
      46          130 :     for (i = 0; i < len; i++) {
      47          128 :         hccp_info("0x%02x ", *(addr + i));
      48              :     }
      49            2 : }
      50              : 
      51          137 : STATIC int RsGetQpcb(struct RsRdevCb *rdevCb, uint32_t qpn, struct RsQpCb **qpCb)
      52              : {
      53          137 :     struct RsQpCb *qpCbTmp = NULL;
      54          137 :     struct RsQpCb *qpCbTmp2 = NULL;
      55              : 
      56          137 :     RS_LIST_GET_HEAD_ENTRY(qpCbTmp, qpCbTmp2, &rdevCb->qpList, list, struct RsQpCb);
      57          180 :     for (; (&qpCbTmp->list) != &rdevCb->qpList;
      58           43 :          qpCbTmp = qpCbTmp2, qpCbTmp2 = list_entry(qpCbTmp2->list.next, struct RsQpCb, list)) {
      59          171 :         if (qpCbTmp->ibQp->qp_num == qpn) {
      60          128 :             *qpCb = qpCbTmp;
      61          128 :             return 0;
      62              :         }
      63              :     }
      64              : 
      65            9 :     *qpCb = NULL;
      66            9 :     hccp_err("qp_cb for qp %u do not available!", qpn);
      67              : 
      68            9 :     return -ENODEV;
      69              : }
      70              : 
      71          140 : int RsQpn2qpcb(unsigned int phyId, unsigned int rdevIndex, uint32_t qpn, struct RsQpCb **qpCb)
      72              : {
      73              :     int ret;
      74              :     unsigned int chipId;
      75          140 :     struct rs_cb *rsCb = NULL;
      76          140 :     struct RsRdevCb *rdevCb = NULL;
      77              : 
      78          140 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs set param error! phyId:%u", phyId), -EINVAL);
      79              : 
      80          137 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
      81          137 :     CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret:%d", phyId, ret), ret);
      82              : 
      83          137 :     ret = RsDev2rscb(chipId, &rsCb, false);
      84          137 :     CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb get rs_cb failed, ret:%d", ret), -ENODEV);
      85              : 
      86          137 :     ret = RsGetRdevCb(rsCb, rdevIndex, &rdevCb);
      87          137 :     CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed! ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
      88              : 
      89          137 :     ret = RsGetQpcb(rdevCb, qpn, qpCb);
      90          137 :     CHK_PRT_RETURN(ret, hccp_err("rs_get_qpcb failed! ret:%d, qpn:%u", ret, qpn), ret);
      91              : 
      92          128 :     return 0;
      93              : }
      94              : 
      95           44 : STATIC int RsGetMrcb(struct RsQpCb *qpCb, uint64_t addr, struct RsMrCb **mrCb, struct RsListHead *mrList)
      96              : {
      97           44 :     struct RsMrCb *mrTmp = NULL;
      98           44 :     struct RsMrCb *mrTmp2 = NULL;
      99              : 
     100           44 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
     101           44 :     RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, mrList, list, struct RsMrCb);
     102           86 :     for (; (&mrTmp->list) != mrList; mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
     103           66 :         if ((mrTmp->mrInfo.addr <= addr) && (addr < mrTmp->mrInfo.addr + mrTmp->mrInfo.len)) {
     104           24 :             *mrCb = mrTmp;
     105           24 :             RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
     106           24 :             return 0;
     107              :         }
     108              :     }
     109              : 
     110           20 :     *mrCb = NULL;
     111           20 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
     112              : 
     113           20 :     hccp_info("cannot find mrcb for addr@0x%lx !", addr);
     114              : 
     115           20 :     return -ENODEV;
     116              : }
     117              : 
     118           18 : STATIC void *RsNotifyMrListAdd(struct RsQpCb *qpCb, const char *buf)
     119              : {
     120              :     int ret;
     121              :     struct RsMrCb *notifyMrCb;
     122              : 
     123           18 :     notifyMrCb = calloc(1, sizeof(struct RsMrCb));
     124           18 :     CHK_PRT_RETURN(notifyMrCb == NULL, hccp_err("notify_mr_cb calloc failed"), NULL);
     125           16 :     ret = memcpy_s(&notifyMrCb->mrInfo, sizeof(struct RsMrInfo), &((const struct RsQpInfo *)buf)->notifyMr,
     126              :         sizeof(struct RsMrInfo));
     127           16 :     if (ret) {
     128            1 :         hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u", ret, sizeof(struct RsMrInfo),
     129              :             sizeof(struct RsMrInfo));
     130            1 :         free(notifyMrCb);
     131            1 :         notifyMrCb = NULL;
     132            1 :         return NULL;
     133              :     }
     134              : 
     135           15 :     hccp_info("qpn is %d, rdevIndex:%u, chipId %u, recv notify va is 0x%llx, notify size is %llu", qpCb->qpInfoLo.qpn,
     136              :         qpCb->rdevCb->rdevIndex, qpCb->rdevCb->rsCb->chipId, notifyMrCb->mrInfo.addr, notifyMrCb->mrInfo.len);
     137              : 
     138           15 :     RsListAddTail(&notifyMrCb->list, &qpCb->remMrList);
     139              : 
     140           15 :     return notifyMrCb;
     141              : }
     142              : 
     143           21 : STATIC int RsQpStateModify(struct RsQpCb *qpCb)
     144              : {
     145           21 :     struct ibv_qp_init_attr initAttr = {0};
     146           21 :     struct ibv_qp_attr attr = {0};
     147              :     enum ibv_qp_state state;
     148              :     int ret;
     149              : 
     150              :     // see ib_modify_qp_is_ok for status modify, only support modify qp from INIT to RTR
     151           21 :     ret = RsIbvQueryQp(qpCb->ibQp, &attr, IBV_QP_STATE, &initAttr);
     152           21 :     if (ret != 0) {
     153            1 :         hccp_warn("rs_ibv_query_qp qpn:%d unsuccessful, ret:%d", qpCb->qpInfoLo.qpn, ret);
     154            1 :         state = IBV_QPS_UNKNOWN;
     155              :     } else {
     156           20 :         state = attr.qp_state;
     157              :     }
     158              : 
     159              :     // disallow modify qp from IBV_QPS_RTS to IBV_QPS_RTS
     160           21 :     if (state == IBV_QPS_RTS) {
     161            1 :         hccp_err("qpn:%d disallow modify from %d", qpCb->qpInfoLo.qpn, state);
     162            1 :         return -EINVAL;
     163              :     }
     164              : 
     165           20 :     hccp_info("qpn:%d state:%d start modify", qpCb->qpInfoLo.qpn, state);
     166              : 
     167              :     // modify qp from others to RESET
     168           20 :     if (state != IBV_QPS_RESET && state != IBV_QPS_INIT && state != IBV_QPS_RTR) {
     169            1 :         ret = RsDrvQpStateModifytoReset(qpCb);
     170            1 :         CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to reset failed, ret:%d", qpCb->qpInfoLo.qpn, state, ret), ret);
     171            0 :         state = IBV_QPS_RESET;
     172              :     }
     173              : 
     174              :     // modify qp from RESET to INIT
     175           19 :     if (state == IBV_QPS_RESET) {
     176           19 :         ret = RsDrvQpStateModifytoInit(qpCb, &attr);
     177           19 :         CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to init failed, ret %d", qpCb->qpInfoLo.qpn, state, ret), ret);
     178           18 :         state = IBV_QPS_INIT;
     179              :     }
     180              : 
     181              :     // modify qp from INIT to RTR
     182           18 :     if (state == IBV_QPS_INIT) {
     183           18 :         ret = RsDrvQpStateModifytoRtr(qpCb, &attr);
     184           18 :         CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to rtr failed, ret %d", qpCb->qpInfoLo.qpn, state, ret), ret);
     185           16 :         state = IBV_QPS_RTR;
     186              :     }
     187              : 
     188              :     // modify qp from RTR to RTS
     189           16 :     if (state == IBV_QPS_RTR) {
     190           16 :         ret = RsDrvQpStateModifytoRts(qpCb, &attr);
     191           16 :         CHK_PRT_RETURN(ret, hccp_err("qpn:%d modify %d to rts failed, ret %d", qpCb->qpInfoLo.qpn, state, ret), ret);
     192              :     }
     193              : 
     194           16 :     hccp_info("local qpn[%d] remote qpn[%d] modify succ", qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn);
     195              : 
     196           16 :     return 0;
     197              : }
     198              : 
     199           17 : STATIC int RsEpollRecvQpHandle(struct RsQpCb *qpCb, const char *bufTmp)
     200              : {
     201              :     int ret;
     202           17 :     float timeCost = 0.0;
     203              : 
     204           17 :     ret = memcpy_s(&qpCb->qpInfoRem, sizeof(struct RsQpInfo), bufTmp, sizeof(struct RsQpInfo));
     205           17 :     CHK_PRT_RETURN(ret,
     206              :         hccp_err("memcpy_s failed[%d], dest size:%d, src size:%d", ret, sizeof(struct RsQpInfo),
     207              :             sizeof(struct RsQpInfo)),
     208              :         -ENOMEM);
     209              : 
     210              :     /* modify qp state to RTR/RTS */
     211           17 :     ret = RsQpStateModify(qpCb);
     212           17 :     CHK_PRT_RETURN(ret,
     213              :         hccp_err("rs_qp_state_modify local qpn[%d] remote qpn[%d] failed ret[%d]", qpCb->qpInfoLo.qpn,
     214              :             qpCb->qpInfoRem.qpn, ret),
     215              :         ret);
     216              : 
     217           16 :     RsGetCurTime(&qpCb->endTime);
     218           16 :     HccpTimeInterval(&qpCb->endTime, &qpCb->startTime, &timeCost);
     219           16 :     if (timeCost > RS_EXPECT_TIME_MAX) {
     220            2 :         hccp_warn("local qpn[%d] remote qpn [%d] connect success cost[%f] more than[%f]ms!", qpCb->qpInfoLo.qpn,
     221              :             qpCb->qpInfoRem.qpn, timeCost, RS_EXPECT_TIME_MAX);
     222              :     } else {
     223           14 :         hccp_info("local qpn[%d] remote qpn [%d] connect success! cost [%f] ms", qpCb->qpInfoLo.qpn,
     224              :             qpCb->qpInfoRem.qpn, timeCost);
     225              :     }
     226              : 
     227           16 :     hccp_info("qp [%d] state has been migrate to RTS!, qpCb state is %d", qpCb->qpInfoLo.qpn, qpCb->state);
     228              : 
     229           16 :     return 0;
     230              : }
     231              : 
     232           14 : STATIC void *RsEpollRecvMrHandle(struct RsQpCb *qpCb, const char *bufTmp)
     233              : {
     234              :     int ret;
     235              :     struct RsMrCb *mrCb;
     236              : 
     237           14 :     mrCb = calloc(1, sizeof(struct RsMrCb));
     238           14 :     CHK_PRT_RETURN(mrCb == NULL, hccp_err("mr_cb calloc failed"), NULL);
     239           13 :     ret = memcpy_s(&mrCb->mrInfo, sizeof(struct RsMrInfo), bufTmp, sizeof(struct RsMrInfo));
     240           13 :     if (ret) {
     241            0 :         hccp_err("memcpy_s failed[%d], dest size:%u, src size:%u", ret, sizeof(struct RsMrInfo),
     242              :             sizeof(struct RsMrInfo));
     243            0 :         free(mrCb);
     244            0 :         mrCb = NULL;
     245            0 :         return NULL;
     246              :     }
     247              : 
     248           13 :     RsListAddTail(&mrCb->list, &qpCb->remMrList);
     249              : 
     250           13 :     hccp_info("recv mr addr is 0x%llx", mrCb->mrInfo.addr);
     251           13 :     hccp_info("recv mr len is %llu", mrCb->mrInfo.len);
     252              : 
     253           13 :     return mrCb;
     254              : }
     255              : 
     256           17 : STATIC int RsCmdQpInfoHandle(struct RsQpCb *qpCb, unsigned int totalSize, const char *bufTmp, unsigned int curSize,
     257              :     bool *flag)
     258              : {
     259              :     int ret;
     260           17 :     CHK_PRT_RETURN((totalSize - curSize) < sizeof(struct RsQpInfo),
     261              :         hccp_info("qp_info remain size"
     262              :                   "[%u] < size [%u], wait for next recv",
     263              :             totalSize - curSize, sizeof(struct RsQpInfo)),
     264              :         -EINVAL);
     265              : 
     266           17 :     ret = RsEpollRecvQpHandle(qpCb, bufTmp);
     267           17 :     CHK_PRT_RETURN(ret, hccp_err("rs_epoll_recv_qp_handle failed! ret[%d]", ret), ret);
     268              : 
     269           16 :     RsNotifyMrListAdd(qpCb, bufTmp);
     270           16 :     hccp_info("rs_notify_mr_list_add");
     271              : 
     272           16 :     *flag = true;
     273           16 :     hccp_info("qp_info cur_size(%u) len(%u) !", curSize, sizeof(struct RsQpInfo));
     274              : 
     275           16 :     return 0;
     276              : }
     277              : 
     278           14 : STATIC int RsCmdMrInfoHandle(struct RsQpCb *qpCb, unsigned int totalSize, const char *bufTmp, unsigned int curSize,
     279              :     bool *flag)
     280              : {
     281           14 :     CHK_PRT_RETURN((totalSize - curSize) < sizeof(struct RsMrInfo),
     282              :         hccp_info("mr_info remain size"
     283              :                   "[%u] < size [%u], wait for next recv",
     284              :             totalSize - curSize, sizeof(struct RsMrInfo)),
     285              :         -EINVAL);
     286              : 
     287           14 :     (void)RsEpollRecvMrHandle(qpCb, bufTmp);
     288              : 
     289           14 :     *flag = true;
     290              : 
     291           14 :     hccp_info("mr_info cur_size(%u) len(%u) !", curSize, sizeof(struct RsMrInfo));
     292              : 
     293           14 :     return 0;
     294              : }
     295              : 
     296           14 : STATIC int RsCmdLenInfoHandle(struct RsQpCb *qpCb, unsigned int totalSize, const char *bufTmp, unsigned int curSize,
     297              :     bool *flag)
     298              : {
     299           14 :     CHK_PRT_RETURN((totalSize - curSize) < sizeof(struct RsQpLenInfo),
     300              :         hccp_info("len_info remain size"
     301              :                   "[%u] < size [%u], wait for next recv",
     302              :             totalSize - curSize, sizeof(struct RsQpLenInfo)),
     303              :         -EINVAL);
     304              : 
     305           14 :     qpCb->expectLen = *((const uint32_t *)(bufTmp + sizeof(uint32_t)));
     306              : 
     307           14 :     *flag = true;
     308              : 
     309           14 :     return 0;
     310              : }
     311              : 
     312           15 : STATIC void RsEpollRecvHandleRemain(struct RsQpCb *qpCb, unsigned int totalSize, unsigned int curSize, bool flag,
     313              :     const char *bufTmp)
     314              : {
     315           15 :     int ret = 0;
     316              : 
     317           15 :     qpCb->remainSize = totalSize - curSize;
     318           15 :     if ((qpCb->remainSize > 0) && (flag == true)) {
     319            1 :         ret = memcpy_s(qpCb->qpMrBuf, RS_BUF_SIZE, bufTmp, qpCb->remainSize);
     320            1 :         if (ret) {
     321            1 :             hccp_err("memcpy_s failed, ret:%d, remainSize:%u", ret, qpCb->remainSize);
     322            1 :             return;
     323              :         }
     324              :     }
     325              : 
     326           14 :     return;
     327              : }
     328              : 
     329           18 : STATIC void RsEpollRecvHandle(struct RsQpCb *qpCb, char *buf, int size)
     330              : {
     331           18 :     unsigned int totalSize = qpCb->remainSize + (unsigned int)size;
     332           18 :     char *bufTmp = (char *)qpCb->qpMrBuf;
     333           18 :     unsigned int curSize = 0;
     334           18 :     bool flag = false;
     335              :     uint32_t cmd;
     336              :     int ret;
     337              : 
     338           18 :     hccp_info("Message for qp:%d, qpCb->remainSize:%u, size:%d", qpCb->qpInfoLo.qpn, qpCb->remainSize, size);
     339           18 :     ret = memcpy_s(qpCb->qpMrBuf + qpCb->remainSize, RS_BUF_SIZE - qpCb->remainSize, buf, size);
     340           18 :     if (ret) {
     341            2 :         hccp_err("memcpy_s failed, ret:%d, remainSize:%u, size:%d", ret, qpCb->remainSize, size);
     342            4 :         return;
     343              :     }
     344              : 
     345              :     do {
     346           47 :         cmd = *((uint32_t *)bufTmp);
     347           47 :         switch (cmd) {
     348           17 :             case RS_CMD_QP_INFO:
     349           17 :                 ret = RsCmdQpInfoHandle(qpCb, totalSize, bufTmp, curSize, &flag);
     350           17 :                 if (ret) {
     351            1 :                     goto out;
     352              :                 }
     353              : 
     354           16 :                 curSize += sizeof(struct RsQpInfo);
     355           16 :                 bufTmp = qpCb->qpMrBuf + curSize;
     356           16 :                 break;
     357           14 :             case RS_CMD_MR_INFO:
     358           14 :                 ret = RsCmdMrInfoHandle(qpCb, totalSize, bufTmp, curSize, &flag);
     359           14 :                 if (ret) {
     360            0 :                     goto out;
     361              :                 }
     362              : 
     363           14 :                 curSize += sizeof(struct RsMrInfo);
     364           14 :                 bufTmp = qpCb->qpMrBuf + curSize;
     365           14 :                 break;
     366           14 :             case RS_CMD_LEN_INFO:
     367           14 :                 ret = RsCmdLenInfoHandle(qpCb, totalSize, bufTmp, curSize, &flag);
     368           14 :                 if (ret) {
     369            0 :                     goto out;
     370              :                 }
     371           14 :                 curSize += sizeof(struct RsQpLenInfo);
     372           14 :                 bufTmp = qpCb->qpMrBuf + curSize;
     373           14 :                 break;
     374            2 :             default:
     375            2 :                 hccp_warn("qp %d, unknown cmd(0x%x)!", qpCb->qpInfoLo.qpn, cmd);
     376            2 :                 RsBufPrint(buf, size);
     377            2 :                 return;
     378              :         }
     379           44 :     } while (curSize < totalSize);
     380              : 
     381           13 : out:
     382           14 :     RsEpollRecvHandleRemain(qpCb, totalSize, curSize, flag, bufTmp);
     383              : }
     384              : 
     385           27 : STATIC void RsQpMrRecvHandle(int fd, struct RsQpCb *qpCb)
     386              : {
     387              :     char buf[RS_BUF_SIZE];
     388              :     int size;
     389              :     int ret;
     390              : 
     391           27 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
     392              : 
     393           27 :     size = RsSocketRecv(fd, buf, RS_BUF_SIZE - qpCb->remainSize);
     394           27 :     hccp_dbg("fd %d qpn %d read size = %d, qpCb->remainSize:%u", fd, qpCb->qpInfoLo.qpn, size, qpCb->remainSize);
     395              : 
     396           27 :     if (size > 0) {
     397           13 :         qpCb->recvLen += (uint32_t)size;
     398           13 :         RsEpollRecvHandle(qpCb, buf, size);
     399           14 :     } else if (size == 0) {
     400            0 :         hccp_dbg("fd %d read size = %d, remote fd has been closed, fd cannot use !", fd, size);
     401              : #ifdef CA_CONFIG_LLT
     402            0 :         qpCb->state = RS_QP_STATUS_REM_FD_CLOSE;
     403              : #endif
     404              :     } else {
     405           14 :         ret = errno;
     406           14 :         hccp_dbg("no data available, errno:%d", ret);
     407              :     }
     408           27 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
     409              : 
     410           27 :     return;
     411              : }
     412              : 
     413            0 : STATIC int RsHandleQpMrEpollEvent(struct RsRdevCb *rdevCb, int fd)
     414              : {
     415              :     struct RsQpCb *qpCb;
     416            0 :     struct RsQpCb *qpCb2 = NULL;
     417              : 
     418              :     /* QP event, QP info exchange */
     419            0 :     RS_LIST_GET_HEAD_ENTRY(qpCb, qpCb2, &rdevCb->qpList, list, struct RsQpCb);
     420            0 :     for (; (&qpCb->list) != &rdevCb->qpList; qpCb = qpCb2, qpCb2 = list_entry(qpCb2->list.next, struct RsQpCb, list)) {
     421            0 :         if (qpCb->channel == NULL) {
     422            0 :             continue;
     423              :         }
     424            0 :         if (qpCb->srqContext != NULL && qpCb->srqContext->channel->fd == fd) {
     425            0 :             hccp_dbg("fd %d poll cq!", fd);
     426            0 :             RsDrvPollSrqCqHandle(qpCb);
     427            0 :             return 0;
     428              :         }
     429            0 :         if (fd == qpCb->channel->fd) {
     430            0 :             hccp_dbg("fd %d poll cq!", fd);
     431            0 :             RsDrvPollCqHandle(qpCb);
     432            0 :             return 0;
     433              :         }
     434              :     }
     435            0 :     return -ENODEV;
     436              : }
     437              : 
     438            0 : int RsEpollEventQpMrInHandle(struct rs_cb *rsCb, int fd)
     439              : {
     440              :     int ret;
     441            0 :     struct RsRdevCb *rdevCbTmp = NULL;
     442            0 :     struct RsRdevCb *rdevCbTmp2 = NULL;
     443              : 
     444            0 :     if (rsCb->protocol != PROTOCOL_RDMA) {
     445            0 :         return -ENODEV;
     446              :     }
     447              : 
     448            0 :     RS_LIST_GET_HEAD_ENTRY(rdevCbTmp, rdevCbTmp2, &rsCb->rdevList, list, struct RsRdevCb);
     449            0 :     for (; (&rdevCbTmp->list) != &rsCb->rdevList;
     450            0 :          rdevCbTmp = rdevCbTmp2, rdevCbTmp2 = list_entry(rdevCbTmp2->list.next, struct RsRdevCb, list)) {
     451            0 :         RS_PTHREAD_MUTEX_LOCK(&rdevCbTmp->rdevMutex);
     452            0 :         ret = RsHandleQpMrEpollEvent(rdevCbTmp, fd);
     453            0 :         RS_PTHREAD_MUTEX_ULOCK(&rdevCbTmp->rdevMutex);
     454            0 :         if (ret == 0) {
     455            0 :             return 0;
     456              :         }
     457              :     }
     458            0 :     return -ENODEV;
     459              : }
     460              : 
     461           28 : STATIC int RsMrInfoSync(struct RsMrCb *mrCb)
     462              : {
     463              :     int ret;
     464              : 
     465           28 :     hccp_info("mr state:%d, addr:0x%lx", mrCb->state, mrCb->mrInfo.addr);
     466              : 
     467           28 :     CHK_PRT_RETURN(mrCb->state & RS_MR_STATE_SYNCED,
     468              :         hccp_warn("mr synced ! mr_cb->flag[%d] & [%d] != 0", mrCb->state, RS_MR_STATE_SYNCED), 0);
     469              : 
     470              :     /*
     471              :      * no socket available for MR_INFO exchange if allowed
     472              :      * need exchange when socket available
     473              :      */
     474           27 :     CHK_PRT_RETURN(mrCb->qpCb->connInfo == NULL, hccp_warn("no conn available !"), 0);
     475              : 
     476           27 :     CHK_PRT_RETURN(mrCb->qpCb->state == RS_QP_STATUS_REM_FD_CLOSE,
     477              :         hccp_warn("remote qp fd closed,"
     478              :                   "cann not use it anymore! status[%d](RS_QP_STATUS_REM_FD_CLOSE)",
     479              :             mrCb->qpCb->state),
     480              :         -EFAULT);
     481              : 
     482           27 :     CHK_PRT_RETURN(mrCb->qpCb->connInfo->connfd == RS_FD_INVALID,
     483              :         hccp_warn("rm info sync failed! fd not ready!"
     484              :                   "connfd[%d](RS_FD_INVALID)",
     485              :             mrCb->qpCb->connInfo->connfd),
     486              :         -ENETUNREACH);
     487              : 
     488           26 :     mrCb->mrInfo.cmd = (unsigned int)RS_CMD_MR_INFO;
     489           26 :     ret = RsSocketSend(mrCb->qpCb->connInfo->connfd, &mrCb->mrInfo, sizeof(struct RsMrInfo));
     490           26 :     CHK_PRT_RETURN(ret != sizeof(struct RsMrInfo),
     491              :         hccp_err("mr_info send %d/%ld incomplete", ret, sizeof(struct RsMrInfo)), -EAGAIN);
     492              : 
     493           25 :     mrCb->qpCb->sendLen += (uint32_t)ret;
     494           25 :     mrCb->state |= RS_MR_STATE_SYNCED;
     495           25 :     hccp_info("after send mr state:%d, addr:0x%lx", mrCb->state, mrCb->mrInfo.addr);
     496              : 
     497           25 :     return 0;
     498              : }
     499              : 
     500            5 : STATIC int RsMrPrepareRoceSign(unsigned int phyId, struct RsRdevCb *devCb, struct roce_process_sign *roceSign)
     501              : {
     502            5 :     unsigned int tmpPhyId = phyId;
     503              :     unsigned int chipId;
     504              :     int ret;
     505              : 
     506              :     // reg mr with backup phyId
     507            5 :     if (devCb->backupInfo.backupFlag) {
     508            0 :         tmpPhyId = devCb->backupInfo.rdevInfo.phyId;
     509            0 :         ret = DlDrvGetLocalDevIdByHostDevId(tmpPhyId, &chipId);
     510              :     } else {
     511            5 :         ret = rsGetLocalDevIDByHostDevID(tmpPhyId, &chipId);
     512              :     }
     513            5 :     CHK_PRT_RETURN(ret != 0,
     514              :         hccp_err("get chipId failed, ret %d, phyid[%u] backupFlag[%d]", ret, tmpPhyId, devCb->backupInfo.backupFlag),
     515              :         -EACCES);
     516            5 :     roceSign->tgid = devCb->rsCb->pRsSign.tgid;
     517            5 :     roceSign->devid = chipId;
     518            5 :     roceSign->vfid = 0;
     519            5 :     ret = strcpy_s(roceSign->sign, PROCESS_RS_SIGN_LENGTH, devCb->rsCb->pRsSign.sign);
     520            5 :     CHK_PRT_RETURN(ret != 0, hccp_err("Invalid pid sign, ret(%d)", ret), -ESAFEFUNC);
     521            5 :     return 0;
     522              : }
     523              : 
     524            8 : STATIC int RsMrPreReg(unsigned int phyId, struct RsQpCb *qpCb, struct RsMrCb *mrCb, struct RdmaMrRegInfo *mrRegInfo)
     525              : {
     526            8 :     unsigned long long len = mrRegInfo->len;
     527            8 :     struct roce_process_sign roceSign = {0};
     528            8 :     int access = mrRegInfo->access;
     529            8 :     char *addr = mrRegInfo->addr;
     530              :     int ret;
     531              : 
     532            8 :     if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE || qpCb->rdevCb->rsCb->hccpMode == NETWORK_ONLINE ||
     533            7 :         qpCb->isExp == RS_NOT_EXP) {
     534            3 :         mrCb->ibMr = RsDrvMrReg(qpCb->ibPd, addr, len, access);
     535            3 :         CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_mr_reg addr is NULL len[%lld] failed ", len), -EACCES);
     536              :     } else {
     537            5 :         ret = RsMrPrepareRoceSign(phyId, qpCb->rdevCb, &roceSign);
     538            5 :         CHK_PRT_RETURN(ret != 0, hccp_err("RsMrPrepareRoceSign failed, ret(%d)", ret), ret);
     539            5 :         mrCb->ibMr = RsDrvExpMrReg(qpCb->ibPd, addr, len, access, roceSign);
     540            5 :         CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_exp_mr_reg addr is NULL len[%lld] failed ", len), -EACCES);
     541              :     }
     542              : 
     543            8 :     mrCb->mrInfo.cmd = (unsigned int)RS_CMD_MR_INFO;
     544            8 :     mrCb->mrInfo.addr = (uintptr_t)addr;
     545            8 :     mrCb->mrInfo.len = len;
     546            8 :     mrCb->mrInfo.rkey = mrCb->ibMr->rkey;
     547              : 
     548            8 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
     549            8 :     RsListAddTail(&mrCb->list, &qpCb->mrList);
     550            8 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
     551              : 
     552            8 :     qpCb->mrNum++;
     553            8 :     return 0;
     554              : }
     555              : 
     556           41 : STATIC int RsCallocMr(int num, struct RsMrCb **mrCb)
     557              : {
     558           41 :     CHK_PRT_RETURN(num <= 0, hccp_err("invalid num for mr calloc"), -EINVAL);
     559              : 
     560           40 :     *mrCb = calloc(num, sizeof(struct RsMrCb));
     561           40 :     CHK_PRT_RETURN((*mrCb) == NULL, hccp_err("calloc mr_cb failed"), -ENOMEM);
     562           40 :     return 0;
     563              : }
     564              : 
     565           54 : STATIC int RsCallocQpcb(int num, struct RsQpCb **qpCb)
     566              : {
     567           54 :     if (num <= 0) {
     568            1 :         return -EINVAL;
     569              :     }
     570              : 
     571           53 :     *qpCb = calloc(num, sizeof(struct RsQpCb));
     572           53 :     if ((*qpCb) == NULL) {
     573            1 :         return -ENOMEM;
     574              :     }
     575              : 
     576           52 :     return 0;
     577              : }
     578              : 
     579           10 : RS_ATTRI_VISI_DEF int RsMrReg(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
     580              :     struct RdmaMrRegInfo *mrRegInfo)
     581              : {
     582              :     int ret;
     583           10 :     struct RsQpCb *qpCb = NULL;
     584           10 :     struct RsMrCb *mrCb = NULL;
     585              : 
     586           10 :     CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 || phyId >= RS_MAX_DEV_NUM,
     587              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
     588              : 
     589            9 :     hccp_info("qpn[%u], len[0x%llx], access[%d]", qpn, mrRegInfo->len, mrRegInfo->access);
     590              : 
     591            9 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
     592            9 :     CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb qpn[%d] ret[%d] failed ", qpn, ret), ret);
     593              : 
     594            8 :     CHK_PRT_RETURN(qpCb->mrNum >= RS_MR_NUM_MAX, hccp_err("Exceeded the maximum MR limit %d", qpCb->mrNum), -EINVAL);
     595              : 
     596            8 :     ret = RsGetMrcb(qpCb, (uintptr_t)mrRegInfo->addr, &mrCb, &qpCb->mrList);
     597            8 :     if (ret == 0) {
     598            0 :         hccp_warn("mr already registered");
     599            0 :         goto found;
     600              :     }
     601              : 
     602            8 :     ret = RsCallocMr(1, &mrCb);
     603            8 :     CHK_PRT_RETURN(ret, hccp_err("calloc mr failed"), ret);
     604              : 
     605            8 :     mrCb->qpCb = qpCb;
     606              : 
     607            8 :     ret = RsMrPreReg(phyId, qpCb, mrCb, mrRegInfo);
     608            8 :     if (ret) {
     609            0 :         hccp_err("pre reg mr failed, qpn %u, ret %d", qpn, ret);
     610            0 :         goto reg_err;
     611              :     }
     612              : 
     613            8 : found:
     614            8 :     mrRegInfo->lkey = mrCb->ibMr->lkey;
     615            8 :     mrRegInfo->rkey = mrCb->ibMr->rkey;
     616              : 
     617            8 :     hccp_info("rs_mr_reg succ, state:%u", mrCb->state);
     618            8 :     return 0;
     619              : 
     620            0 : reg_err:
     621            0 :     free(mrCb);
     622            0 :     mrCb = NULL;
     623              : 
     624            0 :     return ret;
     625              : }
     626              : 
     627           10 : RS_ATTRI_VISI_DEF int RsMrDereg(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, char *addr)
     628              : {
     629              :     int ret;
     630           10 :     struct RsQpCb *qpCb = NULL;
     631           10 :     struct RsMrCb *mrCb = NULL;
     632              : 
     633           10 :     hccp_dbg("start rs_mr_dereg");
     634           10 :     RS_CHECK_POINTER_NULL_RETURN_INT(addr);
     635            9 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
     636              : 
     637            9 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
     638            9 :     CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb failed ret[%d]", ret), ret);
     639              : 
     640            7 :     CHK_PRT_RETURN(RsGetMrcb(qpCb, (uintptr_t)addr, &mrCb, &qpCb->mrList),
     641              :         hccp_err("rs_get_mrcb failed "
     642              :                  "g_rs_send_wr_num[%u]",
     643              :             gRsSendWrNum),
     644              :         -EFAULT);
     645              : 
     646            6 :     ret = RsDrvMrDereg(mrCb->ibMr);
     647            6 :     CHK_PRT_RETURN(ret, hccp_err("rs_drv_mr_dereg failed ret[%d] ", ret), -EACCES);
     648              : 
     649            6 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
     650            6 :     RsListDel(&mrCb->list);
     651            6 :     free(mrCb);
     652            6 :     mrCb = NULL;
     653            6 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
     654            6 :     qpCb->mrNum--;
     655              : 
     656            6 :     hccp_dbg("qpn[%u] succ", qpn);
     657              : 
     658            6 :     return 0;
     659              : }
     660              : 
     661            2 : STATIC int RsRegisterUbSegment(int directFlag, uint64_t addr, uint64_t len)
     662              : {
     663            2 :     struct DVattribute attr = {0};
     664            2 :     int ret = 0;
     665              : 
     666            2 :     if (directFlag != DIRECT_FLAG_UB) {
     667            2 :         return 0;
     668              :     }
     669              : 
     670            0 :     ret = DlDrvMemGetAttribute(addr, &attr);
     671            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("DlDrvMemGetAttribute failed, ret:%d", ret), ret);
     672              : 
     673            0 :     if (attr.memType != DV_MEM_LOCK_DEV) { // not support host memory
     674            0 :         return ret;
     675              :     }
     676              : 
     677            0 :     ret = DlHalMemRegUbSegment(attr.devId, addr, len);
     678            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("DlHalMemRegUbSegment failed, ret:%d devId:%u len:%u", ret, attr.devId, len),
     679              :         ret);
     680              : 
     681            0 :     return ret;
     682              : }
     683              : 
     684            2 : STATIC int RsUnRegisterUbSegment(int directFlag, uint64_t addr)
     685              : {
     686            2 :     struct DVattribute attr = {0};
     687            2 :     int ret = 0;
     688              : 
     689            2 :     if (directFlag != DIRECT_FLAG_UB) {
     690            2 :         return 0;
     691              :     }
     692              : 
     693            0 :     ret = DlDrvMemGetAttribute(addr, &attr);
     694            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("DrvMemGetAttribute failed, ret:%d", ret), ret);
     695              : 
     696            0 :     if (attr.memType != DV_MEM_LOCK_DEV) { // not support host memory
     697            0 :         return ret;
     698              :     }
     699              : 
     700            0 :     ret = DlHalMemUnRegUbSegment(attr.devId, addr);
     701            0 :     if (ret != 0) {
     702            0 :         hccp_err("DlHalMemUnRegUbSegment failed, ret:%d devId:%u", ret, attr.devId);
     703              :     }
     704              : 
     705            0 :     return ret;
     706              : }
     707              : 
     708            3 : RS_ATTRI_VISI_DEF int RsRegisterMr(unsigned int phyId, unsigned int rdevIndex, struct RdmaMrRegInfo *mrRegInfo,
     709              :     void **mrHandle)
     710              : {
     711            3 :     RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
     712              : 
     713              :     int ret;
     714              :     unsigned int chipId;
     715            3 :     struct RsRdevCb *rdevCb = NULL;
     716            3 :     struct ibv_mr *rsMrHandle = NULL;
     717              : 
     718            3 :     CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 || phyId >= RS_MAX_DEV_NUM,
     719              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
     720              : 
     721            2 :     hccp_info("[rs_register_mr] len[0x%llx], access[%d]", mrRegInfo->len, mrRegInfo->access);
     722              : 
     723            2 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
     724            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_register_mr rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d", phyId, ret),
     725              :         ret);
     726              : 
     727            2 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
     728            2 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
     729              :         ret);
     730              : 
     731            2 :     ret = RsRegisterUbSegment(rdevCb->directFlag, (uint64_t)(uintptr_t)mrRegInfo->addr, mrRegInfo->len);
     732            2 :     if (ret != 0) {
     733            0 :         hccp_err("RsRegisterUbSegment failed, ret[%d] vendor_id[0x%x] part_id[0x%x] directFlag[%u] "
     734              :                  "addr[0x%llx] len[0x%llx]",
     735              :             ret, rdevCb->deviceAttr.vendor_id, rdevCb->deviceAttr.vendor_part_id, rdevCb->directFlag,
     736              :             (uint64_t)(uintptr_t)mrRegInfo->addr, mrRegInfo->len);
     737            0 :         goto mem_reg_err;
     738              :     }
     739              : 
     740            2 :     *mrHandle = (void *)RsDrvMrReg(rdevCb->ibPd, mrRegInfo->addr, mrRegInfo->len, mrRegInfo->access);
     741            2 :     if (*mrHandle == NULL) {
     742            1 :         hccp_warn("rs_drv_mr_reg addr is NULL len[0x%llx] access[%d] unsuccessful errno[%d]", mrRegInfo->len,
     743              :             mrRegInfo->access, errno);
     744            1 :         goto mr_reg_err;
     745              :     }
     746              : 
     747            1 :     rsMrHandle = (struct ibv_mr *)*mrHandle;
     748            1 :     mrRegInfo->lkey = rsMrHandle->lkey;
     749            1 :     mrRegInfo->rkey = rsMrHandle->rkey;
     750              : 
     751            1 :     hccp_info("rs_register_mr succ");
     752            1 :     return ret;
     753            1 : mr_reg_err:
     754            1 :     (void)RsUnRegisterUbSegment(rdevCb->directFlag, (uint64_t)(uintptr_t)mrRegInfo->addr);
     755            1 : mem_reg_err:
     756            1 :     mrRegInfo->lkey = 0;
     757              : 
     758            1 :     return ret;
     759              : }
     760              : 
     761            2 : STATIC int RsInitTypicalMrCb(unsigned int phyId, struct RdmaMrRegInfo *mrRegInfo, struct RsRdevCb *devCb,
     762              :     struct RsMrCb *mrCb)
     763              : {
     764            2 :     unsigned long long len = mrRegInfo->len;
     765            2 :     struct roce_process_sign roceSign = {0};
     766            2 :     char *addr = (char *)mrRegInfo->addr;
     767            2 :     int access = mrRegInfo->access;
     768              :     int ret;
     769              : 
     770            2 :     if (devCb->rsCb->hccpMode == NETWORK_PEER_ONLINE || devCb->rsCb->hccpMode == NETWORK_ONLINE) {
     771            2 :         mrCb->ibMr = RsDrvMrReg(devCb->ibPd, addr, len, access);
     772            2 :         CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_mr_reg addr is NULL len[%lld] failed", len), -EACCES);
     773              :     } else {
     774            0 :         ret = RsMrPrepareRoceSign(phyId, devCb, &roceSign);
     775            0 :         CHK_PRT_RETURN(ret != 0, hccp_err("RsMrPrepareRoceSign failed, ret(%d)", ret), ret);
     776            0 :         mrCb->ibMr = RsDrvExpMrReg(devCb->ibPd, addr, len, access, roceSign);
     777            0 :         CHK_PRT_RETURN(mrCb->ibMr == NULL, hccp_err("rs_drv_exp_mr_reg addr is NULL len[%lld] failed", len), -EACCES);
     778              :     }
     779              : 
     780            2 :     mrCb->mrInfo.addr = (uintptr_t)addr;
     781            2 :     mrCb->mrInfo.len = len;
     782            2 :     mrCb->mrInfo.rkey = mrCb->ibMr->rkey;
     783              : 
     784            2 :     RS_PTHREAD_MUTEX_LOCK(&devCb->rdevMutex);
     785            2 :     RsListAddTail(&mrCb->list, &devCb->typicalMrList);
     786            2 :     RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
     787              : 
     788            2 :     return 0;
     789              : }
     790              : 
     791            1 : RS_ATTRI_VISI_DEF int RsTypicalRegisterMrV1(unsigned int phyId, unsigned int rdevIndex, struct RdmaMrRegInfo *mrRegInfo,
     792              :     void **mrHandle)
     793              : {
     794            1 :     RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
     795              : 
     796            1 :     struct RsMrCb *typicalMrCb = NULL;
     797            1 :     struct RsRdevCb *rdevCb = NULL;
     798              :     unsigned int chipId;
     799              :     int ret;
     800              : 
     801            1 :     CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 || phyId >= RS_MAX_DEV_NUM,
     802              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
     803              : 
     804            1 :     hccp_info("[rs_typical_register_mr] len[0x%llx], access[%d]", mrRegInfo->len, mrRegInfo->access);
     805              : 
     806            1 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
     807            1 :     CHK_PRT_RETURN(ret != 0,
     808              :         hccp_err("rs_typical_register_mr rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d", phyId, ret), ret);
     809              : 
     810            1 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
     811            1 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
     812              :         ret);
     813              : 
     814            1 :     ret = RsQueryMrCb(rdevCb, (uint64_t)(uintptr_t)mrRegInfo->addr, &typicalMrCb, &rdevCb->typicalMrList);
     815            1 :     if (ret == 0) {
     816            0 :         hccp_warn("typical mr already registered");
     817            0 :         goto found;
     818              :     }
     819              : 
     820            1 :     typicalMrCb = calloc(1, sizeof(struct RsMrCb));
     821            1 :     CHK_PRT_RETURN(typicalMrCb == NULL, hccp_err("calloc typical_mr_cb failed"), -ENOMEM);
     822            1 :     typicalMrCb->devCb = rdevCb;
     823              : 
     824            1 :     ret = RsInitTypicalMrCb(phyId, mrRegInfo, rdevCb, typicalMrCb);
     825            1 :     if (ret != 0) {
     826            0 :         hccp_err("rs_init_typical_mr_cb failed, devIndex[%u], ret[%d]", rdevIndex, ret);
     827            0 :         goto reg_err;
     828              :     }
     829              : 
     830            1 : found:
     831            1 :     *mrHandle = typicalMrCb->ibMr;
     832            1 :     mrRegInfo->lkey = typicalMrCb->ibMr->lkey;
     833            1 :     mrRegInfo->rkey = typicalMrCb->ibMr->rkey;
     834            1 :     hccp_info("rs_typical_register_mr succ, state:%d", typicalMrCb->state);
     835            1 :     return 0;
     836              : 
     837            0 : reg_err:
     838            0 :     free(typicalMrCb);
     839            0 :     typicalMrCb = NULL;
     840            0 :     return ret;
     841              : }
     842              : 
     843            1 : RS_ATTRI_VISI_DEF int RsTypicalRegisterMr(unsigned int phyId, unsigned int rdevIndex, struct RdmaMrRegInfo *mrRegInfo,
     844              :     void **mrHandle)
     845              : {
     846            1 :     RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
     847              : 
     848            1 :     struct RsMrCb *typicalMrCb = NULL;
     849            1 :     struct RsRdevCb *rdevCb = NULL;
     850              :     unsigned int chipId;
     851              :     int ret;
     852              : 
     853            1 :     CHK_PRT_RETURN(mrRegInfo == NULL || mrRegInfo->addr == NULL || mrRegInfo->len == 0 || phyId >= RS_MAX_DEV_NUM,
     854              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
     855              : 
     856            1 :     hccp_info("start register len[0x%llx], access[%d]", mrRegInfo->len, mrRegInfo->access);
     857              : 
     858            1 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
     859            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d", phyId, ret), ret);
     860              : 
     861            1 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
     862            1 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
     863              :         ret);
     864              : 
     865            1 :     typicalMrCb = calloc(1, sizeof(struct RsMrCb));
     866            1 :     CHK_PRT_RETURN(typicalMrCb == NULL, hccp_err("calloc typical_mr_cb failed"), -ENOMEM);
     867            1 :     typicalMrCb->devCb = rdevCb;
     868              : 
     869            1 :     ret = RsInitTypicalMrCb(phyId, mrRegInfo, rdevCb, typicalMrCb);
     870            1 :     if (ret != 0) {
     871            0 :         hccp_err("rs_init_typical_mr_cb failed, devIndex[%u], ret[%d]", rdevIndex, ret);
     872            0 :         goto reg_err;
     873              :     }
     874              : 
     875              :     // resv len as 1 to save addr for later unreg to query
     876            1 :     typicalMrCb->mrInfo.addr = (uint64_t)(uintptr_t)typicalMrCb->ibMr;
     877            1 :     typicalMrCb->mrInfo.len = 1U;
     878            1 :     *mrHandle = typicalMrCb->ibMr;
     879            1 :     mrRegInfo->lkey = typicalMrCb->ibMr->lkey;
     880            1 :     mrRegInfo->rkey = typicalMrCb->ibMr->rkey;
     881            1 :     hccp_info("register succ, state:%d", typicalMrCb->state);
     882            1 :     return 0;
     883              : 
     884            0 : reg_err:
     885            0 :     free(typicalMrCb);
     886            0 :     typicalMrCb = NULL;
     887            0 :     return ret;
     888              : }
     889              : 
     890            4 : RS_ATTRI_VISI_DEF int RsRemapMr(unsigned int phyId, unsigned int rdevIndex, struct MemRemapInfo memList[],
     891              :     unsigned int memNum)
     892              : {
     893            4 :     struct RsRdevCb *devCb = NULL;
     894            4 :     struct RsMrCb *mrCurr = NULL;
     895            4 :     struct RsMrCb *mrNext = NULL;
     896            4 :     unsigned long long addr = 0;
     897            4 :     bool isMemMatched = false;
     898              :     unsigned int chipId;
     899              :     unsigned int i;
     900              :     int ret;
     901              : 
     902            4 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= %d, is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
     903              : 
     904            4 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
     905            4 :     CHK_PRT_RETURN(ret, hccp_err("rsGetLocalDevIDByHostDevID failed, phyId:%u invalid, ret:%d", phyId, ret), ret);
     906              : 
     907            4 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &devCb);
     908            4 :     CHK_PRT_RETURN(devCb == NULL, hccp_err("rs_rdev2rdev_cb failed, chipId:%u, ret:%d", chipId, ret), -ENODEV);
     909              : 
     910            6 :     for (i = 0; i < memNum; i++) {
     911            4 :         isMemMatched = false;
     912            4 :         addr = (uint64_t)(uintptr_t)memList[i].addr;
     913            4 :         RS_PTHREAD_MUTEX_LOCK(&devCb->rdevMutex);
     914            4 :         RS_LIST_GET_HEAD_ENTRY(mrCurr, mrNext, &devCb->typicalMrList, list, struct RsMrCb);
     915            7 :         for (; (&mrCurr->list) != &devCb->typicalMrList;
     916            3 :              mrCurr = mrNext, mrNext = list_entry(mrNext->list.next, struct RsMrCb, list)) {
     917              :             // mem is out range of mr, continue to find next matching mr
     918            3 :             if ((addr < (uint64_t)(uintptr_t)mrCurr->ibMr->addr) || (memList[i].size > mrCurr->ibMr->length) ||
     919            2 :                 (addr + memList[i].size < addr) ||
     920            2 :                 (addr + memList[i].size > (uint64_t)(uintptr_t)mrCurr->ibMr->addr + mrCurr->ibMr->length)) {
     921            1 :                 continue;
     922              :             }
     923              : 
     924              :             // each mr remap each corresponding mem
     925            2 :             ret = RsRoceRemapMr(mrCurr->ibMr, (struct hns_roce_mr_remap_info *)(void *)&memList[i], 1);
     926            2 :             if (ret != 0) {
     927            0 :                 hccp_err("remap %u-th mem failed, ret:%d addr:0x%llx size:0x%llx", i, ret, addr, memList[i].size);
     928            0 :                 RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
     929            0 :                 return ret;
     930              :             }
     931            2 :             isMemMatched = true;
     932              :         }
     933            4 :         RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
     934              : 
     935            4 :         if (!isMemMatched) {
     936            2 :             hccp_err("find %u-th mem failed, addr:0x%llx size:0x%llx", i, addr, memList[i].size);
     937            2 :             return -ENODEV;
     938              :         }
     939            2 :         hccp_dbg("remap %u-th mem success, addr:0x%llx size:0x%llx", i, addr, memList[i].size);
     940              :     }
     941              : 
     942            2 :     return 0;
     943              : }
     944              : 
     945            2 : RS_ATTRI_VISI_DEF int RsTypicalDeregisterMr(unsigned int phyId, unsigned int devIndex, unsigned long long addr)
     946              : {
     947            2 :     struct RsMrCb *typicalMrCb = NULL;
     948            2 :     struct RsRdevCb *devCb = NULL;
     949              :     unsigned int chipId;
     950              :     int ret;
     951              : 
     952            2 :     hccp_info("typical mr unreg start, addr[%llu]", addr);
     953            2 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= %d, is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
     954              : 
     955            2 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
     956            2 :     CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
     957              : 
     958            2 :     ret = RsRdev2rdevCb(chipId, devIndex, &devCb);
     959            2 :     CHK_PRT_RETURN(ret != 0 || devCb == NULL,
     960              :         hccp_err("rs_rdev2rdev_cb get dev_cb failed for chip_id[%u], ret[%d]", chipId, ret), -ENODEV);
     961              : 
     962            2 :     ret = RsQueryMrCb(devCb, addr, &typicalMrCb, &devCb->typicalMrList);
     963            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_query_mr_cb failed ret[%d]", ret), ret);
     964              : 
     965            2 :     ret = RsDrvMrDereg(typicalMrCb->ibMr);
     966            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_drv_mr_dereg failed ret[%d]", ret), -EACCES);
     967              : 
     968            2 :     RS_PTHREAD_MUTEX_LOCK(&devCb->rdevMutex);
     969            2 :     RsListDel(&typicalMrCb->list);
     970            2 :     free(typicalMrCb);
     971            2 :     typicalMrCb = NULL;
     972            2 :     RS_PTHREAD_MUTEX_ULOCK(&devCb->rdevMutex);
     973              : 
     974            2 :     hccp_info("devIndex[%u] succ", devIndex);
     975              : 
     976            2 :     return 0;
     977              : }
     978              : 
     979            2 : RS_ATTRI_VISI_DEF int RsDeregisterMr(unsigned int phyId, unsigned int rdevIndex, void *mrHandle)
     980              : {
     981            2 :     RS_CHECK_POINTER_NULL_RETURN_INT(mrHandle);
     982              : 
     983            1 :     struct ibv_mr *rsMrHandle = (struct ibv_mr *)mrHandle;
     984            1 :     uint64_t addr = (uint64_t)(uintptr_t)rsMrHandle->addr;
     985            1 :     struct RsRdevCb *devCb = NULL;
     986              :     unsigned int chipId;
     987            1 :     int ret = 0;
     988              : 
     989            1 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
     990            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
     991              : 
     992            1 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &devCb);
     993            1 :     CHK_PRT_RETURN(ret != 0 || devCb == NULL,
     994              :         hccp_err("rs_rdev2rdev_cb get dev_cb failed for chip_id[%u], ret[%d]", chipId, ret), -ENODEV);
     995              : 
     996            1 :     ret = RsDrvMrDereg(rsMrHandle);
     997            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("rs_drv_mr_dereg failed ret[%d]", ret), -EACCES);
     998              : 
     999            1 :     ret = RsUnRegisterUbSegment(devCb->directFlag, addr);
    1000            1 :     CHK_PRT_RETURN(ret != 0,
    1001              :         hccp_err("RsUnRegisterUbSegment failed ret[%d], vendor_id[0x%x] part_id[0x%x]"
    1002              :                  " directFlag[%u]",
    1003              :             ret, devCb->deviceAttr.vendor_id, devCb->deviceAttr.vendor_part_id, devCb->directFlag),
    1004              :         ret);
    1005              : 
    1006            1 :     hccp_info("rs_deregister_mr succ");
    1007            1 :     return 0;
    1008              : }
    1009              : 
    1010            7 : RS_ATTRI_VISI_DEF int RsSendWr(unsigned int phyId, unsigned int rdevIndex, uint32_t qpn, struct SendWr *wr,
    1011              :     struct SendWrRsp *wrRsp)
    1012              : {
    1013              :     int ret;
    1014            7 :     struct RsQpCb *qpCb = NULL;
    1015            7 :     struct RsMrCb *mrCb = NULL;
    1016            7 :     struct RsMrCb *remMrCb = NULL;
    1017              : 
    1018            7 :     RS_CHECK_POINTER_NULL_RETURN_INT(wr);
    1019            7 :     RS_CHECK_POINTER_NULL_RETURN_INT(wr->bufList);
    1020            7 :     RS_CHECK_POINTER_NULL_RETURN_INT(wrRsp);
    1021              : 
    1022            7 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
    1023              : 
    1024            7 :     CHK_PRT_RETURN(wr->bufNum > MAX_SGE_NUM || wr->bufNum == 0, hccp_err("invalid buf_num[%u]!", wr->bufNum), -EINVAL);
    1025              : 
    1026            6 :     CHK_PRT_RETURN(wr->bufList->len > RS_SGLIST_LEN_MAX || wr->bufList->len == 0,
    1027              :         hccp_err("sg list"
    1028              :                  "len is more than 2G, len[%u]",
    1029              :             wr->bufList->len),
    1030              :         -EINVAL);
    1031              : 
    1032            5 :     if (RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb)) {
    1033            1 :         return -EACCES;
    1034              :     }
    1035              : 
    1036            4 :     qpCb->sendWrNum++;
    1037              : 
    1038            4 :     hccp_info("qpn %d, bufList[0].addr is 0x%llx", qpn, wr->bufList[0].addr);
    1039            4 :     if (RsGetMrcb(qpCb, wr->bufList[0].addr, &mrCb, &qpCb->mrList)) {
    1040            1 :         hccp_err("qpn %d, bufList[0].addr[0x%llx] len[0x%x] is invalid.", qpn, wr->bufList[0].addr, wr->bufList[0].len);
    1041            1 :         return -EFAULT;
    1042              :     }
    1043              : 
    1044              :     // send op no need to check & get remote mr
    1045            3 :     if (wr->op != RA_WR_SEND && wr->op != RA_WR_SEND_WITH_IMM) {
    1046            3 :         hccp_info("remote wr dst addr is 0x%llx", wr->dstAddr);
    1047            3 :         if (RsGetMrcb(qpCb, wr->dstAddr, &remMrCb, &qpCb->remMrList)) {
    1048            1 :             hccp_err("qpn %d, remote wr dst addr[0x%llx] len[0x%x] is invalid.", qpn, wr->dstAddr, wr->bufList[0].len);
    1049            1 :             return -ENOENT;
    1050              :         }
    1051              :     }
    1052              : 
    1053            2 :     ret = RsDrvSendExp(qpCb, mrCb, remMrCb, wr, wrRsp);
    1054            2 :     if (ret) {
    1055            0 :         hccp_err("send exp failed qpn %u, ret %d", qpn, ret);
    1056              :     }
    1057            2 :     gRsSendWrNum++;
    1058            2 :     return ret;
    1059              : }
    1060              : 
    1061            5 : STATIC void BuildUpWrWithKey(struct WrInfo *wr, struct ibv_sge *list, struct ibv_send_wr *ibWr)
    1062              : {
    1063            5 :     list->addr = (uintptr_t)wr->memList.addr;
    1064            5 :     list->length = wr->memList.len;
    1065            5 :     list->lkey = wr->memList.lkey;
    1066              : 
    1067            5 :     ibWr->sg_list = list;
    1068            5 :     ibWr->opcode = wr->op;
    1069            5 :     ibWr->send_flags = (unsigned int)wr->sendFlags;
    1070            5 :     ibWr->imm_data = htobe32(wr->immData);
    1071              : 
    1072            5 :     ibWr->num_sge = 1; /* only support one sge */
    1073            5 :     ibWr->wr_id = wr->wrId;
    1074            5 :     if (wr->op != IBV_WR_SEND && wr->op != IBV_WR_SEND_WITH_IMM) {
    1075            5 :         ibWr->wr.rdma.rkey = wr->rkey;
    1076            5 :         ibWr->wr.rdma.remote_addr = wr->dstAddr;
    1077              :     }
    1078            5 : }
    1079              : 
    1080            0 : STATIC void RsSendBuildUpWr(struct RsMrCb *mrCb, struct WrInfo *wr, struct ibv_sge *list, struct ibv_send_wr *ibWr)
    1081              : {
    1082            0 :     list->addr = (uintptr_t)wr->memList.addr;
    1083            0 :     list->lkey = mrCb->ibMr->lkey;
    1084            0 :     list->length = wr->memList.len;
    1085              : 
    1086            0 :     ibWr->sg_list = list;
    1087            0 :     ibWr->opcode = wr->op;
    1088            0 :     ibWr->imm_data = htobe32(wr->immData);
    1089            0 :     ibWr->send_flags = (unsigned int)wr->sendFlags;
    1090              : 
    1091            0 :     ibWr->num_sge = 1; /* only support one sge */
    1092            0 :     ibWr->wr_id = wr->wrId;
    1093            0 : }
    1094              : 
    1095            2 : STATIC void RsWirteAndReadBuildUpWr(struct RsMrCb *mrCb, struct RsMrCb *remMrCb, struct WrInfo *wr,
    1096              :     struct ibv_sge *list, struct ibv_send_wr *ibWr)
    1097              : {
    1098            2 :     list->addr = (uintptr_t)wr->memList.addr;
    1099            2 :     list->length = wr->memList.len;
    1100            2 :     list->lkey = mrCb->ibMr->lkey;
    1101              : 
    1102            2 :     ibWr->sg_list = list;
    1103            2 :     ibWr->opcode = wr->op;
    1104            2 :     ibWr->send_flags = (unsigned int)wr->sendFlags;
    1105            2 :     ibWr->imm_data = htobe32(wr->immData);
    1106              : 
    1107            2 :     ibWr->num_sge = 1; /* only support one sge */
    1108            2 :     ibWr->wr_id = wr->wrId;
    1109            2 :     ibWr->wr.rdma.rkey = remMrCb->mrInfo.rkey;
    1110            2 :     ibWr->wr.rdma.remote_addr = wr->dstAddr;
    1111            2 : }
    1112              : 
    1113           13 : STATIC int RsBuildUpWrList(struct WrInfo *wrList, struct RsQpCb *qpCb, struct ibv_sge *list, struct ibv_send_wr *ibWr,
    1114              :     unsigned int i)
    1115              : {
    1116           13 :     struct RsMrCb *mrCb = NULL;
    1117           13 :     struct RsMrCb *remMrCb = NULL;
    1118           13 :     CHK_PRT_RETURN(wrList[i].memList.len > RS_SGLIST_LEN_MAX,
    1119              :         hccp_err("sg list len is more than 2G, len[%u]", wrList[i].memList.len), -EINVAL);
    1120              : 
    1121           12 :     hccp_dbg("qpn %d, bufList[0].addr is 0x%llx", qpCb->ibQp->qp_num, wrList[i].memList.addr);
    1122           12 :     if (RsGetMrcb(qpCb, wrList[i].memList.addr, &mrCb, &qpCb->mrList)) {
    1123            2 :         hccp_err("qpn %d, bufList[0].addr[0x%llx] len[0x%x] is invalid.", qpCb->ibQp->qp_num, wrList[i].memList.addr,
    1124              :             wrList[i].memList.len);
    1125            2 :         return -EFAULT;
    1126              :     }
    1127              : 
    1128              :     // send op no need to check & get remote mr
    1129           10 :     if (wrList[i].op != IBV_WR_SEND && wrList[i].op != IBV_WR_SEND_WITH_IMM) {
    1130           10 :         hccp_dbg("remote wr dst addr is 0x%llx", wrList[i].dstAddr);
    1131           10 :         if (RsGetMrcb(qpCb, wrList[i].dstAddr, &remMrCb, &qpCb->remMrList)) {
    1132            8 :             hccp_err("qpn %d, remote wr dst addr[0x%llx] len[0x%x] is invalid.", qpCb->ibQp->qp_num, wrList[i].dstAddr,
    1133              :                 wrList[i].memList.len);
    1134            8 :             return -ENOENT;
    1135              :         }
    1136            2 :         RsWirteAndReadBuildUpWr(mrCb, remMrCb, &wrList[i], &list[i], &ibWr[i]);
    1137              :     } else {
    1138            0 :         RsSendBuildUpWr(mrCb, &wrList[i], &list[i], &ibWr[i]);
    1139              :     }
    1140              : 
    1141            2 :     return 0;
    1142              : }
    1143              : 
    1144            6 : STATIC int RsBuildUpWrListWithKey(struct WrInfo *wrList, struct ibv_sge *list, struct ibv_send_wr *ibWr, unsigned int i)
    1145              : {
    1146            6 :     CHK_PRT_RETURN(wrList[i].memList.len > RS_SGLIST_LEN_MAX,
    1147              :         hccp_err("sg list len is more than 2G, len[%u]", wrList[i].memList.len), -EINVAL);
    1148              : 
    1149            5 :     BuildUpWrWithKey(&wrList[i], &list[i], &ibWr[i]);
    1150            5 :     return 0;
    1151              : }
    1152              : 
    1153            8 : STATIC int RsSendNormalWrlist(struct RsQpCb *qpCb, struct WrInfo *wrList, unsigned int sendNum,
    1154              :     unsigned int *completeNum, unsigned int keyFlag)
    1155              : {
    1156              :     int ret;
    1157              :     unsigned int i, j;
    1158              : 
    1159            8 :     struct ibv_send_wr *badWr = NULL;
    1160            8 :     CHK_PRT_RETURN(sendNum > MAX_WR_NUM || sendNum == 0, hccp_err("send num[%u] is invalid!", sendNum), -EINVAL);
    1161            8 :     struct ibv_send_wr *ibWr = (struct ibv_send_wr *)calloc(sendNum, sizeof(struct ibv_send_wr));
    1162            8 :     CHK_PRT_RETURN(ibWr == NULL, hccp_err("calloc ib_wr failed!"), -ENOSPC);
    1163              : 
    1164            8 :     struct ibv_sge *list = (struct ibv_sge *)calloc(sendNum, sizeof(struct ibv_sge));
    1165            8 :     if (list == NULL) {
    1166            0 :         hccp_err("calloc list failed!");
    1167            0 :         ret = -ENOSPC;
    1168            0 :         goto alloc_fail;
    1169              :     }
    1170              : 
    1171           10 :     for (i = 0; i < sendNum; i++) {
    1172            6 :         ret = (keyFlag == 0) ? RsBuildUpWrList(wrList, qpCb, list, ibWr, i)
    1173            8 :                              : RsBuildUpWrListWithKey(wrList, list, ibWr, i);
    1174            8 :         if (ret) {
    1175            6 :             goto input_err;
    1176              :         }
    1177            2 :         j = i + 1;
    1178            2 :         ibWr[i].next = (i < sendNum - 1) ? &ibWr[j] : NULL;
    1179              :     }
    1180              : 
    1181            2 :     ret = RsIbvPostSend(qpCb->ibQp, &ibWr[0], &badWr);
    1182            2 :     if (ret == 0) {
    1183            2 :         *completeNum = sendNum;
    1184            0 :     } else if (ret == -ENOMEM) {
    1185            0 :         *completeNum = (unsigned int)((void *)badWr - (void *)ibWr) / sizeof(struct ibv_send_wr);
    1186            0 :         hccp_dbg("post send wqe overflow, completeNum[%d]", *completeNum);
    1187              :     } else {
    1188            0 :         hccp_err("ibv_post_send failed, ret[%d]", ret);
    1189            0 :         *completeNum = 0;
    1190              :     }
    1191            2 :     qpCb->sendWrNum = qpCb->sendWrNum + (*completeNum);
    1192              : 
    1193            8 : input_err:
    1194            8 :     free(list);
    1195            8 :     list = NULL;
    1196            8 : alloc_fail:
    1197            8 :     free(ibWr);
    1198            8 :     ibWr = NULL;
    1199            8 :     return (ret == -ENOMEM) ? 0 : ret;
    1200              : }
    1201              : 
    1202           11 : STATIC int RsSendExpWrlist(struct RsQpCb *qpCb, struct WrInfo *wrList, unsigned int sendNum, struct SendWrRsp *wrRsp,
    1203              :     unsigned int *completeNum, unsigned int keyFlag)
    1204              : {
    1205           11 :     struct ibv_post_send_ext_attr extAttr = {0};
    1206           11 :     struct ibv_post_send_ext_resp extRsp = {0};
    1207           11 :     struct ibv_send_wr *badWr = NULL;
    1208           11 :     struct wr_exp_rsp expRsp = {0};
    1209           11 :     struct ibv_send_wr ibWr = {0};
    1210           11 :     struct ibv_sge list = {0};
    1211              :     unsigned int i;
    1212           11 :     int ret = 0;
    1213              : 
    1214           14 :     for (i = 0; i < sendNum; i++) {
    1215              :         // reuse code: only need to build up one wr once a time
    1216            7 :         ret = (keyFlag == 0) ? RsBuildUpWrList(&wrList[i], qpCb, &list, &ibWr, 0)
    1217           11 :                              : RsBuildUpWrListWithKey(&wrList[i], &list, &ibWr, 0);
    1218           11 :         if (ret != 0) {
    1219            6 :             hccp_err("qpn:%u key_flag:%u build_up_wr i:%u failed, ret:%d", qpCb->ibQp->qp_num, keyFlag, i, ret);
    1220            6 :             break;
    1221              :         }
    1222              : 
    1223            5 :         if (wrList[i].op == RA_WR_RDMA_WRITE_WITH_NOTIFY || wrList[i].op == RA_WR_RDMA_REDUCE_WRITE ||
    1224            5 :             wrList[i].op == RA_WR_RDMA_REDUCE_WRITE_WITH_NOTIFY) {
    1225            1 :             ibWr.imm_data = htobe32((wrList[i].aux.notifyOffset & WRITE_NOTIFY_OFFSET_MASK) |
    1226              :                                     WRITE_NOTIFY_VALUE_RECORD);
    1227            1 :             extAttr.reduce_op = wrList[i].aux.reduceType;
    1228            1 :             extAttr.reduce_type = wrList[i].aux.dataType;
    1229            1 :             ret = RsIbvExtPostSend(qpCb->ibQp, &ibWr, &badWr, &extAttr, &extRsp);
    1230            1 :             expRsp.wqe_index = extRsp.wqe_index;
    1231            1 :             expRsp.db_info = extRsp.db_info;
    1232            1 :             hccp_dbg("rs_ibv_ext_post_send, op = [%x], immData = [0x%lx], reduce_op = [%d],reduceType = [%d]",
    1233              :                 ibWr.opcode, ibWr.imm_data, extAttr.reduce_op, extAttr.reduce_type);
    1234              :         } else {
    1235            4 :             ret = RsIbvExpPostSend(qpCb->ibQp, &ibWr, &badWr, &expRsp);
    1236            4 :             hccp_dbg("rs_ibv_exp_post_send, op = [%x], remoteAddr = [0x%llx], size = [%d]", ibWr.opcode,
    1237              :                 ibWr.wr.rdma.remote_addr, ibWr.sg_list->length);
    1238              :         }
    1239              : 
    1240            5 :         if (ret != 0) {
    1241            2 :             if (ret == -ENOMEM) {
    1242            1 :                 hccp_warn("qpn:%u rs_ibv_exp_post_send i:%u unsuccessful, ret %d", qpCb->ibQp->qp_num, i, ret);
    1243              :             } else {
    1244            1 :                 hccp_err("qpn:%u rs_ibv_exp_post_send i:%u failed, ret %d", qpCb->ibQp->qp_num, i, ret);
    1245              :             }
    1246            2 :             break;
    1247              :         }
    1248              : 
    1249            3 :         qpCb->sendWrNum++;
    1250              : 
    1251            3 :         if (qpCb->qpMode == RA_RS_GDR_TMPL_QP_MODE) {
    1252            1 :             wrRsp[i].wqeTmp.sqIndex = (unsigned int)qpCb->sqIndex;
    1253            1 :             wrRsp[i].wqeTmp.wqeIndex = expRsp.wqe_index;
    1254            2 :         } else if (qpCb->qpMode == RA_RS_OP_QP_MODE || qpCb->qpMode == RA_RS_GDR_ASYN_QP_MODE) {
    1255            2 :             wrRsp[i].db.dbIndex = (unsigned int)qpCb->dbIndex;
    1256            2 :             wrRsp[i].db.dbInfo = expRsp.db_info;
    1257              :         }
    1258              :     }
    1259              : 
    1260           11 :     hccp_dbg("complete_num[%d], ret[%d]", i, ret);
    1261           11 :     *completeNum = i;
    1262           11 :     return (ret == -ENOMEM) ? 0 : ret;
    1263              : }
    1264              : 
    1265           15 : RS_ATTRI_VISI_DEF int RsSendWrlist(struct RsWrlistBaseInfo baseInfo, struct WrInfo *wrList, unsigned int sendNum,
    1266              :     struct SendWrRsp *wrRsp, unsigned int *completeNum)
    1267              : {
    1268              :     int ret;
    1269              :     unsigned int phyId, rdevIndex, qpn;
    1270           15 :     struct RsQpCb *qpCb = NULL;
    1271              : 
    1272           15 :     RS_CHECK_POINTER_NULL_RETURN_INT(wrList);
    1273           15 :     RS_CHECK_POINTER_NULL_RETURN_INT(wrRsp);
    1274           15 :     CHK_PRT_RETURN(sendNum > MAX_WR_NUM || sendNum == 0 || baseInfo.phyId >= RS_MAX_DEV_NUM,
    1275              :         hccp_err("send_num[%u] or phyId:%u >= [%d], is invalid", sendNum, baseInfo.phyId, RS_MAX_DEV_NUM), -EINVAL);
    1276              : 
    1277           14 :     phyId = baseInfo.phyId;
    1278           14 :     rdevIndex = baseInfo.rdevIndex;
    1279           14 :     qpn = baseInfo.qpn;
    1280              : 
    1281           14 :     CHK_PRT_RETURN(RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb), hccp_err("rs_qpn2qpcb failed, physical id[%u]", phyId),
    1282              :         -EACCES);
    1283              : 
    1284              :     // only allow normal qp to call this func when ai_op_support not set
    1285           13 :     if (qpCb->qpMode == RA_RS_NOR_QP_MODE && qpCb->aiOpSupport == 0) {
    1286            6 :         ret = RsSendNormalWrlist(qpCb, wrList, sendNum, completeNum, baseInfo.keyFlag);
    1287              :     } else {
    1288            7 :         ret = RsSendExpWrlist(qpCb, wrList, sendNum, wrRsp, completeNum, baseInfo.keyFlag);
    1289              :     }
    1290           13 :     return ret;
    1291              : }
    1292              : 
    1293            0 : RS_ATTRI_VISI_DEF int RsRecvWrlist(struct RsWrlistBaseInfo baseInfo, struct RecvWrlistData *wr, unsigned int recvNum,
    1294              :     unsigned int *completeNum)
    1295              : {
    1296            0 :     struct RsQpCb *qpCb = NULL;
    1297              : 
    1298            0 :     RS_CHECK_POINTER_NULL_RETURN_INT(wr);
    1299            0 :     CHK_PRT_RETURN(recvNum > MAX_WR_NUM || recvNum == 0 || baseInfo.phyId >= RS_MAX_DEV_NUM,
    1300              :         hccp_err("recv_num[%u] or phyId:%u >= [%d], is invalid", recvNum, baseInfo.phyId, RS_MAX_DEV_NUM), -EINVAL);
    1301              : 
    1302            0 :     CHK_PRT_RETURN(RsQpn2qpcb(baseInfo.phyId, baseInfo.rdevIndex, baseInfo.qpn, &qpCb),
    1303              :         hccp_err("rs_qpn2qpcb failed, physical id[%u]", baseInfo.phyId), -EACCES);
    1304              : 
    1305            0 :     return RsDrvPostRecv(qpCb, wr, recvNum, completeNum);
    1306              : }
    1307              : 
    1308            0 : RS_ATTRI_VISI_DEF int RsSetHostPid(uint32_t phyId, pid_t hostPid, const char *pidSign)
    1309              : {
    1310              :     int ret;
    1311              :     unsigned int chipId;
    1312            0 :     struct rs_cb *rsCb = NULL;
    1313              : 
    1314            0 :     RS_CHECK_POINTER_NULL_RETURN_INT(pidSign);
    1315            0 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_set_host_pid rs set param error ! phyId:%u", phyId), -EINVAL);
    1316              : 
    1317            0 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1318            0 :     CHK_PRT_RETURN(ret, hccp_err("rs_set_host_pid rsGetLocalDevIDByHostDevID phyId invalid, ret %d", ret), ret);
    1319              : 
    1320            0 :     hccp_info("phyId[%u] host_pid[%d]", chipId, hostPid);
    1321              : 
    1322            0 :     ret = RsDev2rscb(chipId, &rsCb, false);
    1323            0 :     CHK_PRT_RETURN(ret, hccp_err("get rs cb failed, chipId:%u", chipId), ret);
    1324              : 
    1325            0 :     rsCb->pRsSign.tgid = hostPid;
    1326            0 :     ret = strcpy_s(rsCb->pRsSign.sign, PROCESS_RS_SIGN_LENGTH, pidSign);
    1327            0 :     CHK_PRT_RETURN(ret, hccp_err("copy sign failed, ret %d", ret), -ESAFEFUNC);
    1328              : 
    1329            0 :     return 0;
    1330              : }
    1331              : 
    1332            6 : RS_ATTRI_VISI_DEF int RsRdevGetPortStatus(unsigned int phyId, unsigned int rdevIndex, enum PortStatus *status)
    1333              : {
    1334            6 :     struct ibv_port_attr portAttr = {0};
    1335            6 :     struct RsRdevCb *rdevCb = NULL;
    1336              :     unsigned int chipId;
    1337              :     int ret;
    1338              : 
    1339            6 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
    1340            4 :     CHK_PRT_RETURN(status == NULL, hccp_err("param err! status is NULL"), -EINVAL);
    1341              : 
    1342            3 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1343            3 :     CHK_PRT_RETURN(ret, hccp_err("rsGetLocalDevIDByHostDevID failed, phyId[%u] invalid, ret %d", phyId, ret), ret);
    1344              : 
    1345            3 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
    1346            3 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
    1347              :         ret);
    1348              : 
    1349            2 :     ret = RsIbvQueryPort(rdevCb->ibCtx, rdevCb->ibPort, &portAttr);
    1350            2 :     CHK_PRT_RETURN(ret, hccp_err("ibv_query_port failed ret[%d]", ret), -EOPENSRC);
    1351              : 
    1352            1 :     *status = portAttr.state == IBV_PORT_ACTIVE ? PORT_STATUS_ACTIVE : PORT_STATUS_DOWN;
    1353              : 
    1354            1 :     hccp_dbg("phyId:%u port_attr.state:%u status:%u", phyId, portAttr.state, *status);
    1355            1 :     return 0;
    1356              : }
    1357              : 
    1358            3 : RS_ATTRI_VISI_DEF int RsGetNotifyMrInfo(unsigned int phyId, unsigned int rdevIndex, struct MrInfoT *info)
    1359              : {
    1360            3 :     struct RsRdevCb *rdevCb = NULL;
    1361            3 :     struct rs_cb *rsCb = NULL;
    1362              :     unsigned int chipId;
    1363              :     int ret;
    1364              : 
    1365            3 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
    1366              : 
    1367            2 :     CHK_PRT_RETURN(info == NULL, hccp_err("param err! info is NULL"), -EINVAL);
    1368              : 
    1369            1 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1370            1 :     CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret:%d", phyId, ret), ret);
    1371              : 
    1372            1 :     ret = RsDev2rscb(chipId, &rsCb, false);
    1373            1 :     CHK_PRT_RETURN(ret, hccp_err("get rs_cb failed, ret:%d", ret), -ENODEV);
    1374              : 
    1375            1 :     ret = RsGetRdevCb(rsCb, rdevIndex, &rdevCb);
    1376            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed!, ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
    1377              : 
    1378            1 :     info->addr = (void *)(uintptr_t)rdevCb->notifyVaBase;
    1379            1 :     info->size = rdevCb->notifySize;
    1380            1 :     info->access = rdevCb->notifyAccess;
    1381            1 :     info->lkey = rdevCb->notifyMr->lkey;
    1382              : 
    1383            1 :     return 0;
    1384              : }
    1385              : 
    1386            4 : RS_ATTRI_VISI_DEF int RsNotifyCfgSet(unsigned int phyId, unsigned long long va, unsigned long long size)
    1387              : {
    1388              :     int ret;
    1389              :     unsigned int chipId;
    1390            4 :     struct rs_cb *rsCb = NULL;
    1391              : 
    1392            4 :     RS_CHECK_POINTER_NULL_RETURN_INT((void *)(uintptr_t)va);
    1393              : 
    1394            4 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM ||
    1395              :                        (size != MAX_NOTIFY_SIZE_CLOUD && size != NOTIFY_NUM_MAX_V2 && size != NOTIFY_NUM_MAX_V3),
    1396              :         hccp_err("rs_notify_cfg_set rs set param error ! phyId[%u] size[%llu]", phyId, size), -EINVAL);
    1397              : 
    1398            3 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1399            3 :     CHK_PRT_RETURN(ret, hccp_err("rs_notify_cfg_set phyId invalid, ret %d, phyId:%u", ret, phyId), ret);
    1400              : 
    1401            1 :     ret = RsDev2rscb(chipId, &rsCb, false);
    1402            1 :     CHK_PRT_RETURN(ret, hccp_err("get rs cb failed, chipId:%u", chipId), ret);
    1403              : 
    1404            1 :     rsCb->notifyVaBase = va;
    1405            1 :     rsCb->notifySize = size;
    1406              : 
    1407            1 :     return 0;
    1408              : }
    1409              : 
    1410            0 : RS_ATTRI_VISI_DEF int RsNotifyCfgGet(unsigned int phyId, unsigned long long *va, unsigned long long *size)
    1411              : {
    1412              :     int ret;
    1413              :     unsigned int chipId;
    1414            0 :     struct rs_cb *rsCb = NULL;
    1415              : 
    1416            0 :     RS_CHECK_POINTER_NULL_RETURN_INT(va);
    1417            0 :     RS_CHECK_POINTER_NULL_RETURN_INT(size);
    1418              : 
    1419            0 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_notify_cfg_get rs set param error ! phyId:%u", phyId),
    1420              :         -EINVAL);
    1421              : 
    1422            0 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1423            0 :     CHK_PRT_RETURN(ret, hccp_err("rs_notify_cfg_get phyId invalid, ret %d, phyId:%u", ret, phyId), ret);
    1424              : 
    1425            0 :     ret = RsDev2rscb(chipId, &rsCb, false);
    1426            0 :     CHK_PRT_RETURN(ret, hccp_err("get rs cb failed, chipId:%u", chipId), ret);
    1427              : 
    1428            0 :     *va = rsCb->notifyVaBase;
    1429            0 :     *size = rsCb->notifySize;
    1430              : 
    1431            0 :     return 0;
    1432              : }
    1433              : 
    1434            6 : RS_ATTRI_VISI_DEF int RsSetTsqpDepth(unsigned int phyId, unsigned int rdevIndex, unsigned int tempDepth,
    1435              :     unsigned int *qpNum)
    1436              : {
    1437              : #ifdef CUSTOM_INTERFACE
    1438            6 :     struct RsRdevCb *rdevCb = NULL;
    1439            6 :     unsigned int sqDepth = 0;
    1440            6 :     unsigned int chipId = 0;
    1441              :     int ret;
    1442              : 
    1443            6 :     if (!RsIsCustomInterfaceSupported()) {
    1444            0 :         return 0;
    1445              :     }
    1446            6 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_set_tsqp_depth param error ! phyId:%d", phyId), -EINVAL);
    1447              : 
    1448            5 :     CHK_PRT_RETURN(qpNum == NULL, hccp_err("rs_set_tsqp_depth qp_num is NULL, param error!"), -EINVAL);
    1449              : 
    1450            4 :     CHK_PRT_RETURN(tempDepth < RS_MIN_TEMPTH_DEPTH || tempDepth > RS_MAX_TEMPTH_DEPTH,
    1451              :         hccp_err("param error!"
    1452              :                  "temp_depth[%u] can not smaller than [%d] or bigerr than [%d]",
    1453              :             tempDepth, RS_MIN_TEMPTH_DEPTH, RS_MAX_TEMPTH_DEPTH),
    1454              :         -EINVAL);
    1455              : 
    1456            3 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1457            3 :     CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
    1458              : 
    1459            2 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
    1460            2 :     CHK_PRT_RETURN(ret || rdevCb == NULL,
    1461              :         hccp_err("rs_set_tsqp_depth rs_rdev2rdev_cb for chip_id[%u]"
    1462              :                  "failed, ret %d",
    1463              :             chipId, ret),
    1464              :         ret);
    1465              : 
    1466            1 :     ret = RsRoceSetTsqpDepth(rdevCb->devName, rdevIndex, tempDepth, qpNum, &sqDepth);
    1467            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_roce_set_tsqp_depth failed, ret %d, devName[%s]", ret, rdevCb->devName), ret);
    1468              : 
    1469            0 :     rdevCb->txDepth = sqDepth;
    1470            0 :     rdevCb->rxDepth = sqDepth;
    1471            0 :     rdevCb->qpMaxNum = *qpNum;
    1472              : #endif
    1473            0 :     return 0;
    1474              : }
    1475              : 
    1476            5 : RS_ATTRI_VISI_DEF int RsGetTsqpDepth(unsigned int phyId, unsigned int rdevIndex, unsigned int *tempDepth,
    1477              :     unsigned int *qpNum)
    1478              : {
    1479              : #ifdef CUSTOM_INTERFACE
    1480            5 :     struct RsRdevCb *rdevCb = NULL;
    1481            5 :     unsigned int sqDepth = 0;
    1482            5 :     unsigned int chipId = 0;
    1483              :     int ret;
    1484              : 
    1485            5 :     if (!RsIsCustomInterfaceSupported()) {
    1486            0 :         return 0;
    1487              :     }
    1488            5 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("param error ! phyId:%d", phyId), -EINVAL);
    1489              : 
    1490            4 :     CHK_PRT_RETURN(tempDepth == NULL || qpNum == NULL,
    1491              :         hccp_err("temp_depth or qp_num is NULL,"
    1492              :                  "param error!"),
    1493              :         -EINVAL);
    1494              : 
    1495            3 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1496            3 :     CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
    1497              : 
    1498            2 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
    1499            2 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL,
    1500              :         hccp_err("rs_get_tsqp_depth rs_rdev2rdev_cb for chip_id[%u]"
    1501              :                  "failed, ret %d",
    1502              :             chipId, ret),
    1503              :         ret);
    1504              : 
    1505            1 :     ret = RsRoceGetTsqpDepth(rdevCb->devName, rdevIndex, tempDepth, qpNum, &sqDepth);
    1506            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_roce_get_tsqp_depth failed, ret %d, devName[%s]", ret, rdevCb->devName), ret);
    1507              : #endif
    1508            0 :     return 0;
    1509              : }
    1510              : 
    1511           45 : STATIC void RsSetQpDepthAttr(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, struct RsQpNorm *qpNorm)
    1512              : {
    1513           45 :     if (qpCb->qpMode == RA_RS_GDR_TMPL_QP_MODE) {
    1514           41 :         qpCb->txDepth = rdevCb->txDepth;
    1515           41 :         qpCb->rxDepth = rdevCb->rxDepth;
    1516              :     } else {
    1517            4 :         if (rdevCb->rsCb->hccpMode == NETWORK_OFFLINE) {
    1518            2 :             qpCb->txDepth = RS_QP_TX_DEPTH_OFFLINE;
    1519            2 :             qpCb->rxDepth = RS_QP_RX_DEPTH_OFFLINE;
    1520              :         } else {
    1521            2 :             qpCb->txDepth = RS_QP_TX_DEPTH_ONLINE;
    1522            2 :             qpCb->rxDepth = RS_QP_RX_DEPTH_ONLINE;
    1523              :         }
    1524              :     }
    1525              : 
    1526           45 :     if (qpNorm->isExp != 0 && qpNorm->qpMode != RA_RS_NOR_QP_MODE) {
    1527           43 :         if (rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
    1528            2 :             qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->txDepth;
    1529            2 :             qpCb->rxDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->rxDepth;
    1530              :         } else {
    1531           41 :             qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE && qpCb->qpMode != RA_RS_GDR_ASYN_QP_MODE)
    1532              :                                 ? RS_QP_32K_DEPTH
    1533           41 :                                 : qpCb->txDepth;
    1534              :         }
    1535           43 :         qpCb->sendSgeNum = 1;
    1536           43 :         qpCb->recvSgeNum = 1;
    1537              :     } else {
    1538            2 :         if (rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
    1539            0 :             qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->txDepth;
    1540            0 :             qpCb->rxDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH_PEER_ONLINE : qpCb->rxDepth;
    1541              :         } else {
    1542            2 :             qpCb->txDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH : qpCb->txDepth;
    1543            2 :             qpCb->rxDepth = (qpCb->qpMode != RA_RS_GDR_TMPL_QP_MODE) ? RS_QP_TX_DEPTH : qpCb->rxDepth;
    1544              :         }
    1545            2 :         qpCb->sendSgeNum = RS_QP_ATTR_MAX_SEND_SGE;
    1546            2 :         qpCb->recvSgeNum = 1;
    1547              :     }
    1548           45 : }
    1549              : 
    1550           45 : STATIC int RsQpcbInit(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, struct RsQpNorm *qpNorm)
    1551              : {
    1552              : #define RS_DRV_CQ_DEPTH 16384
    1553              : #define RS_DRV_CQ_128_DEPTH 128
    1554              : #define RS_DRV_CQ_8K_DEPTH 8192
    1555              : #define RS_DRV_CQ_32K_DEPTH 32768
    1556           45 :     int qpMode = qpNorm->qpMode;
    1557              :     int ret;
    1558              : 
    1559           45 :     qpCb->rdevCb = rdevCb;
    1560           45 :     RS_INIT_LIST_HEAD(&qpCb->mrList);
    1561           45 :     RS_INIT_LIST_HEAD(&qpCb->remMrList);
    1562              : 
    1563           45 :     qpCb->qpMode = qpMode;
    1564           45 :     qpCb->eqNum = 0;
    1565           45 :     qpCb->numRecvCqEvents = 0;
    1566           45 :     qpCb->numSendCqEvents = 0;
    1567           45 :     qpCb->state = RS_QP_STATUS_DISCONNECT;
    1568           45 :     qpCb->ibPd = rdevCb->ibPd;
    1569              : 
    1570              :     // cq attr
    1571           45 :     if (qpNorm->isExt == 1) {
    1572              :         // update TEMP & ASYN mode cq depth from 32K to 8K due to memory issue
    1573            2 :         qpCb->sendCqDepth = (qpMode != RA_RS_GDR_TMPL_QP_MODE && qpMode != RA_RS_GDR_ASYN_QP_MODE) ? RS_DRV_CQ_32K_DEPTH
    1574            4 :                                                                                                    : RS_DRV_CQ_8K_DEPTH;
    1575            2 :         qpCb->recvCqDepth = RS_DRV_CQ_128_DEPTH;
    1576              :     } else {
    1577           43 :         qpCb->sendCqDepth = RS_DRV_CQ_DEPTH;
    1578           43 :         qpCb->recvCqDepth = RS_DRV_CQ_DEPTH;
    1579              :     }
    1580              : 
    1581              :     // qp attr
    1582           45 :     RsSetQpDepthAttr(rdevCb, qpCb, qpNorm);
    1583              : 
    1584           45 :     qpCb->memAlign = qpNorm->memAlign;
    1585              : 
    1586           45 :     qpCb->channel = RsIbvCreateCompChannel(rdevCb->ibCtx);
    1587           45 :     CHK_PRT_RETURN(qpCb->channel == NULL, hccp_err("ibv_create_comp_channel failed! errno(%d)", errno), -EINVAL);
    1588           44 :     qpCb->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
    1589           44 :     qpCb->qosAttr.sl = RS_ROCE_4_SL;
    1590           44 :     qpCb->timeout = RS_QP_ATTR_TIMEOUT;
    1591           44 :     qpCb->retryCnt = RS_QP_ATTR_RETRY_CNT;
    1592              : 
    1593           44 :     ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_ADD, qpCb->channel->fd, EPOLLIN | EPOLLRDHUP);
    1594              : #ifndef CA_CONFIG_LLT
    1595              :     if (ret) {
    1596              :         RsIbvDestroyCompChannel(qpCb->channel);
    1597              :         hccp_err("add channel fd failed ret %d", ret);
    1598              :         return ret;
    1599              :     }
    1600              : #endif
    1601           44 :     return 0;
    1602              : }
    1603              : 
    1604           48 : STATIC int RsQpcbDeinit(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb)
    1605              : {
    1606              :     int ret;
    1607              : 
    1608           48 :     if (qpCb == NULL || qpCb->channel == NULL) {
    1609            0 :         hccp_err("qp_cb or qp_cb->channel is NULL!");
    1610            0 :         return -EINVAL;
    1611              :     }
    1612              : 
    1613           48 :     ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_DEL, qpCb->channel->fd, EPOLLIN | EPOLLRDHUP);
    1614              : #ifndef CA_CONFIG_LLT
    1615              :     if (ret) {
    1616              :         hccp_err("del channel fd failed ret %d", ret);
    1617              :     }
    1618              : #endif
    1619              : 
    1620           48 :     if (qpCb->channel != NULL) {
    1621           48 :         RsIbvDestroyCompChannel(qpCb->channel);
    1622           48 :         qpCb->channel = NULL;
    1623              :     }
    1624              : #ifndef CA_CONFIG_LLT
    1625              :     return ret;
    1626              : #else
    1627           48 :     return 0;
    1628              : #endif
    1629              : }
    1630              : 
    1631           32 : STATIC int RsQpNotifyMr(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, uint32_t *qpn)
    1632              : {
    1633              :     int ret;
    1634           32 :     struct RsMrCb *notifyMrNode = NULL;
    1635              : 
    1636           32 :     ret = RsCallocMr(1, &notifyMrNode);
    1637           32 :     CHK_PRT_RETURN(ret, hccp_err("notify_mr_cb malloc failed"), ret);
    1638              : 
    1639           32 :     RS_PTHREAD_MUTEX_LOCK(&rdevCb->rdevMutex);
    1640           32 :     RsListAddTail(&qpCb->list, &rdevCb->qpList);
    1641           32 :     RS_PTHREAD_MUTEX_ULOCK(&rdevCb->rdevMutex);
    1642              : 
    1643           32 :     if (rdevCb->notifyType != NO_USE) {
    1644           32 :         notifyMrNode->qpCb = qpCb;
    1645           32 :         notifyMrNode->ibMr = rdevCb->notifyMr;
    1646           32 :         notifyMrNode->mrInfo.addr = rdevCb->notifyVaBase;
    1647           32 :         notifyMrNode->mrInfo.len = rdevCb->notifySize;
    1648           32 :         notifyMrNode->mrInfo.rkey = notifyMrNode->ibMr->rkey;
    1649              :     } else {
    1650            0 :         notifyMrNode->qpCb = qpCb;
    1651            0 :         notifyMrNode->ibMr = NULL;
    1652              :     }
    1653              : 
    1654           32 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
    1655           32 :     RsListAddTail(&notifyMrNode->list, &qpCb->mrList);
    1656           32 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
    1657           32 :     rdevCb->qpCnt++;
    1658           32 :     *qpn = qpCb->ibQp->qp_num;
    1659              : 
    1660           32 :     hccp_info("rs qp %d create OK!", *qpn);
    1661              : 
    1662           32 :     return 0;
    1663              : }
    1664              : 
    1665           53 : STATIC int RsQpQueryInfo(unsigned int phyId, unsigned int rdevIndex, struct RsRdevCb **rdevCb, int qpMode)
    1666              : {
    1667              :     int ret;
    1668              :     unsigned int chipId;
    1669           53 :     struct rs_cb *rsCb = NULL;
    1670              : 
    1671           53 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs_qp_query_info rs set param error! phyId:%u", phyId), -EINVAL);
    1672              : 
    1673           53 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    1674           53 :     CHK_PRT_RETURN(ret, hccp_err("rs_qp_query_info phyId[%u] invalid, ret:%d", phyId, ret), ret);
    1675              : 
    1676           52 :     ret = RsDev2rscb(chipId, &rsCb, false);
    1677           52 :     CHK_PRT_RETURN(ret, hccp_err("rs_qp_query_info get rs_cb failed, ret:%d", ret), -ENODEV);
    1678              : 
    1679           52 :     ret = RsGetRdevCb(rsCb, rdevIndex, rdevCb);
    1680           52 :     CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed! ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
    1681              : 
    1682           52 :     if (qpMode == RA_RS_GDR_TMPL_QP_MODE) {
    1683           46 :         CHK_PRT_RETURN((*rdevCb)->qpCnt >= (*rdevCb)->qpMaxNum,
    1684              :             hccp_err("Exceeded the maximum QP limit(%u)", (*rdevCb)->qpMaxNum), -EINVAL);
    1685              :     } else {
    1686            6 :         CHK_PRT_RETURN((*rdevCb)->qpCnt >= RS_QP_NUM_MAX,
    1687              :             hccp_err("Exceeded the maximum QP limit(%u)", (*rdevCb)->qpCnt), -EINVAL);
    1688              :     }
    1689              : 
    1690           50 :     return 0;
    1691              : }
    1692              : 
    1693           50 : STATIC int RsInitMemPool(struct RsQpCb *qpCb)
    1694              : {
    1695           50 :     struct roce_mem_cq_qp_attr memAttr = {0};
    1696              :     int ret;
    1697              : 
    1698           50 :     if ((qpCb->qpMode != RA_RS_OP_QP_MODE && qpCb->qpMode != RA_RS_OP_QP_MODE_EXT) ||
    1699            4 :         qpCb->memAlign != LITE_ALIGN_2MB) {
    1700           49 :         return 0;
    1701              :     }
    1702              : 
    1703              :     // init mem_pool and store mem_data in mem_resp
    1704            1 :     memAttr.mem_align = qpCb->memAlign;
    1705            1 :     memAttr.send_qp_depth = qpCb->txDepth;
    1706            1 :     memAttr.send_cq_depth = (unsigned int)qpCb->sendCqDepth;
    1707            1 :     memAttr.send_sge_num = qpCb->sendSgeNum;
    1708            1 :     memAttr.recv_qp_depth = qpCb->rxDepth;
    1709            1 :     memAttr.recv_cq_depth = (unsigned int)qpCb->recvCqDepth;
    1710            1 :     memAttr.recv_sge_num = qpCb->recvSgeNum;
    1711            1 :     memAttr.use_resv_mem = qpCb->useResvMem;
    1712            1 :     memAttr.resv_mem_pool_id = qpCb->resvMemPoolId;
    1713            1 :     memAttr.ctx = qpCb->rdevCb->ibCtx;
    1714              : 
    1715            1 :     ret = RsRoceInitMemPool(&memAttr, &qpCb->memResp.memData, qpCb->rdevCb->rsCb->chipId);
    1716            1 :     if (ret != 0) {
    1717            1 :         hccp_err("rs_roce_init_mem_pool failed, ret=%d, chipId=%u", ret, qpCb->rdevCb->rsCb->chipId);
    1718              :     }
    1719            1 :     return ret;
    1720              : }
    1721              : 
    1722           50 : STATIC void RsDeinitMemPool(struct RsQpCb *qpCb)
    1723              : {
    1724           50 :     if ((qpCb->qpMode != RA_RS_OP_QP_MODE && qpCb->qpMode != RA_RS_OP_QP_MODE_EXT) ||
    1725            4 :         qpCb->memAlign != LITE_ALIGN_2MB) {
    1726           49 :         return;
    1727              :     }
    1728              : 
    1729            1 :     (void)RsRoceDeinitMemPool(qpCb->memResp.memData.mem_idx);
    1730              : }
    1731              : 
    1732           46 : STATIC int RsAllocQpcb(struct RsRdevCb *rdevCb, struct RsQpCb **qpCb, struct RsQpNorm *qpNorm)
    1733              : {
    1734              :     int ret;
    1735              : 
    1736           46 :     ret = RsCallocQpcb(1, qpCb);
    1737           46 :     CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
    1738              : 
    1739           45 :     ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
    1740           45 :     if (ret) {
    1741            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    1742            0 :         goto qp_mutex_init_err;
    1743              :     }
    1744              : 
    1745           45 :     ret = pthread_mutex_init(&(*qpCb)->cqeErrInfo.mutex, NULL);
    1746           45 :     if (ret) {
    1747            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    1748            0 :         goto cqe_mutex_init_err;
    1749              :     }
    1750              : 
    1751           45 :     ret = RsQpcbInit(rdevCb, *qpCb, qpNorm);
    1752           45 :     if (ret) {
    1753            1 :         hccp_err("create qp tx rx failed ret %d", ret);
    1754            1 :         goto rs_qpcb_init_err;
    1755              :     }
    1756              : 
    1757           44 :     ret = RsInitMemPool(*qpCb);
    1758           44 :     if (ret) {
    1759            0 :         hccp_err("init mem pool failed ret %d", ret);
    1760            0 :         goto rs_init_mem_err;
    1761              :     }
    1762              : 
    1763           44 :     ret = RsDrvCreateCq(*qpCb, qpNorm->isExt);
    1764           44 :     if (ret) {
    1765            1 :         hccp_err("create cq failed ret %d", ret);
    1766            1 :         goto create_cq_err;
    1767              :     }
    1768              : 
    1769           43 :     return 0;
    1770              : 
    1771            1 : create_cq_err:
    1772            1 :     RsDeinitMemPool(*qpCb);
    1773              : 
    1774            1 : rs_init_mem_err:
    1775            1 :     RsQpcbDeinit(rdevCb, *qpCb);
    1776              : 
    1777            2 : rs_qpcb_init_err:
    1778            2 :     pthread_mutex_destroy(&(*qpCb)->cqeErrInfo.mutex);
    1779              : 
    1780            2 : cqe_mutex_init_err:
    1781            2 :     pthread_mutex_destroy(&(*qpCb)->qpMutex);
    1782              : 
    1783            2 : qp_mutex_init_err:
    1784            2 :     free(*qpCb);
    1785            2 :     *qpCb = NULL;
    1786              : 
    1787            2 :     return ret;
    1788              : }
    1789              : 
    1790           15 : STATIC void RsFreeQpcb(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb)
    1791              : {
    1792           15 :     RsDrvDestroyCq(qpCb);
    1793           15 :     RsDeinitMemPool(qpCb);
    1794           15 :     (void)RsQpcbDeinit(rdevCb, qpCb);
    1795           15 :     pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
    1796           15 :     pthread_mutex_destroy(&qpCb->qpMutex);
    1797           15 :     free(qpCb);
    1798           15 :     qpCb = NULL;
    1799           15 : }
    1800              : 
    1801           48 : RS_ATTRI_VISI_DEF int RsQpCreate(unsigned int phyId, unsigned int rdevIndex, struct RsQpNorm qpNorm,
    1802              :     struct RsQpResp *qpResp)
    1803              : {
    1804           48 :     struct RsRdevCb *rdevCb = NULL;
    1805           48 :     struct RsQpCb *qpCb = NULL;
    1806              :     int ret;
    1807              : 
    1808           48 :     RS_QP_PARA_CHECK(phyId);
    1809           47 :     CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
    1810              : 
    1811           47 :     ret = RsQpQueryInfo(phyId, rdevIndex, &rdevCb, qpNorm.qpMode);
    1812           47 :     CHK_PRT_RETURN(ret, hccp_err("query qp info failed:%d", ret), ret);
    1813              : 
    1814           46 :     ret = RsAllocQpcb(rdevCb, &qpCb, &qpNorm);
    1815           46 :     CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d", ret), ret);
    1816              : 
    1817           43 :     ret = RsDrvQpCreate(qpCb, &qpNorm);
    1818           43 :     if (ret) {
    1819           14 :         hccp_err("create drv qp create failed:%d", ret);
    1820           14 :         goto create_qp_err;
    1821              :     }
    1822              : 
    1823           29 :     ret = ibv_req_notify_cq(qpCb->ibSendCq, 0);
    1824           29 :     if (ret) {
    1825            1 :         hccp_err("Couldn't request send CQ notification, ret:%d", ret);
    1826            1 :         ret = -EOPENSRC;
    1827            1 :         goto ret_noritfy_cq;
    1828              :     }
    1829              : 
    1830           28 :     ret = ibv_req_notify_cq(qpCb->ibRecvCq, 0);
    1831           28 :     if (ret) {
    1832            0 :         hccp_err("Couldn't request recv CQ notification, ret:%d", ret);
    1833            0 :         ret = -EOPENSRC;
    1834            0 :         goto ret_noritfy_cq;
    1835              :     }
    1836              : 
    1837           28 :     ret = RsQpNotifyMr(rdevCb, qpCb, &qpResp->qpn); // alloc mr
    1838           28 :     if (ret) {
    1839            0 :         hccp_err("store qp notify mr failed:%d", ret);
    1840            0 :         goto ret_noritfy_cq;
    1841              :     }
    1842              : 
    1843           28 :     if (qpNorm.isExp) {
    1844           26 :         qpCb->isExp = RS_IS_EXP;
    1845              :     } else {
    1846            2 :         qpCb->isExp = RS_NOT_EXP;
    1847              :     }
    1848              : 
    1849           28 :     qpResp->qpn = (unsigned int)qpCb->qpInfoLo.qpn;
    1850           28 :     qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
    1851           28 :     qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
    1852           28 :     qpResp->gid = qpCb->qpInfoLo.gid;
    1853              : 
    1854           28 :     return 0;
    1855              : 
    1856            1 : ret_noritfy_cq:
    1857            1 :     RsDrvQpDestroy(qpCb);
    1858              : 
    1859           15 : create_qp_err:
    1860           15 :     RsFreeQpcb(rdevCb, qpCb);
    1861           15 :     return ret;
    1862              : }
    1863              : 
    1864            4 : STATIC int RsQpcbInitWithAttrs(struct RsRdevCb *rdevCb, struct RsQpCb *qpCb, struct RsQpNormWithAttrs *qpNorm)
    1865              : {
    1866              :     int ret;
    1867              : 
    1868            4 :     qpCb->rdevCb = rdevCb;
    1869            4 :     RS_INIT_LIST_HEAD(&qpCb->mrList);
    1870            4 :     RS_INIT_LIST_HEAD(&qpCb->remMrList);
    1871              : 
    1872            4 :     qpCb->qpMode = qpNorm->extAttrs.qpMode;
    1873            4 :     qpCb->numRecvCqEvents = 0;
    1874            4 :     qpCb->numSendCqEvents = 0;
    1875            4 :     qpCb->state = RS_QP_STATUS_DISCONNECT;
    1876            4 :     qpCb->ibPd = rdevCb->ibPd;
    1877              : 
    1878            4 :     qpCb->txDepth = qpNorm->extAttrs.qpAttr.cap.max_send_wr;
    1879            4 :     qpCb->rxDepth = qpNorm->extAttrs.qpAttr.cap.max_send_wr;
    1880            4 :     qpCb->sendSgeNum = qpNorm->extAttrs.qpAttr.cap.max_send_sge;
    1881            4 :     qpCb->recvSgeNum = qpNorm->extAttrs.qpAttr.cap.max_recv_sge;
    1882            4 :     qpCb->sendCqDepth = qpNorm->extAttrs.cqAttr.sendCqDepth;
    1883            4 :     qpCb->recvCqDepth = qpNorm->extAttrs.cqAttr.recvCqDepth;
    1884            4 :     qpCb->memAlign = qpNorm->extAttrs.memAlign;
    1885              : 
    1886            4 :     qpCb->channel = RsIbvCreateCompChannel(rdevCb->ibCtx);
    1887            4 :     CHK_PRT_RETURN(qpCb->channel == NULL, hccp_err("ibv_create_comp_channel failed! errno(%d)", errno), -EINVAL);
    1888            4 :     qpCb->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
    1889            4 :     qpCb->qosAttr.sl = RS_ROCE_4_SL;
    1890            4 :     qpCb->timeout = RS_QP_ATTR_TIMEOUT;
    1891            4 :     qpCb->retryCnt = RS_QP_ATTR_RETRY_CNT;
    1892              : 
    1893            4 :     qpCb->udpSport = qpNorm->extAttrs.udpSport;
    1894              : 
    1895            4 :     qpCb->aiOpSupport = qpNorm->aiOpSupport;
    1896            4 :     qpCb->grpId = rdevCb->rsCb->grpId;
    1897            4 :     qpCb->cqCstmFlag = qpNorm->extAttrs.dataPlaneFlag.bs.cqCstm;
    1898            4 :     qpCb->useResvMem = qpNorm->extAttrs.cstmFlag.bs.useResvMem;
    1899            4 :     qpCb->resvMemPoolId = qpNorm->extAttrs.resvMemPoolId;
    1900              : 
    1901            4 :     ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_ADD, qpCb->channel->fd, EPOLLIN | EPOLLRDHUP);
    1902              : #ifndef CA_CONFIG_LLT
    1903              :     if (ret) {
    1904              :         RsIbvDestroyCompChannel(qpCb->channel);
    1905              :         hccp_err("add channel fd failed ret %d", ret);
    1906              :         return ret;
    1907              :     }
    1908              : #endif
    1909            4 :     return 0;
    1910              : }
    1911              : 
    1912            4 : STATIC int RsAllocQpcbWithAttrs(struct RsRdevCb *rdevCb, struct RsQpCb **qpCb, struct RsQpNormWithAttrs *qpNorm)
    1913              : {
    1914              :     int ret;
    1915              : 
    1916            4 :     ret = RsCallocQpcb(1, qpCb);
    1917            4 :     CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
    1918              : 
    1919            4 :     ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
    1920            4 :     if (ret) {
    1921            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    1922            0 :         goto qp_mutex_init_err;
    1923              :     }
    1924              : 
    1925            4 :     ret = pthread_mutex_init(&(*qpCb)->cqeErrInfo.mutex, NULL);
    1926            4 :     if (ret) {
    1927            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    1928            0 :         goto cqe_mutex_init_err;
    1929              :     }
    1930              : 
    1931            4 :     ret = RsQpcbInitWithAttrs(rdevCb, *qpCb, qpNorm);
    1932            4 :     if (ret) {
    1933            0 :         hccp_err("create qp tx rx failed ret %d", ret);
    1934            0 :         goto rs_qpcb_init_err;
    1935              :     }
    1936              : 
    1937            4 :     ret = RsInitMemPool(*qpCb);
    1938            4 :     if (ret) {
    1939            0 :         hccp_err("init mem pool failed ret %d", ret);
    1940            0 :         goto rs_init_mem_err;
    1941              :     }
    1942              : 
    1943            4 :     ret = RsDrvCreateCqWithAttrs(*qpCb, qpNorm->isExt, &qpNorm->extAttrs.cqAttr);
    1944            4 :     if (ret) {
    1945            0 :         hccp_err("create cq failed ret %d", ret);
    1946            0 :         goto create_cq_err;
    1947              :     }
    1948              : 
    1949            4 :     return 0;
    1950              : 
    1951            0 : create_cq_err:
    1952            0 :     RsDeinitMemPool(*qpCb);
    1953              : 
    1954            0 : rs_init_mem_err:
    1955            0 :     RsQpcbDeinit(rdevCb, *qpCb);
    1956              : 
    1957            0 : rs_qpcb_init_err:
    1958            0 :     pthread_mutex_destroy(&(*qpCb)->cqeErrInfo.mutex);
    1959              : 
    1960            0 : cqe_mutex_init_err:
    1961            0 :     pthread_mutex_destroy(&(*qpCb)->qpMutex);
    1962              : 
    1963            0 : qp_mutex_init_err:
    1964            0 :     free(*qpCb);
    1965            0 :     *qpCb = NULL;
    1966              : 
    1967            0 :     return ret;
    1968              : }
    1969              : 
    1970            9 : STATIC int RsQpCheckQpNorm(struct RsQpNormWithAttrs *qpNorm, int *qpMode)
    1971              : {
    1972            9 :     CHK_PRT_RETURN(qpNorm == NULL, hccp_err("qp_norm is NULL!"), -EINVAL);
    1973            8 :     CHK_PRT_RETURN(qpNorm->extAttrs.version != QP_CREATE_WITH_ATTR_VERSION,
    1974              :         hccp_err("attr version[%d] mismatch, expect [%d]", qpNorm->extAttrs.version, QP_CREATE_WITH_ATTR_VERSION),
    1975              :         -EINVAL);
    1976              : 
    1977            7 :     *qpMode = qpNorm->extAttrs.qpMode;
    1978            7 :     if (*qpMode < 0 || *qpMode >= RA_RS_ERR_QP_MODE) {
    1979            1 :         hccp_err("qp_mode[%d] must greater or equal to 0 and less than %d", *qpMode, RA_RS_ERR_QP_MODE);
    1980            1 :         return -EINVAL;
    1981              :     }
    1982              : 
    1983            6 :     if (*qpMode == RA_RS_OP_QP_MODE_EXT) {
    1984            1 :         *qpMode = RA_RS_OP_QP_MODE;
    1985              :     }
    1986              : 
    1987            6 :     qpNorm->extAttrs.qpMode = *qpMode;
    1988            6 :     return 0;
    1989              : }
    1990              : 
    1991              : #ifdef CUSTOM_INTERFACE
    1992            8 : STATIC void RsQpPrepareCqDataPlaneInfo(struct ibv_cq *ibCq, struct AiDataPlaneCq *dataPlaneCq)
    1993              : {
    1994            8 :     struct hns_roce_cq_data_plane_info cqInfo = {0};
    1995              : 
    1996            8 :     (void)RsRoceGetCqDataPlaneInfo(ibCq, &cqInfo);
    1997            8 :     dataPlaneCq->cqn = cqInfo.cqn;
    1998            8 :     dataPlaneCq->bufAddr = cqInfo.buf_addr;
    1999            8 :     dataPlaneCq->cqeSize = cqInfo.cqe_size;
    2000            8 :     dataPlaneCq->depth = cqInfo.depth;
    2001            8 :     dataPlaneCq->headAddr = cqInfo.head_addr;
    2002            8 :     dataPlaneCq->tailAddr = cqInfo.tail_addr;
    2003            8 :     dataPlaneCq->swdbAddr = cqInfo.swdb_addr;
    2004            8 :     dataPlaneCq->dbReg = cqInfo.db_reg;
    2005            8 :     hccp_info("cqn:%u buf_addr:0x%llx cqe_size:%u depth:%u head_addr:0x%llx tail_addr:0x%llx swdb_addr:0x%llx",
    2006              :         dataPlaneCq->cqn, dataPlaneCq->bufAddr, dataPlaneCq->cqeSize, dataPlaneCq->depth, dataPlaneCq->headAddr,
    2007              :         dataPlaneCq->tailAddr, dataPlaneCq->swdbAddr);
    2008            8 : }
    2009              : 
    2010            8 : STATIC void RsQpPrepareWqDataPlaneInfo(struct hns_roce_wq_data_plane_info *wqInfo, struct AiDataPlaneWq *dataPlaneWq)
    2011              : {
    2012            8 :     dataPlaneWq->wqn = wqInfo->wqn;
    2013            8 :     dataPlaneWq->bufAddr = wqInfo->buf_addr;
    2014            8 :     dataPlaneWq->wqebbSize = wqInfo->wqebb_size;
    2015            8 :     dataPlaneWq->depth = wqInfo->depth;
    2016            8 :     dataPlaneWq->headAddr = wqInfo->head_addr;
    2017            8 :     dataPlaneWq->tailAddr = wqInfo->tail_addr;
    2018            8 :     dataPlaneWq->swdbAddr = wqInfo->swdb_addr;
    2019            8 :     dataPlaneWq->dbReg = wqInfo->db_reg;
    2020            8 :     hccp_info("wqn:%u buf_addr:0x%llx wqebb_size:%u depth:%u head_addr:%u tail_addr:%u swdb_addr:0x%llx",
    2021              :         dataPlaneWq->wqn, dataPlaneWq->bufAddr, dataPlaneWq->wqebbSize, dataPlaneWq->depth, dataPlaneWq->headAddr,
    2022              :         dataPlaneWq->tailAddr, dataPlaneWq->swdbAddr);
    2023            8 : }
    2024              : 
    2025            4 : STATIC void RsQpPrepareQpDataPlaneInfo(struct ibv_qp *ibQp, struct AiDataPlaneWq *dataPlaneSq,
    2026              :     struct AiDataPlaneWq *dataPlaneRq)
    2027              : {
    2028            4 :     struct hns_roce_qp_data_plane_info qpInfo = {0};
    2029              : 
    2030            4 :     (void)RsRoceGetQpDataPlaneInfo(ibQp, &qpInfo);
    2031            4 :     RsQpPrepareWqDataPlaneInfo(&qpInfo.sq, dataPlaneSq);
    2032            4 :     RsQpPrepareWqDataPlaneInfo(&qpInfo.rq, dataPlaneRq);
    2033            4 : }
    2034              : 
    2035            4 : STATIC void RsQpPrepareDataPlaneInfo(struct RsQpNormWithAttrs *qpNorm, struct RsQpCb *qpCb,
    2036              :     struct RsQpRespWithAttrs *qpResp)
    2037              : {
    2038              :     // skip to prepare cq data plane info
    2039            4 :     if (qpNorm->extAttrs.dataPlaneFlag.bs.cqCstm != 0) {
    2040            4 :         qpResp->aiScqAddr = (unsigned long long)(uintptr_t)qpCb->ibSendCq;
    2041            4 :         qpResp->aiRcqAddr = (unsigned long long)(uintptr_t)qpCb->ibRecvCq;
    2042            4 :         RsQpPrepareCqDataPlaneInfo(qpCb->ibSendCq, &qpResp->dataPlaneInfo.scq);
    2043            4 :         RsQpPrepareCqDataPlaneInfo(qpCb->ibRecvCq, &qpResp->dataPlaneInfo.rcq);
    2044              :     }
    2045              : 
    2046              :     // skip to prepare qp data plane info
    2047            4 :     if (qpNorm->aiOpSupport != 0) {
    2048            4 :         RsQpPrepareQpDataPlaneInfo(qpCb->ibQp, &qpResp->dataPlaneInfo.sq, &qpResp->dataPlaneInfo.rq);
    2049              :     }
    2050            4 : }
    2051              : #endif
    2052              : 
    2053            4 : STATIC void RsQpPrepareQpResp(struct RsQpNormWithAttrs *qpNorm, struct RsQpCb *qpCb, struct RsQpRespWithAttrs *qpResp)
    2054              : {
    2055            4 :     if (qpNorm->isExp != 0) {
    2056            4 :         qpCb->isExp = RS_IS_EXP;
    2057              :     } else {
    2058            0 :         qpCb->isExp = RS_NOT_EXP;
    2059              :     }
    2060              : 
    2061            4 :     qpResp->aiQpAddr = (unsigned long long)(uintptr_t)qpCb->ibQp;
    2062            4 :     qpResp->sqIndex = (unsigned int)qpCb->sqIndex;
    2063            4 :     qpResp->dbIndex = (unsigned int)qpCb->dbIndex;
    2064            4 :     qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
    2065            4 :     qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
    2066              : 
    2067              : #ifdef CUSTOM_INTERFACE
    2068            4 :     if (RsIsCustomInterfaceSupported()) {
    2069            4 :         RsQpPrepareDataPlaneInfo(qpNorm, qpCb, qpResp);
    2070              :     }
    2071              : #endif
    2072              : 
    2073            4 :     return;
    2074              : }
    2075              : 
    2076           12 : RS_ATTRI_VISI_DEF int RsQpCreateWithAttrs(unsigned int phyId, unsigned int rdevIndex, struct RsQpNormWithAttrs *qpNorm,
    2077              :     struct RsQpRespWithAttrs *qpResp)
    2078              : {
    2079           12 :     struct RsRdevCb *rdevCb = NULL;
    2080           12 :     struct RsQpCb *qpCb = NULL;
    2081              :     int qpMode;
    2082              :     int ret;
    2083              : 
    2084           12 :     RS_QP_PARA_CHECK(phyId);
    2085           10 :     CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
    2086              : 
    2087            9 :     ret = RsQpCheckQpNorm(qpNorm, &qpMode);
    2088            9 :     CHK_PRT_RETURN(ret != 0, hccp_err("check qp mode failed, ret:%d", ret), ret);
    2089              : 
    2090            6 :     ret = RsQpQueryInfo(phyId, rdevIndex, &rdevCb, qpMode);
    2091            6 :     CHK_PRT_RETURN(ret, hccp_err("query qp info failed:%d", ret), ret);
    2092              : 
    2093            4 :     ret = RsAllocQpcbWithAttrs(rdevCb, &qpCb, qpNorm);
    2094            4 :     CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d", ret), ret);
    2095              : 
    2096            4 :     ret = RsDrvQpCreateWithAttrs(qpCb, qpNorm);
    2097            4 :     if (ret) {
    2098            0 :         hccp_err("create drv qp create failed:%d", ret);
    2099            0 :         goto create_qp_err;
    2100              :     }
    2101              : 
    2102            4 :     ret = ibv_req_notify_cq(qpCb->ibSendCq, 0);
    2103            4 :     if (ret) {
    2104            0 :         hccp_err("Couldn't request send CQ notification, ret:%d", ret);
    2105            0 :         ret = -EOPENSRC;
    2106            0 :         goto ret_noritfy_cq;
    2107              :     }
    2108              : 
    2109            4 :     ret = ibv_req_notify_cq(qpCb->ibRecvCq, 0);
    2110            4 :     if (ret) {
    2111            0 :         hccp_err("Couldn't request recv CQ notification, ret:%d", ret);
    2112            0 :         ret = -EOPENSRC;
    2113            0 :         goto ret_noritfy_cq;
    2114              :     }
    2115              : 
    2116            4 :     ret = RsQpNotifyMr(rdevCb, qpCb, &qpResp->qpn); // alloc mr
    2117            4 :     if (ret) {
    2118            0 :         hccp_err("store qp notify mr failed:%d", ret);
    2119            0 :         goto ret_noritfy_cq;
    2120              :     }
    2121              : 
    2122            4 :     RsQpPrepareQpResp(qpNorm, qpCb, qpResp);
    2123              : 
    2124            4 :     return 0;
    2125              : 
    2126            0 : ret_noritfy_cq:
    2127            0 :     RsDrvQpDestroy(qpCb);
    2128              : 
    2129            0 : create_qp_err:
    2130            0 :     RsFreeQpcb(rdevCb, qpCb);
    2131            0 :     return ret;
    2132              : }
    2133              : 
    2134           35 : void RsMrRelease(struct RsQpCb *qpCb)
    2135              : {
    2136           35 :     struct RsMrCb *mrTmp2 = NULL;
    2137           35 :     struct RsMrCb *mrTmp = NULL;
    2138              : 
    2139           35 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
    2140           35 :     RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, &qpCb->mrList, list, struct RsMrCb);
    2141           69 :     for (; (&mrTmp->list) != &qpCb->mrList;
    2142           34 :          mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
    2143           34 :         if (mrTmp->ibMr != qpCb->rdevCb->notifyMr) {
    2144            2 :             (void)RsDrvMrDereg(mrTmp->ibMr);
    2145              :         }
    2146           34 :         RsListDel(&mrTmp->list);
    2147           34 :         free(mrTmp);
    2148           34 :         mrTmp = NULL;
    2149              :     }
    2150              : 
    2151           35 :     RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, &qpCb->remMrList, list, struct RsMrCb);
    2152           66 :     for (; (&mrTmp->list) != &qpCb->remMrList;
    2153           31 :          mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
    2154           31 :         RsListDel(&mrTmp->list);
    2155           31 :         free(mrTmp);
    2156           31 :         mrTmp = NULL;
    2157              :     }
    2158           35 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
    2159           35 : }
    2160              : 
    2161           34 : STATIC void RsQpRelease(struct RsQpCb *qpCb)
    2162              : {
    2163           34 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->rdevCb->rdevMutex);
    2164           34 :     RsListDel(&qpCb->list);
    2165           34 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->rdevCb->rdevMutex);
    2166           34 :     RsIbvAckCqEvents(qpCb->ibSendCq, qpCb->numSendCqEvents);
    2167           34 :     RsIbvAckCqEvents(qpCb->ibRecvCq, qpCb->numRecvCqEvents);
    2168              : 
    2169              :     // dereg mr
    2170           34 :     RsMrRelease(qpCb);
    2171           34 : }
    2172              : 
    2173           34 : RS_ATTRI_VISI_DEF int RsQpDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
    2174              : {
    2175           34 :     struct RsQpCb *qpCb = NULL;
    2176              :     int ret;
    2177              : 
    2178           34 :     RS_QP_PARA_CHECK(phyId);
    2179           34 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    2180           34 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed! qpn %u, ret %d", qpn, ret), ret);
    2181              : 
    2182           32 :     RsQpRelease(qpCb);
    2183              : 
    2184              :     // destroy qp
    2185           32 :     RsDrvQpDestroy(qpCb);
    2186           32 :     RsDrvDestroyCq(qpCb);
    2187           32 :     RsDeinitMemPool(qpCb);
    2188              : 
    2189           32 :     qpCb->rdevCb->qpCnt--;
    2190           32 :     ret = RsQpcbDeinit(qpCb->rdevCb, qpCb);
    2191           32 :     if (ret) {
    2192            0 :         hccp_err("rs_qpcb_deinit failed! ret[%d]", ret);
    2193              :     }
    2194              : 
    2195           32 :     pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
    2196           32 :     pthread_mutex_destroy(&qpCb->qpMutex);
    2197           32 :     hccp_info("qp %d destroy qp, send wr[%u].", qpn, qpCb->sendWrNum);
    2198              : 
    2199           32 :     free(qpCb);
    2200           32 :     qpCb = NULL;
    2201           32 :     return ret;
    2202              : }
    2203              : 
    2204            0 : RS_ATTRI_VISI_DEF int RsQpDestroyWithoutCQ(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
    2205              : {
    2206            0 :     struct RsQpCb *qpCb = NULL;
    2207              :     int ret;
    2208              : 
    2209            0 :     RS_QP_PARA_CHECK(phyId);
    2210            0 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    2211            0 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed! qpn %u, ret %d", qpn, ret), ret);
    2212              : 
    2213            0 :     RsQpRelease(qpCb);
    2214              : 
    2215              :     // destroy qp
    2216            0 :     RsDrvQpDestroy(qpCb);
    2217            0 :     RsDeinitMemPool(qpCb);
    2218              : 
    2219            0 :     qpCb->rdevCb->qpCnt--;
    2220            0 :     ret = RsQpcbDeinit(qpCb->rdevCb, qpCb);
    2221            0 :     if (ret) {
    2222            0 :         hccp_err("rs_qpcb_deinit failed! ret[%d]", ret);
    2223              :     }
    2224              : 
    2225            0 :     pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
    2226            0 :     pthread_mutex_destroy(&qpCb->qpMutex);
    2227            0 :     hccp_info("qp %d destroy qp without cq, send wr[%u].", qpn, qpCb->sendWrNum);
    2228              : 
    2229            0 :     free(qpCb);
    2230            0 :     qpCb = NULL;
    2231            0 :     return ret;
    2232              : }
    2233              : 
    2234           27 : static void RsQpConnectAsyncMr(const struct RsQpCb *qpCb)
    2235              : {
    2236              :     int ret;
    2237           27 :     struct RsMrCb *mrCb = NULL;
    2238           27 :     struct RsMrCb *mrCb2 = NULL;
    2239              : 
    2240           27 :     RS_LIST_GET_HEAD_ENTRY(mrCb, mrCb2, &qpCb->mrList, list, struct RsMrCb);
    2241           53 :     for (; (&mrCb->list) != &qpCb->mrList; mrCb = mrCb2, mrCb2 = list_entry(mrCb2->list.next, struct RsMrCb, list)) {
    2242           26 :         ret = RsMrInfoSync(mrCb);
    2243           26 :         if (ret) {
    2244            0 :             hccp_warn("rs_mr_info_sync unsuccessful, ret:%d", ret);
    2245              :         }
    2246              :     }
    2247           27 : }
    2248              : 
    2249           27 : STATIC void RsQpConnectAsyncQpcbSet(int fd, struct RsQpCb *qpCb)
    2250              : {
    2251              :     int ret;
    2252           27 :     ret = RsSocketSend(fd, &qpCb->qpInfoLo, sizeof(struct RsQpInfo));
    2253           27 :     if (ret == sizeof(struct RsQpInfo)) {
    2254           27 :         qpCb->sendLen += (uint32_t)ret;
    2255           27 :         qpCb->state = RS_QP_STATUS_CONNECTING;
    2256              :     } else {
    2257            0 :         qpCb->state = RS_QP_STATUS_TIMEOUT;
    2258              :     }
    2259           27 : }
    2260              : 
    2261           27 : STATIC void RsQpConnectAsyncLength(int fd, struct RsQpCb *qpCb)
    2262              : {
    2263              :     int ret;
    2264              :     struct RsQpLenInfo msg;
    2265              : 
    2266           27 :     msg.cmd = RS_CMD_LEN_INFO;
    2267           27 :     msg.len = qpCb->sendLen;
    2268              : 
    2269           27 :     ret = RsSocketSend(fd, &msg, sizeof(struct RsQpLenInfo));
    2270           27 :     if (ret != sizeof(struct RsQpLenInfo)) {
    2271            0 :         qpCb->state = RS_QP_STATUS_TIMEOUT;
    2272              :     }
    2273           27 : }
    2274              : 
    2275           32 : static int RsQpConnectAsyncInitPara(struct RsQpConnPara qpConnPara, int fd, struct RsQpCb **qpCb,
    2276              :     struct RsConnInfo **conn)
    2277              : {
    2278              :     int ret;
    2279              : 
    2280           32 :     CHK_PRT_RETURN(qpConnPara.phyId >= RS_MAX_DEV_NUM, hccp_err("param error ! phyId:%u", qpConnPara.phyId), -EINVAL);
    2281              : 
    2282           32 :     CHK_PRT_RETURN(fd < 0, hccp_err("param error ! fd:%d must bigger than 0", fd), -EINVAL);
    2283              : 
    2284           30 :     ret = RsQpn2qpcb(qpConnPara.phyId, qpConnPara.rdevIndex, qpConnPara.qpn, qpCb);
    2285           30 :     CHK_PRT_RETURN(ret, hccp_err("get qpcb failed, qpn %u, ret %d", qpConnPara.qpn, ret), ret);
    2286              : 
    2287           28 :     ret = RsFd2conn(fd, conn);
    2288           28 :     CHK_PRT_RETURN(ret, hccp_err("get conn failed, fd %d, ret %d", fd, ret), ret);
    2289              : 
    2290           28 :     RsGetCurTime(&((*qpCb)->startTime));
    2291           28 :     (*qpCb)->sendLen = 0;
    2292           28 :     (*qpCb)->recvLen = 0;
    2293           28 :     (*qpCb)->expectLen = 0;
    2294           28 :     (*qpCb)->connInfo = *conn;
    2295              : 
    2296           28 :     return 0;
    2297              : }
    2298              : 
    2299            2 : STATIC int RsTypicalQpStateModifytoRtr(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo,
    2300              :     struct TypicalQp *remoteQpInfo)
    2301              : {
    2302            2 :     struct ibv_port_attr portAttr = {0};
    2303            2 :     union ibv_gid remoteInfoGid = {0};
    2304            2 :     struct ibv_qp_attr attr = {0};
    2305              :     int ret;
    2306              : 
    2307            2 :     attr.qp_state = IBV_QPS_RTR;
    2308            2 :     attr.dest_qp_num = remoteQpInfo->qpn;
    2309            2 :     attr.rq_psn = remoteQpInfo->psn;
    2310            2 :     attr.min_rnr_timer = RS_QP_ATTR_MIN_RNR_TIMER;
    2311            2 :     (attr.ah_attr).is_global = 0;
    2312            2 :     (attr.ah_attr).sl = localQpInfo->sl;
    2313            2 :     (attr.ah_attr).src_path_bits = 0;
    2314            2 :     (attr.ah_attr).port_num = qpCb->rdevCb->ibPort;
    2315              : 
    2316            2 :     attr.path_mtu = RsDrvSetMtu(qpCb);
    2317            2 :     CHK_PRT_RETURN(attr.path_mtu < IBV_MTU_1024,
    2318              :         hccp_err("qpn[%u] failed to set mtu, mtu[%d] < [%d]", localQpInfo->qpn, attr.path_mtu, IBV_MTU_1024), -EPERM);
    2319            2 :     if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
    2320            2 :         attr.max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
    2321              :     } else {
    2322            0 :         attr.max_dest_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
    2323              :     }
    2324            2 :     (attr.ah_attr).grh.traffic_class = localQpInfo->tc;
    2325              :     // get gid_idx dynamically to avoid gid_idx changed issue: refresh gid_idx when it changed
    2326            2 :     ret = RsDrvGetGidIndex(qpCb->rdevCb, &portAttr, &qpCb->qpInfoLo.gidIdx);
    2327            2 :     if (ret == 0 && localQpInfo->gidIdx != (uint32_t)qpCb->qpInfoLo.gidIdx) {
    2328            0 :         hccp_warn("qpn[%u] qp_mode[%d] refresh gid_idx[%u] to [%d]", localQpInfo->qpn, qpCb->qpMode,
    2329              :             localQpInfo->gidIdx, qpCb->qpInfoLo.gidIdx);
    2330            0 :         localQpInfo->gidIdx = (uint32_t)qpCb->qpInfoLo.gidIdx;
    2331              :     }
    2332              : 
    2333            2 :     (void)memcpy_s(remoteInfoGid.raw, HCCP_GID_RAW_LEN, remoteQpInfo->gid, HCCP_GID_RAW_LEN);
    2334            2 :     if (remoteInfoGid.global.interface_id) {
    2335            2 :         attr.ah_attr.is_global = 1;
    2336            2 :         attr.ah_attr.grh.hop_limit = 1;
    2337            2 :         attr.ah_attr.grh.dgid = remoteInfoGid;
    2338            2 :         attr.ah_attr.grh.sgid_index = localQpInfo->gidIdx;
    2339              :     }
    2340              : 
    2341            2 :     ret = RsIbvModifyQp(qpCb->ibQp, &attr,
    2342              :         IBV_QP_STATE | IBV_QP_AV | IBV_QP_PATH_MTU | IBV_QP_DEST_QPN | IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC |
    2343              :             IBV_QP_MIN_RNR_TIMER);
    2344            2 :     CHK_PRT_RETURN(ret,
    2345              :         hccp_err("[modifyto_rtr]local_qpn[%u] remote_qpn[%u] ibv_modify_qp failed ret[%d], errno[%d]", localQpInfo->qpn,
    2346              :             remoteQpInfo->qpn, ret, errno),
    2347              :         -EOPENSRC);
    2348            2 :     hccp_info("qp qos attr: qpn[%u] tc[%u] sl[%u]", localQpInfo->qpn, localQpInfo->tc, localQpInfo->sl);
    2349            2 :     return 0;
    2350              : }
    2351              : 
    2352            2 : STATIC int RsTypicalQpStateModifytoRts(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo)
    2353              : {
    2354            2 :     struct ibv_qp_attr attr = {0};
    2355              :     int ret;
    2356              : 
    2357            2 :     attr.qp_state = IBV_QPS_RTS;
    2358            2 :     attr.timeout = (uint8_t)localQpInfo->retryTime;
    2359            2 :     attr.retry_cnt = (uint8_t)localQpInfo->retryCnt;
    2360            2 :     attr.rnr_retry = RS_QP_ATTR_RNR_RETRY;
    2361            2 :     attr.sq_psn = localQpInfo->psn;
    2362            2 :     if (qpCb->rdevCb->rsCb->hccpMode == NETWORK_PEER_ONLINE) {
    2363            2 :         attr.max_rd_atomic = RS_MAX_RD_ATOMIC_NUM_PEER_ONLINE;
    2364              :     } else {
    2365            0 :         attr.max_rd_atomic = RS_MAX_RD_ATOMIC_NUM;
    2366              :     }
    2367              : 
    2368            2 :     ret = RsIbvModifyQp(qpCb->ibQp, &attr,
    2369              :         IBV_QP_STATE | IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY | IBV_QP_SQ_PSN | IBV_QP_MAX_QP_RD_ATOMIC);
    2370            2 :     CHK_PRT_RETURN(ret != 0,
    2371              :         hccp_err("[modifyto_rts]local_qpn[%u] ibv_modify_qp failed ret[%d], errno[%d]", localQpInfo->qpn, ret, errno),
    2372              :         -EOPENSRC);
    2373              : 
    2374            2 :     hccp_info("qp rdma attr: qpn[%u] timeout[%u] retrycnt[%u]", localQpInfo->qpn, localQpInfo->retryTime,
    2375              :         localQpInfo->retryCnt);
    2376            2 :     return 0;
    2377              : }
    2378              : 
    2379            2 : STATIC void RsTypicalQpModifyInfoRelated(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo,
    2380              :     struct TypicalQp *remoteQpInfo)
    2381              : {
    2382            2 :     qpCb->state = RS_QP_STATUS_CONNECTED;
    2383              :     // local qp info related: no need to relate qpn, psn, gid_idx, gid
    2384            2 :     qpCb->qosAttr.tc = (unsigned char)localQpInfo->tc;
    2385            2 :     qpCb->qosAttr.sl = (unsigned char)localQpInfo->sl;
    2386            2 :     qpCb->retryCnt = localQpInfo->retryCnt;
    2387            2 :     qpCb->timeout = localQpInfo->retryTime;
    2388              :     // remote qp info related
    2389            2 :     qpCb->qpInfoRem.qpn = (int)remoteQpInfo->qpn;
    2390            2 :     qpCb->qpInfoRem.psn = (int)remoteQpInfo->psn;
    2391            2 :     qpCb->qpInfoRem.gidIdx = (int)remoteQpInfo->gidIdx;
    2392            2 :     (void)memcpy_s(qpCb->qpInfoRem.gid.raw, HCCP_GID_RAW_LEN, remoteQpInfo->gid, HCCP_GID_RAW_LEN);
    2393            2 : }
    2394              : 
    2395            2 : STATIC void RsTypicalQpModifyExtend(struct RsQpCb *qpCb, struct TypicalQp *localQpInfo, struct TypicalQp *remoteQpInfo)
    2396              : {
    2397            2 :     struct ibv_hyroce_feature output = {0};
    2398            2 :     struct ibv_hyroce_feature input = {0};
    2399            2 :     struct ibv_qp_attr_extend attr = {0};
    2400            2 :     uint32_t needMoreNego = 0;
    2401            2 :     int ret = 0;
    2402              : 
    2403            2 :     if (qpCb->rdevCb->ibCtxEx == NULL) {
    2404            0 :         return;
    2405              :     }
    2406              : 
    2407            2 :     if (localQpInfo->tc != qpCb->qosAttr.tc || localQpInfo->sl != qpCb->qosAttr.sl) {
    2408            2 :         hccp_warn("localQpInfo tc:%u sl:%u is not equal to qpCb tc:%u sl:%u", localQpInfo->tc, localQpInfo->sl,
    2409              :             qpCb->qosAttr.tc, qpCb->qosAttr.sl);
    2410            2 :         return;
    2411              :     }
    2412              : 
    2413            0 :     ret = memcpy_s(&input, sizeof(struct ibv_hyroce_feature), &remoteQpInfo->feature, sizeof(struct HyperFeature));
    2414            0 :     if (ret != 0) {
    2415            0 :         hccp_warn("memcpy_s feature unsuccessful, ret:%d qpn:%u ibv_hyroce_feature len:%zu HyperFeature len:%zu", ret,
    2416              :             qpCb->ibQp->qp_num, sizeof(struct ibv_hyroce_feature), sizeof(struct HyperFeature));
    2417            0 :         return;
    2418              :     }
    2419              : 
    2420            0 :     ret = RsIbvNegoQpHyroceFeature(qpCb->rdevCb->ibCtxEx, qpCb->ibQp, &input, &output, &needMoreNego);
    2421            0 :     if (ret != 0) {
    2422            0 :         hccp_warn("RsIbvNegoQpHyroceFeature unsuccessful, ret:%d qpn:%u errno:%d", ret, qpCb->ibQp->qp_num, errno);
    2423            0 :         return;
    2424              :     }
    2425              : 
    2426            0 :     attr.qp = qpCb->ibQp;
    2427            0 :     (void)memcpy_s(&attr.feature, sizeof(struct ibv_hyroce_feature), &output, sizeof(struct ibv_hyroce_feature));
    2428            0 :     attr.udp_src_port = localQpInfo->udpSport;
    2429            0 :     ret = RsIbvModifyQpExtend(qpCb->rdevCb->ibCtxEx, &attr,
    2430              :         IBV_QP_ATTR_EXTEND_UDP_SRC_PORT | IBV_QP_ATTR_EXTEND_HYROCE_FEATURE);
    2431            0 :     if (ret != 0) {
    2432            0 :         hccp_warn("RsIbvModifyQpExtend unsuccessful, ret:%d qpn:%u errno:%d", ret, qpCb->ibQp->qp_num, errno);
    2433            0 :         return;
    2434              :     }
    2435              : 
    2436            0 :     hccp_dbg("RsIbvModifyQpExtend successful, qpn:%u", qpCb->ibQp->qp_num);
    2437            0 :     return;
    2438              : }
    2439              : 
    2440            2 : STATIC int RsTypicalQueryQpAttr(struct RsQpCb *qpCb, struct TypicalQpAttr *qpAttr)
    2441              : {
    2442            2 :     unsigned int qpAttrMask = HNS_ROCE_AI_QPC_UDPSPN;
    2443            2 :     struct hns_roce_qpc_attr_val qpAttrVal = {0};
    2444            2 :     struct ibv_qp_init_attr initAttr = {0};
    2445            2 :     struct ibv_qp_attr ibvQpAttr = {0};
    2446            2 :     int ret = 0;
    2447              : 
    2448              :     (void)qpAttrMask;
    2449              :     (void)qpAttrVal;
    2450              : #ifdef CUSTOM_INTERFACE
    2451            2 :     if (RsIsCustomInterfaceSupported()) {
    2452            2 :         ret = RsRoceQueryQpc(qpCb->ibQp, &qpAttrVal, qpAttrMask);
    2453            2 :         if (ret != 0) {
    2454            2 :             hccp_warn("qpn:%d query qpc unsuccessful, ret %d", qpCb->qpInfoLo.qpn, ret);
    2455              :         } else {
    2456            0 :             qpCb->udpSport = qpAttrVal.udp_sport;
    2457              :         }
    2458              :     }
    2459              : #endif
    2460              : 
    2461            2 :     ret = RsIbvQueryQp(qpCb->ibQp, &ibvQpAttr, IBV_QP_PATH_MTU, &initAttr);
    2462            2 :     CHK_PRT_RETURN(ret, hccp_err("RsIbvQueryQp failed, ret:%d errno:%d", ret, errno), -EOPENSRC);
    2463              : 
    2464            2 :     if (qpCb->ibQpEx != NULL) {
    2465            0 :         qpAttr->vendorPrivInfo = qpCb->ibQpEx->vendor_priv_info.value;
    2466              :     }
    2467              : 
    2468            2 :     qpAttr->udpSport = qpCb->udpSport;
    2469            2 :     qpAttr->pathMtu = (int)ibvQpAttr.path_mtu;
    2470            2 :     return 0;
    2471              : }
    2472              : 
    2473            2 : RS_ATTRI_VISI_DEF int RsTypicalQpModify(unsigned int phyId, unsigned int rdevIndex, struct TypicalQp localQpInfo,
    2474              :     struct TypicalQp remoteQpInfo, struct TypicalQpAttr *qpAttr)
    2475              : {
    2476            2 :     struct ibv_qp_init_attr initAttr = {0};
    2477            2 :     struct ibv_qp_attr attr = {0};
    2478            2 :     struct RsQpCb *qpCb = NULL;
    2479              :     int ret;
    2480              : 
    2481            2 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("[modify]phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM),
    2482              :         -EINVAL);
    2483              : 
    2484            2 :     CHK_PRT_RETURN(RsQpn2qpcb(phyId, rdevIndex, localQpInfo.qpn, &qpCb),
    2485              :         hccp_err("[modify]rs_qpn2qpcb qpn:%u failed, phyId[%u]", localQpInfo.qpn, phyId), -EACCES);
    2486              : 
    2487            2 :     CHK_PRT_RETURN(qpCb->state == RS_QP_STATUS_CONNECTED,
    2488              :         hccp_info("local_qpn:%u remote_qpn:%u already been connected, no need to modify again", localQpInfo.qpn,
    2489              :             remoteQpInfo.qpn),
    2490              :         0);
    2491              : 
    2492              :     // see ib_modify_qp_is_ok for status modify, only support modify qp from INIT to RTR
    2493            2 :     ret = RsIbvQueryQp(qpCb->ibQp, &attr, IBV_QP_STATE, &initAttr);
    2494            2 :     CHK_PRT_RETURN(ret != 0 || attr.qp_state != IBV_QPS_INIT,
    2495              :         hccp_err("query qpn:%u failed, ret:%d or state:%d != %d", localQpInfo.qpn, ret, attr.qp_state, IBV_QPS_INIT),
    2496              :         -EOPENSRC);
    2497              : 
    2498            2 :     RsTypicalQpModifyExtend(qpCb, &localQpInfo, &remoteQpInfo);
    2499              : 
    2500            2 :     ret = RsTypicalQpStateModifytoRtr(qpCb, &localQpInfo, &remoteQpInfo);
    2501            2 :     CHK_PRT_RETURN(ret != 0,
    2502              :         hccp_err("[modify]local_qpn:%u remote_qpn:%u modify to rtr failed, ret %d", localQpInfo.qpn, remoteQpInfo.qpn,
    2503              :             ret),
    2504              :         ret);
    2505              : 
    2506            2 :     ret = RsTypicalQpStateModifytoRts(qpCb, &localQpInfo);
    2507            2 :     CHK_PRT_RETURN(ret != 0,
    2508              :         hccp_err("[modify]local_qpn:%u remote_qpn:%u modify to rts failed, ret %d", localQpInfo.qpn, remoteQpInfo.qpn,
    2509              :             ret),
    2510              :         ret);
    2511              : 
    2512            2 :     ret = RsTypicalQueryQpAttr(qpCb, qpAttr);
    2513            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsTypicalQueryQpAttr failed, ret %d local_qpn:%u", ret, localQpInfo.qpn), ret);
    2514              : 
    2515            2 :     RsTypicalQpModifyInfoRelated(qpCb, &localQpInfo, &remoteQpInfo);
    2516              : 
    2517            2 :     hccp_info("local_qpn:%u remote_qpn:%u modify succ, udpSport:%u", localQpInfo.qpn, remoteQpInfo.qpn, qpCb->udpSport);
    2518              : 
    2519            2 :     return 0;
    2520              : }
    2521              : 
    2522            2 : STATIC int RsQpStateBatchModifytoPause(struct RsQpCb *qpCb)
    2523              : {
    2524              :     int ret;
    2525              : 
    2526            2 :     ret = RsDrvQpStateModifytoReset(qpCb);
    2527            2 :     CHK_PRT_RETURN(ret, hccp_err("qp modify to reset failed, ret %d", ret), ret);
    2528              : 
    2529            2 :     hccp_info("local qpn[%d] remote qpn[%d] modify to pause succ", qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn);
    2530            2 :     return 0;
    2531              : }
    2532              : 
    2533            2 : STATIC int RsQpStateBatchModifytoConnected(struct RsQpCb *qpCb)
    2534              : {
    2535              :     struct ibv_qp_attr attr;
    2536              :     int ret;
    2537              : 
    2538            2 :     ret = memset_s(&attr, sizeof(struct ibv_qp_attr), 0, sizeof(struct ibv_qp_attr));
    2539            2 :     CHK_PRT_RETURN(ret, hccp_err("memset_s attr failed ret %d", ret), -ESAFEFUNC);
    2540              : 
    2541            2 :     ret = RsDrvQpStateModifytoInit(qpCb, &attr);
    2542            2 :     CHK_PRT_RETURN(ret, hccp_err("qp modify to init failed, ret %d", ret), ret);
    2543            2 :     ret = RsDrvQpStateModifytoRtr(qpCb, &attr);
    2544            2 :     CHK_PRT_RETURN(ret, hccp_err("qp modify to rtr failed, ret %d", ret), ret);
    2545            2 :     ret = RsDrvQpStateModifytoRts(qpCb, &attr);
    2546            2 :     CHK_PRT_RETURN(ret, hccp_err("qp modify to rts failed, ret %d", ret), ret);
    2547              : 
    2548            2 :     hccp_info("local qpn[%d] remote qpn[%d] modify to rts succ", qpCb->qpInfoLo.qpn, qpCb->qpInfoRem.qpn);
    2549            2 :     return 0;
    2550              : }
    2551              : 
    2552            3 : RS_ATTRI_VISI_DEF int RsQpBatchModify(unsigned int phyId, unsigned int rdevIndex, int status, int qpn[], int qpnNum)
    2553              : {
    2554            3 :     struct RsQpCb *qpCb = NULL;
    2555              :     int ret;
    2556              :     int i;
    2557              : 
    2558            3 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("[modify]phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM),
    2559              :         -EINVAL);
    2560              : 
    2561            7 :     for (i = 0; i < qpnNum; i++) {
    2562            5 :         CHK_PRT_RETURN(RsQpn2qpcb(phyId, rdevIndex, (uint32_t)qpn[i], &qpCb),
    2563              :             hccp_err("[modify]rs_qpn2qpcb failed, phyId[%u]", phyId), -EACCES);
    2564              : 
    2565              :         /*
    2566              :          * see ib_modify_qp_is_ok for status modify
    2567              :          * only support modify qp from STATUS_PAUSE(RESET) to STATUS_CONNECTED(INIT)
    2568              :          */
    2569            5 :         if (status == RS_QP_STATUS_CONNECTED && qpCb->state == RS_QP_STATUS_PAUSE) {
    2570            2 :             ret = RsQpStateBatchModifytoConnected(qpCb);
    2571            2 :             CHK_PRT_RETURN(ret,
    2572              :                 hccp_err("modify_qp qpn[%d]:%d to connected failed, ret[%d] phyId[%u]", i, qpn[i], ret, phyId), ret);
    2573            3 :         } else if (status == RS_QP_STATUS_PAUSE) {
    2574            2 :             ret = RsQpStateBatchModifytoPause(qpCb);
    2575            2 :             CHK_PRT_RETURN(ret,
    2576              :                 hccp_err("modify_qp qpn[%d]:%d to pause failed, ret[%d] phyId[%u]", i, qpn[i], ret, phyId), ret);
    2577              :         } else {
    2578            1 :             hccp_err("modify_qp qpn[%d]:%d failed, not support to modify status[%d] to status[%d], phyId[%u]", i,
    2579              :                 qpn[i], qpCb->state, status, phyId);
    2580            1 :             return -EINVAL;
    2581              :         }
    2582              : 
    2583            4 :         qpCb->state = status;
    2584              :     }
    2585              : 
    2586            2 :     return 0;
    2587              : }
    2588              : 
    2589            2 : RS_ATTRI_VISI_DEF int RsSetQpLbValue(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, int lbValue)
    2590              : {
    2591            2 :     struct RsQpCb *qpCb = NULL;
    2592            2 :     int ret = 0;
    2593              : 
    2594            2 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    2595            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQpn2qpcb failed ret:%d", ret), ret);
    2596              : 
    2597            1 :     return RsRoceSetQpLbValue(qpCb->ibQp, lbValue);
    2598              : }
    2599              : 
    2600            3 : RS_ATTRI_VISI_DEF int RsGetQpLbValue(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, int *lbValue)
    2601              : {
    2602            3 :     struct RsQpCb *qpCb = NULL;
    2603            3 :     int ret = 0;
    2604              : 
    2605            3 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    2606            3 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQpn2qpcb failed ret:%d", ret), ret);
    2607              : 
    2608            2 :     return RsRoceGetQpLbValue(qpCb->ibQp, lbValue);
    2609              : }
    2610              : 
    2611           32 : RS_ATTRI_VISI_DEF int RsQpConnectAsync(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, int fd)
    2612              : {
    2613              :     int ret;
    2614           32 :     struct RsQpCb *qpCb = NULL;
    2615           32 :     struct RsConnInfo *conn = NULL;
    2616              :     struct RsQpConnPara qpConnPara;
    2617           32 :     hccp_info("qp:%d, fd:%d", qpn, fd);
    2618              : 
    2619           32 :     qpConnPara.phyId = phyId;
    2620           32 :     qpConnPara.rdevIndex = rdevIndex;
    2621           32 :     qpConnPara.qpn = qpn;
    2622           32 :     ret = RsQpConnectAsyncInitPara(qpConnPara, fd, &qpCb, &conn);
    2623           32 :     CHK_PRT_RETURN(ret, hccp_err("rs_qp_connect_async_init_para failed, qpn %u, ret %d", qpn, ret), ret);
    2624              : 
    2625           28 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
    2626              : 
    2627           28 :     if (qpCb->state == RS_QP_STATUS_REM_FD_CLOSE) {
    2628            0 :         hccp_warn("remote qp fd close, can not use it anymore!");
    2629            0 :         RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
    2630            0 :         return -EFAULT;
    2631              :     }
    2632              : 
    2633           28 :     if ((qpCb->state == RS_QP_STATUS_CONNECTED) || (qpCb->state == RS_QP_STATUS_CONNECTING)) {
    2634            1 :         hccp_warn("qp %d has already sync! state[%d]", qpCb->qpInfoLo.qpn, qpCb->state);
    2635            1 :         RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
    2636            1 :         return -EEXIST;
    2637              :     }
    2638              : 
    2639           27 :     RsQpConnectAsyncQpcbSet(fd, qpCb);
    2640              : 
    2641           27 :     hccp_info("after socket fd %d send QP %u, chipId %u, state:%d!", fd, qpn, qpCb->rdevCb->rsCb->chipId, qpCb->state);
    2642              : 
    2643           27 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
    2644              : 
    2645           27 :     RsQpMrRecvHandle(fd, qpCb);
    2646              : 
    2647           27 :     RsQpConnectAsyncMr(qpCb);
    2648              : 
    2649           27 :     RsQpConnectAsyncLength(fd, qpCb);
    2650              : 
    2651           27 :     hccp_info("QP %d async done, state:%d!", qpn, qpCb->state);
    2652              : 
    2653           27 :     return 0;
    2654              : }
    2655              : 
    2656            1 : RS_ATTRI_VISI_DEF int RsGetQpStatus(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
    2657              :     struct RsQpStatusInfo *qpInfo)
    2658              : {
    2659            1 :     unsigned int qpAttrMask = HNS_ROCE_AI_QPC_UDPSPN;
    2660            1 :     struct hns_roce_qpc_attr_val qpAttrVal = {0};
    2661            1 :     struct RsQpCb *qpCb = NULL;
    2662              :     int ret;
    2663              : 
    2664              :     (void)qpAttrMask;
    2665              :     (void)qpAttrVal;
    2666            1 :     CHK_PRT_RETURN(qpInfo == NULL, hccp_err("param error, qpInfo is NULL"), -EINVAL);
    2667              : 
    2668            1 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
    2669              : 
    2670            1 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    2671            1 :     CHK_PRT_RETURN(ret, hccp_err("get qp cb failed, qpn:%u, ret %d", qpn, ret), ret);
    2672              : 
    2673              :     // qp state is CONNECTED, no need to handle
    2674            1 :     if (qpCb->state == RS_QP_STATUS_CONNECTED) {
    2675            1 :         goto update_qp_cb;
    2676              :     }
    2677              : 
    2678              :     // modify state to CONNECTED
    2679            0 :     if (qpCb->expectLen == qpCb->recvLen - sizeof(struct RsQpLenInfo)) {
    2680            0 :         qpCb->state = RS_QP_STATUS_CONNECTED;
    2681              :     } else {
    2682            0 :         RsQpMrRecvHandle(qpCb->connInfo->connfd, qpCb);
    2683            0 :         goto out;
    2684              :     }
    2685              : 
    2686            1 : update_qp_cb:
    2687              : #ifdef CUSTOM_INTERFACE
    2688            1 :     if (RsIsCustomInterfaceSupported()) {
    2689            1 :         ret = RsRoceQueryQpc(qpCb->ibQp, &qpAttrVal, qpAttrMask);
    2690            1 :         if (ret != 0) {
    2691            1 :             hccp_warn("qpn:%d query qpc unsuccessful, ret %d", qpCb->qpInfoLo.qpn, ret);
    2692              :         } else {
    2693            0 :             qpCb->udpSport = qpAttrVal.udp_sport;
    2694              :         }
    2695              :     }
    2696              : #endif
    2697            0 : out:
    2698            1 :     hccp_dbg("qp:%u, state:%d, udpSport:%u", qpn, qpCb->state, qpCb->udpSport);
    2699            1 :     qpInfo->status = qpCb->state;
    2700            1 :     qpInfo->udpSport = qpCb->udpSport;
    2701              : 
    2702            1 :     return 0;
    2703              : }
    2704              : 
    2705            3 : RS_ATTRI_VISI_DEF int RsGetQpContext(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn, void **qp,
    2706              :     void **sendCq, void **recvCq)
    2707              : {
    2708              :     int ret;
    2709            3 :     struct RsQpCb *qpCb = NULL;
    2710              : 
    2711            3 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("phyId:%u >= [%d], is invalid", phyId, RS_MAX_DEV_NUM), -EINVAL);
    2712              : 
    2713            2 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    2714            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_qpn2qpcb failed ret[%d]", ret), ret);
    2715              : 
    2716            1 :     *qp = qpCb->ibQp;
    2717            1 :     *sendCq = qpCb->ibSendCq;
    2718            1 :     *recvCq = qpCb->ibRecvCq;
    2719              : 
    2720            1 :     hccp_dbg("qpn[%u] succ", qpn);
    2721              : 
    2722            1 :     return 0;
    2723              : }
    2724              : 
    2725           26 : int RsQueryRdevCb(unsigned int phyId, unsigned int rdevIndex, struct RsRdevCb **rdevCb)
    2726              : {
    2727              :     int ret;
    2728              :     unsigned int chipId;
    2729           26 :     struct rs_cb *rsCb = NULL;
    2730              : 
    2731           26 :     RS_QP_PARA_CHECK(phyId);
    2732              : 
    2733           24 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    2734           24 :     CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb phyId[%u] invalid, ret:%d", phyId, ret), ret);
    2735              : 
    2736           23 :     ret = RsDev2rscb(chipId, &rsCb, false);
    2737           23 :     CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb get rs_cb failed, ret:%d", ret), -ENODEV);
    2738              : 
    2739           23 :     ret = RsGetRdevCb(rsCb, rdevIndex, rdevCb);
    2740           23 :     CHK_PRT_RETURN(ret, hccp_err("rs_get_rdev_cb failed! ret:%d, rdevIndex:%u", ret, rdevIndex), ret);
    2741              : 
    2742           23 :     return 0;
    2743              : }
    2744              : 
    2745            3 : RS_ATTRI_VISI_DEF int RsGetLbMax(unsigned int phyId, unsigned int rdevIndex, int *lbMax)
    2746              : {
    2747            3 :     struct RsRdevCb *rdevCb = NULL;
    2748            3 :     int ret = 0;
    2749              : 
    2750            3 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
    2751            3 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQueryRdevCb phyId:%u rdev_index:%u ret:%d", phyId, rdevIndex, ret), ret);
    2752              : 
    2753            2 :     return RsRoceGetQpNum(rdevCb->ibCtx, lbMax);
    2754              : }
    2755              : 
    2756            3 : STATIC int RsBuildUpQpcb(struct RsCqContext *cqContext, struct ibv_qp_init_attr *qpInitAttr, struct RsQpCb **qpCb)
    2757              : {
    2758              :     int ret;
    2759              : 
    2760            3 :     ret = RsCallocQpcb(1, qpCb);
    2761            3 :     CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
    2762              : 
    2763            3 :     ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
    2764            3 :     if (ret) {
    2765            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    2766            0 :         goto pthread_mutex_init_err;
    2767              :     }
    2768              : 
    2769            3 :     (*qpCb)->rdevCb = cqContext->rdevCb;
    2770            3 :     RS_INIT_LIST_HEAD(&(*qpCb)->mrList);
    2771            3 :     RS_INIT_LIST_HEAD(&(*qpCb)->remMrList);
    2772              : 
    2773            3 :     (*qpCb)->eqNum = cqContext->eqNum;
    2774            3 :     (*qpCb)->channel = cqContext->channel;
    2775            3 :     (*qpCb)->ibSendCq = cqContext->ibSendCq;
    2776            3 :     (*qpCb)->ibRecvCq = cqContext->ibRecvCq;
    2777            3 :     (*qpCb)->sendEvent = cqContext->sendEvent;
    2778            3 :     (*qpCb)->recvEvent = cqContext->recvEvent;
    2779            3 :     (*qpCb)->numRecvCqEvents = 0;
    2780            3 :     (*qpCb)->numSendCqEvents = 0;
    2781            3 :     (*qpCb)->srqContext = cqContext->srqContext;
    2782            3 :     (*qpCb)->state = RS_QP_STATUS_DISCONNECT;
    2783            3 :     (*qpCb)->ibPd = cqContext->rdevCb->ibPd;
    2784            3 :     (*qpCb)->txDepth = qpInitAttr->cap.max_send_wr;
    2785            3 :     (*qpCb)->rxDepth = qpInitAttr->cap.max_recv_wr;
    2786            3 :     (*qpCb)->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
    2787            3 :     (*qpCb)->qosAttr.sl = RS_ROCE_4_SL;
    2788            3 :     (*qpCb)->timeout = RS_QP_ATTR_TIMEOUT;
    2789            3 :     (*qpCb)->retryCnt = RS_QP_ATTR_RETRY_CNT;
    2790              : 
    2791            3 :     return 0;
    2792              : 
    2793            0 : pthread_mutex_init_err:
    2794            0 :     free(*qpCb);
    2795            0 :     (*qpCb) = NULL;
    2796            0 :     return ret;
    2797              : }
    2798              : 
    2799            6 : RS_ATTRI_VISI_DEF int RsCreateCqEvent(struct RsCqContext *cqContext, struct CqAttr *attr)
    2800              : {
    2801              :     int ret;
    2802            6 :     cqContext->channel = RsIbvCreateCompChannel(cqContext->rdevCb->ibCtx);
    2803              : 
    2804            6 :     if (cqContext->channel == NULL) {
    2805            1 :         hccp_err("ibv_create_comp_channel failed, ret %d, errno(%d)", -EINVAL, errno);
    2806            1 :         return -EINVAL;
    2807              :     }
    2808              : 
    2809            5 :     hccp_info("comp channel fd[%d].", cqContext->channel->fd);
    2810            5 :     ret = RsEpollCtl(cqContext->rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_ADD, cqContext->channel->fd,
    2811              :         EPOLLIN | EPOLLRDHUP);
    2812              : #ifndef CA_CONFIG_LLT
    2813              :     if (ret) {
    2814              :         hccp_err("add channel fd failed ret %d", ret);
    2815              :         goto rs_cq_epoll_ctl_err;
    2816              :     }
    2817              : #endif
    2818              : 
    2819            5 :     ret = RsDrvCreateCqEvent(cqContext, attr);
    2820            5 :     if (ret) {
    2821            0 :         hccp_err("create drv cq event failed:%d", ret);
    2822            0 :         goto rs_cq_create_err;
    2823              :     }
    2824              : 
    2825            5 :     return ret;
    2826            0 : rs_cq_create_err:
    2827            0 :     ret = RsEpollCtl(cqContext->rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_DEL, cqContext->channel->fd,
    2828              :         EPOLLIN | EPOLLRDHUP);
    2829              : #ifndef CA_CONFIG_LLT
    2830              :     if (ret) {
    2831              :         hccp_err("del channel fd failed ret %d", ret);
    2832              :     }
    2833              : #endif
    2834            0 : rs_cq_epoll_ctl_err:
    2835            0 :     if (cqContext->channel != NULL) {
    2836            0 :         RsIbvDestroyCompChannel(cqContext->channel);
    2837            0 :         cqContext->channel = NULL;
    2838              :     }
    2839            0 :     return ret;
    2840              : }
    2841              : 
    2842            5 : RS_ATTRI_VISI_DEF int RsCqCreate(unsigned int phyId, unsigned int rdevIndex, struct CqAttr *attr)
    2843              : {
    2844              :     int ret;
    2845            5 :     struct RsRdevCb *rdevCb = NULL;
    2846            5 :     struct RsCqContext *cqContext = NULL;
    2847              : 
    2848            5 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
    2849            5 :     if (ret) {
    2850            0 :         hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret);
    2851            0 :         return ret;
    2852              :     }
    2853              : 
    2854            5 :     cqContext = calloc(1, sizeof(struct RsCqContext));
    2855            5 :     if (cqContext == NULL) {
    2856            0 :         return -ENOMEM;
    2857              :     }
    2858            5 :     cqContext->rdevCb = rdevCb;
    2859            5 :     cqContext->eqNum = 0;
    2860            5 :     if (attr->sendChannel == NULL && attr->recvChannel == NULL) {
    2861            3 :         if (*attr->ibSendCq == NULL && *attr->ibRecvCq != NULL) {
    2862              :             // 只创建sq cq
    2863            1 :             cqContext->cqCreateMode = RS_SQ_CQ_CREATE;
    2864            1 :             cqContext->ibRecvCq = *attr->ibRecvCq;
    2865            1 :             cqContext->srqContext = attr->srqContext;
    2866              :         } else {
    2867              :             // 创建sq&rq cq
    2868            2 :             cqContext->cqCreateMode = RS_NORMAL_CQ_CREATE;
    2869              :         }
    2870            3 :         ret = RsCreateCqEvent(cqContext, attr);
    2871            3 :         if (ret) {
    2872            0 :             hccp_err("create cq event failed:%d", ret);
    2873            0 :             goto rs_cq_create_err;
    2874              :         }
    2875            2 :     } else if (attr->sendChannel != NULL && attr->recvChannel != NULL) {
    2876              :         // 使用输入comp channel创建sq&rq
    2877            1 :         ret = RsDrvCreateCqWithChannel(cqContext, attr);
    2878            1 :         if (ret) {
    2879            0 :             hccp_err("create drv cq with channel failed:%d", ret);
    2880            0 :             goto rs_cq_create_err;
    2881              :         }
    2882              :     } else {
    2883            1 :         hccp_err("rs create cq failed, sendChannel or recvChannel is NULL.");
    2884            1 :         ret = -EPERM;
    2885            1 :         goto rs_cq_create_err;
    2886              :     }
    2887              : 
    2888            4 :     *attr->qpContext = cqContext;
    2889            4 :     return 0;
    2890              : 
    2891            1 : rs_cq_create_err:
    2892            1 :     free(cqContext);
    2893            1 :     cqContext = NULL;
    2894              : 
    2895            1 :     return ret;
    2896              : }
    2897              : 
    2898            0 : RS_ATTRI_VISI_DEF int RsTypicalCqCreate(unsigned int phyId, unsigned int rdevIndex, unsigned int cqDepth,
    2899              :     unsigned int *cqn)
    2900              : {
    2901              :     struct RsTypicalCqEntry *entry;
    2902              :     struct RsTypicalCqEntry *tmp;
    2903              :     int ret;
    2904            0 :     struct RsRdevCb *rdevCb = NULL;
    2905            0 :     struct ibv_cq *ibCq = NULL;
    2906              :     struct rdma_lite_device_cq_attr deviceCqAttr;
    2907              : 
    2908            0 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
    2909            0 :     if (ret) {
    2910            0 :         hccp_err("rs_query_rdev_cb phyId[%u] rdevIndex[%u], ret %d", phyId, rdevIndex, ret);
    2911            0 :         return ret;
    2912              :     }
    2913              : 
    2914            0 :     ret = RsDrvTypicalCqCreate(rdevCb, cqDepth, cqn, &ibCq, &deviceCqAttr);
    2915            0 :     if (ret) {
    2916            0 :         hccp_err("rs_drv_typical_cq_create failed, cqDepth[%u] ret[%d]", cqDepth, ret);
    2917            0 :         return ret;
    2918              :     }
    2919              : 
    2920            0 :     pthread_mutex_lock(&gRsTypicalCqMutex);
    2921            0 :     if (gRsTypicalCqList.next == NULL) {
    2922            0 :         RS_INIT_LIST_HEAD(&gRsTypicalCqList);
    2923              :     }
    2924              : 
    2925            0 :     RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
    2926            0 :     for (; &tmp->list != &gRsTypicalCqList;
    2927            0 :          tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
    2928            0 :         if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == *cqn) {
    2929            0 :             tmp->ibCq = ibCq;
    2930            0 :             tmp->deviceCqAttr = deviceCqAttr;
    2931            0 :             pthread_mutex_unlock(&gRsTypicalCqMutex);
    2932            0 :             hccp_info("RsTypicalCqCreate updated: phyId[%u] rdevIndex[%u] cqn[%u] cqDepth[%u]", phyId, rdevIndex, *cqn,
    2933              :                 cqDepth);
    2934            0 :             return 0;
    2935              :         }
    2936              :     }
    2937              : 
    2938            0 :     entry = calloc(1, sizeof(struct RsTypicalCqEntry));
    2939            0 :     if (entry == NULL) {
    2940            0 :         pthread_mutex_unlock(&gRsTypicalCqMutex);
    2941            0 :         hccp_err("RsTypicalCqCreate calloc failed, cqn[%u]", *cqn);
    2942            0 :         return -ENOMEM;
    2943              :     }
    2944            0 :     entry->phyId = phyId;
    2945            0 :     entry->rdevIndex = rdevIndex;
    2946            0 :     entry->cqn = *cqn;
    2947            0 :     entry->ibCq = ibCq;
    2948            0 :     entry->deviceCqAttr = deviceCqAttr;
    2949            0 :     RsListAddTail(&entry->list, &gRsTypicalCqList);
    2950            0 :     pthread_mutex_unlock(&gRsTypicalCqMutex);
    2951              : 
    2952            0 :     hccp_info("RsTypicalCqCreate success: phyId[%u] rdevIndex[%u] cqn[%u] cqDepth[%u]", phyId, rdevIndex, *cqn,
    2953              :         cqDepth);
    2954              : 
    2955            0 :     return 0;
    2956              : }
    2957              : 
    2958            0 : RS_ATTRI_VISI_DEF int RsTypicalCqDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int cqn)
    2959              : {
    2960              :     struct RsTypicalCqEntry *entry;
    2961              :     struct RsTypicalCqEntry *tmp;
    2962              :     int ret;
    2963              : 
    2964            0 :     pthread_mutex_lock(&gRsTypicalCqMutex);
    2965            0 :     if (gRsTypicalCqList.next == NULL) {
    2966            0 :         pthread_mutex_unlock(&gRsTypicalCqMutex);
    2967            0 :         hccp_err("rs_typical_cq_destroy: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
    2968            0 :         return -EINVAL;
    2969              :     }
    2970              : 
    2971            0 :     RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
    2972            0 :     for (; &tmp->list != &gRsTypicalCqList;
    2973            0 :          tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
    2974            0 :         if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == cqn) {
    2975            0 :             RsListDel(&tmp->list);
    2976            0 :             pthread_mutex_unlock(&gRsTypicalCqMutex);
    2977              : 
    2978            0 :             if (tmp->ibCq != NULL) {
    2979            0 :                 ret = RsIbvDestroyCq(tmp->ibCq);
    2980            0 :                 if (ret) {
    2981            0 :                     hccp_err("rs_ibv_destroy_cq failed cqn[%u] ret[%d]", cqn, ret);
    2982            0 :                     free(tmp);
    2983            0 :                     return ret;
    2984              :                 }
    2985              :             }
    2986            0 :             free(tmp);
    2987            0 :             hccp_info("RsTypicalCqDestroy success: phyId[%u] rdevIndex[%u] cqn[%u]", phyId, rdevIndex, cqn);
    2988            0 :             return 0;
    2989              :         }
    2990              :     }
    2991            0 :     pthread_mutex_unlock(&gRsTypicalCqMutex);
    2992              : 
    2993            0 :     hccp_err("rs_typical_cq_destroy: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
    2994            0 :     return -EINVAL;
    2995              : }
    2996              : 
    2997            0 : RS_ATTRI_VISI_DEF int RsGetLiteCqAttr(unsigned int phyId, unsigned int rdevIndex, unsigned int cqn,
    2998              :     struct rdma_lite_device_cq_attr *deviceCqAttr)
    2999              : {
    3000              :     struct RsTypicalCqEntry *entry;
    3001              :     struct RsTypicalCqEntry *tmp;
    3002              :     int ret;
    3003              : 
    3004            0 :     RS_CHECK_POINTER_NULL_RETURN_INT(deviceCqAttr);
    3005              : 
    3006            0 :     pthread_mutex_lock(&gRsTypicalCqMutex);
    3007            0 :     if (gRsTypicalCqList.next == NULL) {
    3008            0 :         pthread_mutex_unlock(&gRsTypicalCqMutex);
    3009            0 :         hccp_err("rs_get_lite_cq_attr: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
    3010            0 :         return -EINVAL;
    3011              :     }
    3012              : 
    3013            0 :     RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
    3014            0 :     for (; &tmp->list != &gRsTypicalCqList;
    3015            0 :          tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
    3016            0 :         if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == cqn) {
    3017            0 :             ret = memcpy_s(deviceCqAttr, sizeof(*deviceCqAttr), &tmp->deviceCqAttr, sizeof(tmp->deviceCqAttr));
    3018            0 :             pthread_mutex_unlock(&gRsTypicalCqMutex);
    3019            0 :             if (ret) {
    3020            0 :                 hccp_err("memcpy_s failed, ret:%d", ret);
    3021            0 :                 return ret;
    3022              :             }
    3023            0 :             hccp_info("RsGetLiteCqAttr success: cqn[%u] depth[%u]", cqn, deviceCqAttr->depth);
    3024            0 :             return 0;
    3025              :         }
    3026              :     }
    3027            0 :     pthread_mutex_unlock(&gRsTypicalCqMutex);
    3028              : 
    3029            0 :     hccp_err("rs_get_lite_cq_attr: cqn[%u] not found phyId[%u] rdevIndex[%u]", cqn, phyId, rdevIndex);
    3030            0 :     return -EINVAL;
    3031              : }
    3032              : 
    3033            0 : RS_ATTRI_VISI_DEF int RsQpCreateWithCQWithAttrs(unsigned int phyId, unsigned int rdevIndex, unsigned int sendCqn,
    3034              :     unsigned int recvCqn, struct RsQpNormWithAttrs *qpNorm, struct RsQpRespWithAttrs *qpResp)
    3035              : {
    3036              :     struct RsTypicalCqEntry *entry;
    3037              :     struct RsTypicalCqEntry *tmp;
    3038            0 :     struct RsRdevCb *rdevCb = NULL;
    3039            0 :     struct RsQpCb *qpCb = NULL;
    3040            0 :     struct ibv_cq *sendIbCq = NULL;
    3041            0 :     struct ibv_cq *recvIbCq = NULL;
    3042              :     struct rdma_lite_device_cq_attr sendDeviceCqAttr;
    3043              :     struct rdma_lite_device_cq_attr recvDeviceCqAttr;
    3044              :     int qpMode;
    3045              :     int ret;
    3046            0 :     bool sendFound = false;
    3047            0 :     bool recvFound = false;
    3048              : 
    3049            0 :     RS_QP_PARA_CHECK(phyId);
    3050            0 :     CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
    3051              : 
    3052            0 :     ret = RsQpCheckQpNorm(qpNorm, &qpMode);
    3053            0 :     CHK_PRT_RETURN(ret != 0, hccp_err("check qp mode failed, ret:%d", ret), ret);
    3054              : 
    3055            0 :     ret = RsQpQueryInfo(phyId, rdevIndex, &rdevCb, qpMode);
    3056            0 :     CHK_PRT_RETURN(ret, hccp_err("query qp info failed:%d", ret), ret);
    3057              : 
    3058            0 :     pthread_mutex_lock(&gRsTypicalCqMutex);
    3059            0 :     if (gRsTypicalCqList.next != NULL) {
    3060            0 :         RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
    3061            0 :         for (; &tmp->list != &gRsTypicalCqList;
    3062            0 :              tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
    3063            0 :             if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == sendCqn) {
    3064            0 :                 sendIbCq = tmp->ibCq;
    3065            0 :                 sendDeviceCqAttr = tmp->deviceCqAttr;
    3066            0 :                 sendFound = true;
    3067            0 :                 break;
    3068              :             }
    3069              :         }
    3070              :     }
    3071            0 :     pthread_mutex_unlock(&gRsTypicalCqMutex);
    3072            0 :     CHK_PRT_RETURN(!sendFound,
    3073              :         hccp_err("send cq not found: sendCqn[%u] phyId[%u] rdevIndex[%u]", sendCqn, phyId, rdevIndex), -EINVAL);
    3074              : 
    3075            0 :     pthread_mutex_lock(&gRsTypicalCqMutex);
    3076            0 :     if (gRsTypicalCqList.next != NULL) {
    3077            0 :         RS_LIST_GET_HEAD_ENTRY(tmp, entry, &gRsTypicalCqList, list, struct RsTypicalCqEntry);
    3078            0 :         for (; &tmp->list != &gRsTypicalCqList;
    3079            0 :              tmp = entry, entry = list_entry(entry->list.next, struct RsTypicalCqEntry, list)) {
    3080            0 :             if (tmp->phyId == phyId && tmp->rdevIndex == rdevIndex && tmp->cqn == recvCqn) {
    3081            0 :                 recvIbCq = tmp->ibCq;
    3082            0 :                 recvDeviceCqAttr = tmp->deviceCqAttr;
    3083            0 :                 recvFound = true;
    3084            0 :                 break;
    3085              :             }
    3086              :         }
    3087              :     }
    3088            0 :     pthread_mutex_unlock(&gRsTypicalCqMutex);
    3089            0 :     CHK_PRT_RETURN(!recvFound,
    3090              :         hccp_err("recv cq not found: recvCqn[%u] phyId[%u] rdevIndex[%u]", recvCqn, phyId, rdevIndex), -EINVAL);
    3091              : 
    3092            0 :     ret = RsCallocQpcb(1, &qpCb);
    3093            0 :     CHK_PRT_RETURN(ret, hccp_err("alloc mem for qp_cb failed, ret:%d errno:%d", ret, errno), -ENOMEM);
    3094              : 
    3095            0 :     ret = pthread_mutex_init(&qpCb->qpMutex, NULL);
    3096            0 :     if (ret) {
    3097            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    3098            0 :         goto qp_mutex_init_err;
    3099              :     }
    3100              : 
    3101            0 :     ret = pthread_mutex_init(&qpCb->cqeErrInfo.mutex, NULL);
    3102            0 :     if (ret) {
    3103            0 :         hccp_err("pthread_mutex_init failed, ret %d", ret);
    3104            0 :         goto cqe_mutex_init_err;
    3105              :     }
    3106              : 
    3107            0 :     ret = RsQpcbInitWithAttrs(rdevCb, qpCb, qpNorm);
    3108            0 :     if (ret) {
    3109            0 :         hccp_err("create qp tx rx failed ret %d", ret);
    3110            0 :         goto rs_qpcb_init_err;
    3111              :     }
    3112              : 
    3113            0 :     ret = RsInitMemPool(qpCb);
    3114            0 :     if (ret) {
    3115            0 :         hccp_err("init mem pool failed ret %d", ret);
    3116            0 :         goto rs_init_mem_err;
    3117              :     }
    3118              : 
    3119              :     // Assign pre-existing CQs (instead of RsDrvCreateCqWithAttrs)
    3120            0 :     qpCb->ibSendCq = sendIbCq;
    3121            0 :     qpCb->ibRecvCq = recvIbCq;
    3122            0 :     qpCb->qpResp.sendCqData = sendDeviceCqAttr;
    3123            0 :     qpCb->qpResp.recvCqData = recvDeviceCqAttr;
    3124            0 :     qpCb->sendCqDepth = sendDeviceCqAttr.depth;
    3125            0 :     qpCb->recvCqDepth = recvDeviceCqAttr.depth;
    3126              : 
    3127            0 :     ret = RsDrvQpCreateWithAttrs(qpCb, qpNorm);
    3128            0 :     if (ret) {
    3129            0 :         hccp_err("Create drv qp create failed:%d", ret);
    3130            0 :         goto create_qp_err;
    3131              :     }
    3132              : 
    3133            0 :     ret = ibv_req_notify_cq(qpCb->ibSendCq, 0);
    3134            0 :     if (ret) {
    3135            0 :         hccp_err("Can't request send CQ notification, ret:%d", ret);
    3136            0 :         ret = -EOPENSRC;
    3137            0 :         goto ret_noritfy_cq;
    3138              :     }
    3139              : 
    3140            0 :     ret = ibv_req_notify_cq(qpCb->ibRecvCq, 0);
    3141            0 :     if (ret) {
    3142            0 :         hccp_err("Can't request recv CQ notification, ret:%d", ret);
    3143            0 :         ret = -EOPENSRC;
    3144            0 :         goto ret_noritfy_cq;
    3145              :     }
    3146              : 
    3147            0 :     ret = RsQpNotifyMr(rdevCb, qpCb, &qpResp->qpn);
    3148            0 :     if (ret) {
    3149            0 :         hccp_err("Store qp notify mr failed:%d", ret);
    3150            0 :         goto ret_noritfy_cq;
    3151              :     }
    3152              : 
    3153            0 :     RsQpPrepareQpResp(qpNorm, qpCb, qpResp);
    3154              : 
    3155            0 :     return 0;
    3156              : 
    3157            0 : ret_noritfy_cq:
    3158            0 :     RsDrvQpDestroy(qpCb);
    3159              : 
    3160            0 : create_qp_err:
    3161              :     // Do NOT call RsDrvDestroyCq — CQs are not owned by this QP
    3162            0 :     RsDeinitMemPool(qpCb);
    3163            0 :     (void)RsQpcbDeinit(rdevCb, qpCb);
    3164              : 
    3165            0 : rs_init_mem_err:
    3166            0 : rs_qpcb_init_err:
    3167            0 :     pthread_mutex_destroy(&qpCb->cqeErrInfo.mutex);
    3168              : 
    3169            0 : cqe_mutex_init_err:
    3170            0 :     pthread_mutex_destroy(&qpCb->qpMutex);
    3171              : 
    3172            0 : qp_mutex_init_err:
    3173            0 :     free(qpCb);
    3174            0 :     qpCb = NULL;
    3175              : 
    3176            0 :     return ret;
    3177              : }
    3178              : 
    3179            7 : RS_ATTRI_VISI_DEF int RsCqDestroy(unsigned int phyId, unsigned int rdevIndex, struct CqAttr *attr)
    3180              : {
    3181              :     int ret;
    3182            7 :     struct RsRdevCb *rdevCb = NULL;
    3183            7 :     struct RsCqContext *cqContext = NULL;
    3184              : 
    3185            7 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
    3186            7 :     CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret), ret);
    3187              : 
    3188            7 :     cqContext = *attr->qpContext;
    3189              : 
    3190            7 :     ret = RsDrvDestroyCqEvent(cqContext);
    3191            7 :     if (ret) {
    3192            0 :         hccp_err("rs_drv_destroy_cq_event failed ret %d", ret);
    3193              :     }
    3194              : 
    3195            7 :     if (cqContext->channel != NULL) {
    3196            5 :         ret = RsEpollCtl(rdevCb->rsCb->connCb.epollfd, EPOLL_CTL_DEL, cqContext->channel->fd, EPOLLIN | EPOLLRDHUP);
    3197              : #ifndef CA_CONFIG_LLT
    3198              :         if (ret) {
    3199              :             hccp_err("del channel fd failed ret %d", ret);
    3200              :         }
    3201              : #endif
    3202            5 :         RsIbvDestroyCompChannel(cqContext->channel);
    3203            5 :         cqContext->channel = NULL;
    3204              :     }
    3205              : 
    3206            7 :     free(cqContext);
    3207            7 :     cqContext = NULL;
    3208              : 
    3209            7 :     return ret;
    3210              : }
    3211              : 
    3212            4 : RS_ATTRI_VISI_DEF int RsNormalQpCreate(unsigned int phyId, unsigned int rdevIndex, struct ibv_qp_init_attr *qpInitAttr,
    3213              :     struct RsQpResp *qpResp, void **qp)
    3214              : {
    3215            4 :     struct RsCqContext *cqContext = NULL;
    3216            4 :     struct RsRdevCb *rdevCb = NULL;
    3217            4 :     struct RsQpCb *qpCb = NULL;
    3218              :     int ret;
    3219              : 
    3220            4 :     CHK_PRT_RETURN(qpResp == NULL, hccp_err("qp_resp is NULL!"), -EINVAL);
    3221            4 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
    3222            4 :     CHK_PRT_RETURN(ret != 0, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret), ret);
    3223              : 
    3224            4 :     CHK_PRT_RETURN(qpInitAttr == NULL, hccp_err("qp_init_attr is NULL!"), -EINVAL);
    3225              : 
    3226            4 :     cqContext = qpInitAttr->qp_context;
    3227            4 :     CHK_PRT_RETURN(cqContext == NULL, hccp_err("cq_context is NULL!"), -EINVAL);
    3228            3 :     CHK_PRT_RETURN(rdevCb != cqContext->rdevCb,
    3229              :         hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u],"
    3230              :                  "rdevCb is invalid.",
    3231              :             phyId, rdevIndex),
    3232              :         -EINVAL);
    3233              : 
    3234            3 :     ret = RsBuildUpQpcb(cqContext, qpInitAttr, &qpCb);
    3235            3 :     CHK_PRT_RETURN(ret, hccp_err("rs_build_up_qpcb failed, ret:%d", ret), ret);
    3236              : 
    3237            3 :     ret = RsDrvNormalQpCreate(qpCb, qpInitAttr);
    3238            3 :     if (ret) {
    3239            1 :         hccp_err("create drv qp create failed:%d", ret);
    3240            1 :         goto create_qp_err;
    3241              :     }
    3242              : 
    3243            2 :     RS_PTHREAD_MUTEX_LOCK(&rdevCb->rdevMutex);
    3244            2 :     RsListAddTail(&qpCb->list, &rdevCb->qpList);
    3245            2 :     RS_PTHREAD_MUTEX_ULOCK(&rdevCb->rdevMutex);
    3246            2 :     rdevCb->qpCnt++;
    3247            2 :     *qp = qpCb->ibQp;
    3248            2 :     qpResp->qpn = (unsigned int)qpCb->qpInfoLo.qpn;
    3249            2 :     qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
    3250            2 :     qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
    3251            2 :     qpResp->gid = qpCb->qpInfoLo.gid;
    3252              : 
    3253            2 :     hccp_info("qp %d create qp.", qpResp->qpn);
    3254              : 
    3255            2 :     return 0;
    3256              : 
    3257            1 : create_qp_err:
    3258            1 :     pthread_mutex_destroy(&qpCb->qpMutex);
    3259            1 :     free(qpCb);
    3260            1 :     qpCb = NULL;
    3261            1 :     return ret;
    3262              : }
    3263              : 
    3264            2 : RS_ATTRI_VISI_DEF int RsNormalQpDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
    3265              : {
    3266            2 :     struct RsQpCb *qpCb = NULL;
    3267              :     int ret;
    3268              : 
    3269            2 :     RS_QP_PARA_CHECK(phyId);
    3270            2 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    3271            2 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
    3272              : 
    3273            2 :     RsQpRelease(qpCb);
    3274              : 
    3275              :     // destroy qp
    3276            2 :     RsDrvQpDestroy(qpCb);
    3277              : 
    3278            2 :     qpCb->rdevCb->qpCnt--;
    3279              : 
    3280            2 :     pthread_mutex_destroy(&qpCb->qpMutex);
    3281            2 :     hccp_info("qp %d destroy qp, send wr[%u].", qpn, qpCb->sendWrNum);
    3282              : 
    3283            2 :     free(qpCb);
    3284            2 :     qpCb = NULL;
    3285            2 :     return ret;
    3286              : }
    3287              : 
    3288            4 : RS_ATTRI_VISI_DEF int RsCreateCompChannel(unsigned int phyId, unsigned int rdevIndex, void **compChannel)
    3289              : {
    3290              :     int ret;
    3291              :     unsigned int chipId;
    3292              : 
    3293            4 :     struct RsRdevCb *rdevCb = NULL;
    3294              : 
    3295            4 :     CHK_PRT_RETURN(compChannel == NULL || phyId >= RS_MAX_DEV_NUM,
    3296              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
    3297              : 
    3298            4 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    3299            4 :     CHK_PRT_RETURN(ret,
    3300              :         hccp_err("rs_create_comp_channel rsGetLocalDevIDByHostDevID phyId[%u] invalid, ret %d", phyId, ret), ret);
    3301              : 
    3302            3 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
    3303            3 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
    3304              :         ret);
    3305              : 
    3306            2 :     *compChannel = (void *)RsIbvCreateCompChannel(rdevCb->ibCtx);
    3307            2 :     if (*compChannel == NULL) {
    3308            1 :         hccp_err("rs_ibv_create_comp_channel failed, errno(%d)", errno);
    3309            1 :         return -EOPENSRC;
    3310              :     }
    3311            1 :     hccp_info("create comp channel success!");
    3312            1 :     return 0;
    3313              : }
    3314              : 
    3315            2 : RS_ATTRI_VISI_DEF int RsDestroyCompChannel(void *compChannel)
    3316              : {
    3317              :     int ret;
    3318            2 :     struct ibv_comp_channel *rsCompChannel = (struct ibv_comp_channel *)compChannel;
    3319              : 
    3320            2 :     ret = RsIbvDestroyCompChannel(rsCompChannel);
    3321            2 :     CHK_PRT_RETURN(ret, hccp_err("rs_destroy_comp_channel failed."), ret);
    3322            1 :     hccp_info("destroy comp channel success!");
    3323              : 
    3324            1 :     return 0;
    3325              : }
    3326              : 
    3327            5 : RS_ATTRI_VISI_DEF int RsCreateSrq(unsigned int phyId, unsigned int rdevIndex, struct SrqAttr *attr)
    3328              : {
    3329              :     int ret;
    3330            5 :     struct RsRdevCb *rdevCb = NULL;
    3331            5 :     struct RsCqContext *cqContext = NULL;
    3332              : 
    3333            5 :     CHK_PRT_RETURN(attr == NULL || attr->context == NULL || attr->ibRecvCq == NULL || attr->ibSrq == NULL ||
    3334              :                        phyId >= RS_MAX_DEV_NUM,
    3335              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
    3336              : 
    3337            5 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
    3338            5 :     CHK_PRT_RETURN(ret, hccp_err("rs_query_rdev_cb phyId[%u] rdev_index[%u], ret %d", phyId, rdevIndex, ret), ret);
    3339              : 
    3340            4 :     cqContext = calloc(1, sizeof(struct RsCqContext));
    3341            4 :     if (cqContext == NULL) {
    3342            1 :         return -ENOMEM;
    3343              :     }
    3344              : 
    3345            3 :     cqContext->rdevCb = rdevCb;
    3346            3 :     cqContext->eqNum = 0;
    3347            3 :     cqContext->cqCreateMode = RS_SRQ_CQ_CREATE;
    3348            3 :     *attr->context = cqContext;
    3349              : 
    3350            3 :     struct CqAttr cqAttr = {0};
    3351            3 :     cqAttr.recvCqDepth = attr->cqDepth;
    3352            3 :     cqAttr.recvCqEventId = attr->srqEventId;
    3353            3 :     cqAttr.ibRecvCq = attr->ibRecvCq;
    3354              :     // 创建srq cq
    3355            3 :     ret = RsCreateCqEvent(cqContext, &cqAttr);
    3356            3 :     if (ret) {
    3357            1 :         hccp_err("rs_create_cq_event create cq failed! ret:%d", ret);
    3358            1 :         goto create_cq_event_err;
    3359              :     }
    3360            2 :     cqContext->ibSrqCq = *attr->ibRecvCq;
    3361              : 
    3362            2 :     struct ibv_srq_init_attr srqInitAttr = {.attr = {.max_wr = attr->srqDepth, .max_sge = attr->maxSge}};
    3363            2 :     hccp_info("max_wr [%u], max_sge[%u]", srqInitAttr.attr.max_wr, srqInitAttr.attr.max_sge);
    3364              : 
    3365              :     // 创建srq
    3366            2 :     *attr->ibSrq = RsIbvCreateSrq(rdevCb->ibPd, &srqInitAttr);
    3367            2 :     if (*attr->ibSrq == NULL) {
    3368            1 :         hccp_err("rs_ibv_create_srq failed.");
    3369            1 :         ret = -EOPENSRC;
    3370            1 :         goto create_srq_err;
    3371              :     }
    3372            1 :     hccp_info("create srq success!");
    3373              : 
    3374            1 :     return 0;
    3375            1 : create_cq_event_err:
    3376            2 : create_srq_err:
    3377            2 :     cqAttr.qpContext = attr->context;
    3378            2 :     RsCqDestroy(phyId, rdevIndex, &cqAttr);
    3379              : 
    3380            2 :     return ret;
    3381              : }
    3382              : 
    3383            1 : RS_ATTRI_VISI_DEF int RsDestroySrq(unsigned int phyId, unsigned int rdevIndex, struct SrqAttr *attr)
    3384              : {
    3385              :     int ret;
    3386              : 
    3387            1 :     CHK_PRT_RETURN(*attr->context == NULL || *attr->ibSrq == NULL || phyId >= RS_MAX_DEV_NUM,
    3388              :         hccp_err("param err, NULL pointer or phyId:%u >= [%d]", phyId, RS_MAX_DEV_NUM), -EINVAL);
    3389              : 
    3390            1 :     struct CqAttr cqAttr = {0};
    3391            1 :     struct RsCqContext *cqContext = *attr->context;
    3392            1 :     cqAttr.qpContext = attr->context;
    3393            1 :     RsIbvAckCqEvents(cqContext->ibSrqCq, cqContext->numRecvCqEvents);
    3394              : 
    3395              :     // 销毁srq cq
    3396            1 :     ret = RsCqDestroy(phyId, rdevIndex, &cqAttr);
    3397            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_cq_destroy destroy cq failed! ret:%d", ret), ret);
    3398              : 
    3399            1 :     ret = RsIbvDestroySrq(*attr->ibSrq);
    3400            1 :     CHK_PRT_RETURN(ret, hccp_err("rs_ibv_destroy_srq failed."), ret);
    3401              : 
    3402            1 :     return 0;
    3403              : }
    3404              : 
    3405            2 : RS_ATTRI_VISI_DEF int RsGetLiteSupport(unsigned int phyId, unsigned int rdevIndex, int *supportLite)
    3406              : {
    3407              :     int ret;
    3408              :     unsigned int chipId;
    3409            2 :     struct RsRdevCb *rdevCb = NULL;
    3410              : 
    3411            2 :     RS_CHECK_POINTER_NULL_RETURN_INT(supportLite);
    3412              : 
    3413            2 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs set param error ! phyId:%u", phyId), -EINVAL);
    3414            2 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    3415            2 :     CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
    3416              : 
    3417            2 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
    3418            2 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
    3419              :         ret);
    3420              : 
    3421            2 :     rdevCb->supportLite = 1;
    3422            2 :     *supportLite = rdevCb->supportLite;
    3423              : 
    3424            2 :     return 0;
    3425              : }
    3426              : 
    3427            2 : RS_ATTRI_VISI_DEF int RsGetLiteRdevCap(unsigned int phyId, unsigned int rdevIndex, struct LiteRdevCapResp *resp)
    3428              : {
    3429              :     int ret;
    3430              :     unsigned int chipId;
    3431            2 :     struct RsRdevCb *rdevCb = NULL;
    3432              : 
    3433            2 :     RS_CHECK_POINTER_NULL_RETURN_INT(resp);
    3434              : 
    3435            2 :     CHK_PRT_RETURN(phyId >= RS_MAX_DEV_NUM, hccp_err("rs set param error ! phyId:%u", phyId), -EINVAL);
    3436            2 :     ret = rsGetLocalDevIDByHostDevID(phyId, &chipId);
    3437            2 :     CHK_PRT_RETURN(ret, hccp_err("phyId[%u] invalid, ret %d", phyId, ret), ret);
    3438              : 
    3439            2 :     ret = RsRdev2rdevCb(chipId, rdevIndex, &rdevCb);
    3440            2 :     CHK_PRT_RETURN(ret != 0 || rdevCb == NULL, hccp_err("rs_rdev2rdev_cb for chip_id[%u] failed, ret %d", chipId, ret),
    3441              :         ret);
    3442              : 
    3443            2 :     ret = RsIbvExpQueryDevice(rdevCb->ibCtx, &resp->cap);
    3444            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("rs_ibv_exp_query_device for phyId[%u] failed, ret %d", phyId, ret), ret);
    3445              : 
    3446            2 :     ret = memcpy_s(resp, sizeof(struct dev_cap_info), (void *)&resp->cap, sizeof(resp->cap));
    3447            2 :     if (ret) {
    3448            0 :         hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u", ret, (unsigned int)sizeof(resp->cap),
    3449              :             (unsigned int)sizeof(struct dev_cap_info));
    3450            0 :         return ret;
    3451              :     }
    3452              : 
    3453            2 :     return 0;
    3454              : }
    3455              : 
    3456            2 : RS_ATTRI_VISI_DEF int RsGetLiteQpCqAttr(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
    3457              :     struct LiteQpCqAttrResp *resp)
    3458              : {
    3459              :     int ret;
    3460            2 :     struct RsQpCb *qpCb = NULL;
    3461              : 
    3462            2 :     RS_CHECK_POINTER_NULL_RETURN_INT(resp);
    3463              : 
    3464            2 :     RS_QP_PARA_CHECK(phyId);
    3465            2 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    3466            2 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
    3467              : 
    3468            2 :     ret = memcpy_s(resp, sizeof(struct LiteQpCqAttrResp), (void *)&qpCb->qpResp, sizeof(qpCb->qpResp));
    3469            2 :     if (ret) {
    3470            0 :         hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u", ret, (unsigned int)sizeof(qpCb->qpResp),
    3471              :             (unsigned int)sizeof(struct LiteQpCqAttrResp));
    3472            0 :         return ret;
    3473              :     }
    3474              : 
    3475            2 :     return 0;
    3476              : }
    3477              : 
    3478            0 : RS_ATTRI_VISI_DEF int RsGetLiteQpAttr(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
    3479              :     struct LiteQpAttrResp *resp)
    3480              : {
    3481              :     int ret;
    3482            0 :     struct RsQpCb *qpCb = NULL;
    3483              : 
    3484            0 :     RS_CHECK_POINTER_NULL_RETURN_INT(resp);
    3485              : 
    3486            0 :     RS_QP_PARA_CHECK(phyId);
    3487            0 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    3488            0 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
    3489              : 
    3490            0 :     ret = memcpy_s(resp, sizeof(struct LiteQpAttrResp), (void *)&qpCb->qpResp.qpData, sizeof(qpCb->qpResp.qpData));
    3491            0 :     if (ret) {
    3492            0 :         hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u", ret, (unsigned int)sizeof(qpCb->qpResp.qpData),
    3493              :             (unsigned int)sizeof(struct LiteQpAttrResp));
    3494            0 :         return ret;
    3495              :     }
    3496              : 
    3497            0 :     return 0;
    3498              : }
    3499              : 
    3500            2 : RS_ATTRI_VISI_DEF int RsGetLiteMemAttr(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
    3501              :     struct LiteMemAttrResp *resp)
    3502              : {
    3503              :     int ret;
    3504            2 :     struct RsQpCb *qpCb = NULL;
    3505              : 
    3506            2 :     RS_CHECK_POINTER_NULL_RETURN_INT(resp);
    3507              : 
    3508            2 :     RS_QP_PARA_CHECK(phyId);
    3509            2 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    3510            2 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
    3511              : 
    3512            2 :     ret = memcpy_s(resp, sizeof(struct LiteMemAttrResp), (void *)&qpCb->memResp, sizeof(qpCb->memResp));
    3513            2 :     if (ret) {
    3514            0 :         hccp_err("memcpy_s failed, ret:%d, src_len:%u, dst_len:%u", ret, (unsigned int)sizeof(qpCb->memResp),
    3515              :             (unsigned int)sizeof(struct LiteMemAttrResp));
    3516            0 :         return ret;
    3517              :     }
    3518              : 
    3519            2 :     return 0;
    3520              : }
    3521              : 
    3522            4 : STATIC void RsGetMrInfo(struct RsQpCb *qpCb, struct LiteMrInfo *mr, uint32_t maxMrNum, struct RsListHead *mrList)
    3523              : {
    3524            4 :     struct RsMrCb *mrTmp = NULL;
    3525            4 :     struct RsMrCb *mrTmp2 = NULL;
    3526            4 :     uint32_t i = 0;
    3527              : 
    3528            4 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->qpMutex);
    3529            4 :     RS_LIST_GET_HEAD_ENTRY(mrTmp, mrTmp2, mrList, list, struct RsMrCb);
    3530            6 :     for (; (&mrTmp->list) != mrList; mrTmp = mrTmp2, mrTmp2 = list_entry(mrTmp2->list.next, struct RsMrCb, list)) {
    3531            2 :         if (i < maxMrNum) {
    3532            2 :             mr[i].key = mrTmp->mrInfo.rkey;
    3533            2 :             mr[i].addr = mrTmp->mrInfo.addr;
    3534            2 :             mr[i].len = mrTmp->mrInfo.len;
    3535            2 :             i++;
    3536              :         } else {
    3537            0 :             break;
    3538              :         }
    3539              :     }
    3540              : 
    3541            4 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->qpMutex);
    3542            4 : }
    3543              : 
    3544            2 : RS_ATTRI_VISI_DEF int RsGetLiteConnectedInfo(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
    3545              :     struct LiteConnectedInfoResp *resp)
    3546              : {
    3547              :     int ret;
    3548            2 :     struct RsQpCb *qpCb = NULL;
    3549              : 
    3550            2 :     RS_CHECK_POINTER_NULL_RETURN_INT(resp);
    3551            2 :     RS_QP_PARA_CHECK(phyId);
    3552            2 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
    3553            2 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed qpn %u, ret %d", qpn, ret), ret);
    3554              : 
    3555            2 :     resp->state = (unsigned int)qpCb->state;
    3556            2 :     if (resp->state == RS_QP_STATUS_CONNECTED) {
    3557            2 :         RsGetMrInfo(qpCb, &resp->localMr[0], RA_MR_MAX_NUM, &qpCb->mrList);
    3558            2 :         RsGetMrInfo(qpCb, &resp->remMr[0], RA_MR_MAX_NUM, &qpCb->remMrList);
    3559            2 :         resp->qosAttr.sl = qpCb->qosAttr.sl;
    3560            2 :         resp->qosAttr.tc = qpCb->qosAttr.tc;
    3561              :     }
    3562              : 
    3563            2 :     return 0;
    3564              : }
        

Generated by: LCOV version 2.0-1