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: 77.0 % 1979 1523
Test Date: 2026-07-28 12:11:00 Functions: 89.3 % 112 100

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

Generated by: LCOV version 2.0-1