LCOV - code coverage report
Current view: top level - base_comm/resources/hccp/rdma_service - rs_nda.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.0 % 483 401
Test Date: 2026-08-25 19:18:03 Functions: 84.8 % 33 28

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include <stdlib.h>
      12              : #include <stdint.h>
      13              : #include <errno.h>
      14              : #include "securec.h"
      15              : #include "dl_hal_function.h"
      16              : #include "dl_ibverbs_function.h"
      17              : #include "dl_ibv_extend_function.h"
      18              : #include "hccp_nda.h"
      19              : #include "ra_rs_err.h"
      20              : #include "rs.h"
      21              : #include "rs_inner.h"
      22              : #include "rs_drv_rdma.h"
      23              : #include "rs_rdma.h"
      24              : #include "rs_nda.h"
      25              : 
      26            2 : RS_ATTRI_VISI_DEF int RsNdaGetDirectFlag(unsigned int phyId, unsigned int rdevIndex, int *directFlag)
      27              : {
      28            2 :     struct ibv_device_attr_extend extDevAttr = {0};
      29            2 :     struct RsRdevCb *rdevCb = NULL;
      30            2 :     int ret = 0;
      31              : 
      32            2 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
      33            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQueryRdevCb phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret), ret);
      34              : 
      35            1 :     if (rdevCb->ibCtxEx == NULL) {
      36            1 :         hccp_warn("ibCtxEx is null, phyId:%u rdevIndex:%u", phyId, rdevIndex);
      37            1 :         *directFlag = DIRECT_FLAG_NOTSUPP;
      38            1 :         return ret;
      39              :     }
      40              : 
      41            0 :     ret = RsIbvQueryDeviceExtend(rdevCb->ibCtxEx, &extDevAttr);
      42            0 :     CHK_PRT_RETURN(ret != 0,
      43              :         hccp_err("RsIbvQueryDeviceExtend failed, phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret), ret);
      44              : 
      45            0 :     if ((extDevAttr.ext_cap & IBV_EXTEND_DEV_NDA) == 0) {
      46            0 :         hccp_warn("dev not support NDA, phyId:%u rdevIndex:%u ext_cap:0x%x", phyId, rdevIndex, extDevAttr.ext_cap);
      47            0 :         *directFlag = DIRECT_FLAG_NOTSUPP;
      48            0 :         return ret;
      49              :     }
      50              : 
      51            0 :     *directFlag = rdevCb->directFlag;
      52            0 :     return ret;
      53              : }
      54              : 
      55           32 : STATIC int RsNdaGetDirectFlagByDevAttr(struct ibv_device_attr *deviceAttr)
      56              : {
      57              :     struct {
      58              :         uint32_t vendorId;
      59              :         uint32_t vendorPartID;
      60           32 :     } vendorInfoList[] = {
      61              :         {0x19E5U, 0x0230U},
      62              :         {0x19E5U, 0x0231U},
      63              :         {0x19E5U, 0x0232U},
      64              :         {0xCC08U, 0x8200U},
      65              :         {0xCC08U, 0x8201U},
      66              :     };
      67           32 :     unsigned int listSize = sizeof(vendorInfoList) / sizeof(vendorInfoList[0]);
      68              :     unsigned int i;
      69              : 
      70          192 :     for (i = 0; i < listSize; i++) {
      71          160 :         if ((deviceAttr->vendor_id == vendorInfoList[i].vendorId) &&
      72            0 :             (deviceAttr->vendor_part_id == vendorInfoList[i].vendorPartID)) {
      73            0 :             return DIRECT_FLAG_UB;
      74              :         }
      75              :     }
      76              : 
      77           32 :     return DIRECT_FLAG_PCIE;
      78              : }
      79              : 
      80            6 : STATIC int RsGetNdaPcieDbCb(struct RsNdaCb *ndaCb, uint64_t hva, struct NdaPcieDbCb **ndaDbCb)
      81              : {
      82            6 :     struct NdaPcieDbCb *dbCbCurr = NULL;
      83            6 :     struct NdaPcieDbCb *dbCbNext = NULL;
      84              : 
      85            6 :     RS_LIST_GET_HEAD_ENTRY(dbCbCurr, dbCbNext, &ndaCb->ndaPcieCb.ndaDbList, list, struct NdaPcieDbCb);
      86            6 :     for (; (&dbCbCurr->list) != &ndaCb->ndaPcieCb.ndaDbList;
      87            0 :          dbCbCurr = dbCbNext, dbCbNext = list_entry(dbCbNext->list.next, struct NdaPcieDbCb, list)) {
      88            3 :         if (dbCbCurr->hva == hva) {
      89            3 :             *ndaDbCb = dbCbCurr;
      90            3 :             return 0;
      91              :         }
      92              :     }
      93              : 
      94            3 :     *ndaDbCb = NULL;
      95            3 :     hccp_info("ndaDbCb for hva:0x%llx does not exist", hva);
      96            3 :     return -ENODEV;
      97              : }
      98              : 
      99            7 : STATIC int RsGetNdaUbDbCb(struct RsNdaCb *ndaCb, uint64_t guidL, uint64_t guidH, struct NdaUbDbCb **ndaDbCb)
     100              : {
     101            7 :     struct NdaUbDbCb *dbCbCurr = NULL;
     102            7 :     struct NdaUbDbCb *dbCbNext = NULL;
     103              : 
     104            7 :     RS_LIST_GET_HEAD_ENTRY(dbCbCurr, dbCbNext, &ndaCb->ndaUbCb.ndaDbList, list, struct NdaUbDbCb);
     105            7 :     for (; (&dbCbCurr->list) != &ndaCb->ndaUbCb.ndaDbList;
     106            0 :          dbCbCurr = dbCbNext, dbCbNext = list_entry(dbCbNext->list.next, struct NdaUbDbCb, list)) {
     107            3 :         if (dbCbCurr->guidL == guidL && dbCbCurr->guidH == guidH) {
     108            3 :             *ndaDbCb = dbCbCurr;
     109            3 :             return 0;
     110              :         }
     111              :     }
     112              : 
     113            4 :     *ndaDbCb = NULL;
     114            4 :     hccp_info("ndaDbCb for guidL:0x%llx guidH:0x%llx does not exist", guidL, guidH);
     115            4 :     return -ENODEV;
     116              : }
     117              : 
     118            0 : STATIC void *RsNdaPcieAlloc(size_t size)
     119              : {
     120            0 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     121            0 :     void *ptr = NULL;
     122              : 
     123            0 :     CHK_PRT_RETURN(ndaCb == NULL || ndaCb->ndaOps.alloc == NULL,
     124              :         hccp_err("ndaCb or ndaOps.alloc is NULL, chipId:%u", gRsCb->chipId), NULL);
     125              : 
     126            0 :     ptr = ndaCb->ndaOps.alloc(size);
     127            0 :     CHK_PRT_RETURN(ptr == NULL, hccp_err("ptr alloc failed"), NULL);
     128              : 
     129            0 :     return ptr;
     130              : }
     131              : 
     132            0 : STATIC void RsNdaPcieFree(void *ptr)
     133              : {
     134            0 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     135              : 
     136            0 :     if (ndaCb == NULL || ndaCb->ndaOps.free == NULL) {
     137            0 :         hccp_err("gRsCb->ndaCb or ndaOps.free is NULL, chipId:%u", gRsCb->chipId);
     138            0 :         return;
     139              :     }
     140              : 
     141            0 :     ndaCb->ndaOps.free(ptr);
     142            0 :     ptr = NULL;
     143              : }
     144              : 
     145            4 : STATIC void *RsNdaUbAlloc(size_t size)
     146              : {
     147            4 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     148            4 :     struct DVattribute attr = {0};
     149            4 :     void *ptr = NULL;
     150            4 :     int ret = 0;
     151              : 
     152            4 :     CHK_PRT_RETURN(ndaCb == NULL || ndaCb->ndaOps.alloc == NULL || ndaCb->ndaOps.free == NULL,
     153              :         hccp_err("ndaCb or alloc or free is NULL, chipId:%u", gRsCb->chipId), NULL);
     154              : 
     155            2 :     ptr = ndaCb->ndaOps.alloc(size);
     156            2 :     CHK_PRT_RETURN(ptr == NULL, hccp_err("ptr alloc failed"), NULL);
     157              : 
     158            2 :     ret = DlDrvMemGetAttribute((uint64_t)(uintptr_t)ptr, &attr);
     159            2 :     if (ret != 0) {
     160            1 :         hccp_err("DlDrvMemGetAttribute failed, ret:%d", ret);
     161            1 :         goto free_ptr;
     162              :     }
     163              : 
     164            1 :     if (attr.memType == DV_MEM_LOCK_DEV) {
     165            1 :         ret = DlHalMemRegUbSegment(attr.devId, (uint64_t)(uintptr_t)ptr, size);
     166            1 :         if (ret != 0) {
     167            1 :             hccp_err("DlHalMemRegUbSegment failed, ret:%d devId:%u size:%zu", ret, attr.devId, size);
     168            1 :             goto free_ptr;
     169              :         }
     170              :     }
     171              : 
     172            0 :     return ptr;
     173              : 
     174            2 : free_ptr:
     175            2 :     ndaCb->ndaOps.free(ptr);
     176            2 :     ptr = NULL;
     177            2 :     return NULL;
     178              : }
     179              : 
     180            0 : STATIC void RsNdaUbFree(void *ptr)
     181              : {
     182            0 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     183            0 :     struct DVattribute attr = {0};
     184            0 :     int ret = 0;
     185              : 
     186            0 :     if (ndaCb == NULL || ndaCb->ndaOps.free == NULL) {
     187            0 :         hccp_err("gRsCb->ndaCb or ndaOps.free is NULL, chipId:%u", gRsCb->chipId);
     188            0 :         return;
     189              :     }
     190              : 
     191            0 :     ret = DlDrvMemGetAttribute((uint64_t)(uintptr_t)ptr, &attr);
     192            0 :     if (ret != 0) {
     193            0 :         hccp_err("DlDrvMemGetAttribute failed, ret:%d", ret);
     194            0 :         goto free_ptr;
     195              :     }
     196              : 
     197            0 :     if (attr.memType == DV_MEM_LOCK_DEV) {
     198            0 :         (void)DlHalMemUnRegUbSegment(attr.devId, (uint64_t)(uintptr_t)ptr);
     199              :     }
     200              : 
     201            0 : free_ptr:
     202            0 :     ndaCb->ndaOps.free(ptr);
     203            0 :     ptr = NULL;
     204              : }
     205              : 
     206            0 : STATIC void RsNdaMemset(void *dst, int value, size_t count)
     207              : {
     208            0 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     209              : 
     210            0 :     if (ndaCb == NULL || ndaCb->ndaOps.memset_s == NULL) {
     211            0 :         hccp_err("gRsCb->ndaCb or ndaOps.memset_s is NULL, chipId:%u", gRsCb->chipId);
     212            0 :         return;
     213              :     }
     214              : 
     215            0 :     ndaCb->ndaOps.memset_s(dst, value, count);
     216              : }
     217              : 
     218            0 : STATIC int RsNdaMemcpy(void *dst, size_t dstSize, void *src, size_t srcSize, uint32_t direct)
     219              : {
     220            0 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     221              : 
     222            0 :     if (ndaCb == NULL || ndaCb->ndaOps.memcpy_s == NULL) {
     223            0 :         hccp_err("gRsCb->ndaCb or ndaOps.memcpy_s is NULL, chipId:%u", gRsCb->chipId);
     224            0 :         return -ENODEV;
     225              :     }
     226              : 
     227            0 :     return ndaCb->ndaOps.memcpy_s(dst, dstSize, src, srcSize, direct);
     228              : }
     229              : 
     230            5 : STATIC void RsNdaFreeUbDbCb(struct NdaUbDbCb *ndaDbCb)
     231              : {
     232            5 :     if (ndaDbCb->refCnt != 0) {
     233            1 :         return;
     234              :     }
     235              : 
     236            4 :     RsListDel(&ndaDbCb->list);
     237            4 :     free(ndaDbCb);
     238            4 :     ndaDbCb = NULL;
     239              : }
     240              : 
     241            4 : STATIC void *RsNdaDbMmapHostVa(struct RsNdaCb *ndaCb, struct doorbell_map_desc *desc)
     242              : {
     243            4 :     uint64_t alignHva = AlignDown(desc->hva, (uint64_t)RA_RS_4K_PAGE_SIZE);
     244            4 :     uint64_t alignSize = AlignUp(desc->size, (uint64_t)RA_RS_4K_PAGE_SIZE);
     245            4 :     uint64_t offset = desc->hva - alignHva;
     246            4 :     unsigned int logicId = gRsCb->logicId;
     247            4 :     struct NdaPcieDbCb *ndaDbCb = NULL;
     248            4 :     void *dbDva = NULL;
     249            4 :     int ret = 0;
     250              : 
     251            4 :     ret = RsGetNdaPcieDbCb(ndaCb, alignHva, &ndaDbCb);
     252            4 :     if (ret == 0) {
     253            1 :         ndaDbCb->refCnt++;
     254            1 :         return (void *)(uintptr_t)(ndaDbCb->dva + offset);
     255              :     }
     256              : 
     257            3 :     ndaDbCb = (struct NdaPcieDbCb *)calloc(1, sizeof(struct NdaPcieDbCb));
     258            3 :     CHK_PRT_RETURN(ndaDbCb == NULL, hccp_err("ndaDbCb calloc failed"), NULL);
     259              : 
     260            3 :     ret = DlHalHostRegister((void *)(uintptr_t)alignHva, alignSize, HOST_IO_MAP_DEV, logicId, &dbDva);
     261            3 :     if (ret != 0) {
     262            2 :         hccp_err("register host failed, chipId:%u logicId:%u ret:%d alignHva:0x%llx", gRsCb->chipId, logicId, ret,
     263              :             alignHva);
     264            2 :         free(ndaDbCb);
     265            2 :         ndaDbCb = NULL;
     266            2 :         return NULL;
     267              :     }
     268              : 
     269            1 :     ndaDbCb->hva = alignHva;
     270            1 :     ndaDbCb->dva = (uint64_t)(uintptr_t)dbDva;
     271            1 :     ndaDbCb->refCnt++;
     272            1 :     RsListAddTail(&ndaDbCb->list, &ndaCb->ndaPcieCb.ndaDbList);
     273            1 :     return (void *)(uintptr_t)(ndaDbCb->dva + offset);
     274              : }
     275              : 
     276            7 : STATIC void RsNdaMapPrivPrepare(struct doorbell_map_desc *desc, struct NdaUbResMapPrivInfo *resMapIn)
     277              : {
     278            7 :     resMapIn->guid_l = desc->ub_res.guid_l;
     279            7 :     resMapIn->guid_h = desc->ub_res.guid_h;
     280            7 :     resMapIn->db_idx = desc->ub_res.bits.offset / (uint64_t)RA_RS_4K_PAGE_SIZE;
     281            7 :     resMapIn->db_num = 1;
     282            7 :     return;
     283              : }
     284              : 
     285            5 : STATIC void *RsNdaDbMmapUbRes(struct RsNdaCb *ndaCb, struct doorbell_map_desc *desc)
     286              : {
     287            5 :     struct NdaUbResMapPrivInfo resMapIn = {0};
     288            5 :     struct res_map_info_out resInfoOut = {0};
     289            5 :     struct res_map_info_in resInfoIn = {0};
     290            5 :     unsigned int logicId = gRsCb->logicId;
     291            5 :     struct NdaUbDbCb *ndaDbCb = NULL;
     292            5 :     uint64_t dva = 0;
     293            5 :     int ret = 0;
     294              : 
     295            5 :     ret = RsGetNdaUbDbCb(ndaCb, desc->ub_res.guid_l, desc->ub_res.guid_h, &ndaDbCb);
     296            5 :     if (ret == 0) {
     297            1 :         goto map_db;
     298              :     }
     299              : 
     300            4 :     ndaDbCb = (struct NdaUbDbCb *)calloc(1, sizeof(struct NdaUbDbCb));
     301            4 :     CHK_PRT_RETURN(ndaDbCb == NULL, hccp_err("ndaDbCb calloc failed"), NULL);
     302            4 :     ndaDbCb->guidL = desc->ub_res.guid_l;
     303            4 :     ndaDbCb->guidH = desc->ub_res.guid_h;
     304            4 :     ndaDbCb->guidIdx = ndaCb->ndaUbCb.ndaDbGuidCnt;
     305            4 :     RsListAddTail(&ndaDbCb->list, &ndaCb->ndaUbCb.ndaDbList);
     306            4 :     ndaCb->ndaUbCb.ndaDbGuidCnt++;
     307              : 
     308            5 : map_db:
     309            5 :     RsNdaMapPrivPrepare(desc, &resMapIn);
     310            5 :     resInfoIn.target_proc_type = PROCESS_CP1;
     311            5 :     resInfoIn.res_type = RES_ADDR_TYPE_NDA_URMA_DB;
     312            5 :     resInfoIn.res_id = RsNdaGenerateResId(resMapIn.db_idx, ndaDbCb->guidIdx);
     313            5 :     resInfoIn.priv_len = sizeof(struct NdaUbResMapPrivInfo);
     314            5 :     resInfoIn.priv = (void *)&resMapIn;
     315            5 :     ret = DlHalResAddrMapV2(logicId, &resInfoIn, &resInfoOut);
     316            5 :     if (ret != 0) {
     317            3 :         hccp_err("DlHalResAddrMapV2 failed, chipId:%u logicId:%u resId:0x%x ret:%d", gRsCb->chipId, logicId,
     318              :             resInfoIn.res_id, ret);
     319            3 :         RsNdaFreeUbDbCb(ndaDbCb);
     320            3 :         return NULL;
     321              :     }
     322              : 
     323            2 :     ndaDbCb->refCnt++;
     324            2 :     dva = resInfoOut.va + (desc->ub_res.bits.offset % (uint64_t)RA_RS_4K_PAGE_SIZE);
     325            2 :     return (void *)(uintptr_t)dva;
     326              : }
     327              : 
     328           11 : STATIC void *RsNdaDbMmap(struct doorbell_map_desc *desc)
     329              : {
     330           11 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     331              : 
     332           11 :     CHK_PRT_RETURN(desc == NULL, hccp_err("desc is null"), NULL);
     333           11 :     CHK_PRT_RETURN(ndaCb == NULL, hccp_err("ndaCb is null, chipId:%u", gRsCb->chipId), NULL);
     334              : 
     335           11 :     if (desc->type == DB_MAP_MODE_HOST_VA) {
     336            4 :         return RsNdaDbMmapHostVa(ndaCb, desc);
     337            7 :     } else if (desc->type == DB_MAP_MODE_UB_RES) {
     338            5 :         return RsNdaDbMmapUbRes(ndaCb, desc);
     339              :     } else {
     340            2 :         hccp_err("invalid desc->type:%u, chipId:%u", desc->type, gRsCb->chipId);
     341            2 :         return NULL;
     342              :     }
     343              : }
     344              : 
     345            3 : STATIC int RsNdaDbUnmapHostVa(struct RsNdaCb *ndaCb, void *ptr, struct doorbell_map_desc *desc)
     346              : {
     347              :     (void)ptr;
     348            3 :     uint64_t alignHva = AlignDown(desc->hva, (uint64_t)RA_RS_4K_PAGE_SIZE);
     349            3 :     unsigned int logicId = gRsCb->logicId;
     350            3 :     struct NdaPcieDbCb *ndaDbCb = NULL;
     351            3 :     int ret = 0;
     352              : 
     353            3 :     ret = RsGetNdaPcieDbCb(ndaCb, alignHva, &ndaDbCb);
     354            3 :     CHK_PRT_RETURN(ret != 0,
     355              :         hccp_err("RsGetNdaPcieDbCb failed, hva:0x%llx chipId:%u ret:%d", alignHva, gRsCb->chipId, ret), ret);
     356              : 
     357            2 :     ndaDbCb->refCnt--;
     358            2 :     if (ndaDbCb->refCnt != 0) {
     359            1 :         return ret;
     360              :     }
     361              : 
     362            1 :     ret = DlHalHostUnRegisterEx((void *)(uintptr_t)alignHva, logicId, HOST_IO_MAP_DEV);
     363            1 :     if (ret != 0) {
     364            0 :         hccp_err("DlHalHostUnRegisterEx failed, chipId:%u logicId:%u ret:%d", gRsCb->chipId, logicId, ret);
     365              :     }
     366              : 
     367            1 :     RsListDel(&ndaDbCb->list);
     368            1 :     free(ndaDbCb);
     369            1 :     ndaDbCb = NULL;
     370            1 :     return ret;
     371              : }
     372              : 
     373            3 : STATIC int RsNdaDbUnmapUbRes(struct RsNdaCb *ndaCb, void *ptr, struct doorbell_map_desc *desc)
     374              : {
     375              :     (void)ptr;
     376            3 :     struct NdaUbResMapPrivInfo resMapIn = {0};
     377            3 :     struct res_map_info_in resInfoIn = {0};
     378            3 :     unsigned int logicId = gRsCb->logicId;
     379            3 :     struct NdaUbDbCb *ndaDbCb = NULL;
     380            3 :     int ret = 0;
     381              : 
     382            3 :     ret = RsGetNdaUbDbCb(ndaCb, desc->ub_res.guid_l, desc->ub_res.guid_h, &ndaDbCb);
     383            3 :     CHK_PRT_RETURN(ret != 0,
     384              :         hccp_err("RsGetNdaUbDbCb failed, chipId:%u guidL:0x%llx guidH:0x%llx", gRsCb->chipId, desc->ub_res.guid_l,
     385              :             desc->ub_res.guid_h),
     386              :         ret);
     387              : 
     388            2 :     RsNdaMapPrivPrepare(desc, &resMapIn);
     389            2 :     resInfoIn.target_proc_type = PROCESS_CP1;
     390            2 :     resInfoIn.res_type = RES_ADDR_TYPE_NDA_URMA_DB;
     391            2 :     resInfoIn.res_id = RsNdaGenerateResId(resMapIn.db_idx, ndaDbCb->guidIdx);
     392            2 :     resInfoIn.priv_len = sizeof(struct NdaUbResMapPrivInfo);
     393            2 :     resInfoIn.priv = (void *)&resMapIn;
     394            2 :     ret = DlHalResAddrUnmapV2(logicId, &resInfoIn);
     395            2 :     if (ret != 0) {
     396            0 :         hccp_err("DlHalResAddrUnmapV2 failed, chipId:%u logicId:%u resId:0x%x ret:%d", gRsCb->chipId, logicId,
     397              :             resInfoIn.res_id, ret);
     398              :     }
     399              : 
     400            2 :     ndaDbCb->refCnt--;
     401            2 :     RsNdaFreeUbDbCb(ndaDbCb);
     402            2 :     return ret;
     403              : }
     404              : 
     405            6 : STATIC int RsNdaDbUnmap(void *ptr, struct doorbell_map_desc *desc)
     406              : {
     407            6 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)gRsCb->ndaCb;
     408              : 
     409            6 :     CHK_PRT_RETURN(ptr == NULL || desc == NULL, hccp_err("ptr or desc is null"), -EINVAL);
     410            6 :     CHK_PRT_RETURN(ndaCb == NULL, hccp_err("ndaCb is null, chipId:%u", gRsCb->chipId), -ENODEV);
     411              : 
     412            6 :     if (desc->type == DB_MAP_MODE_HOST_VA) {
     413            3 :         return RsNdaDbUnmapHostVa(ndaCb, ptr, desc);
     414            3 :     } else if (desc->type == DB_MAP_MODE_UB_RES) {
     415            3 :         return RsNdaDbUnmapUbRes(ndaCb, ptr, desc);
     416              :     } else {
     417            0 :         hccp_err("invalid desc->type:%u, chipId:%u", desc->type, gRsCb->chipId);
     418            0 :         return -EINVAL;
     419              :     }
     420              : }
     421              : 
     422           32 : STATIC void RsNdaCbInitCb(struct RsNdaCb *ndaCb)
     423              : {
     424           32 :     ndaCb->ndaPcieCb.ibvExOps.alloc = RsNdaPcieAlloc;
     425           32 :     ndaCb->ndaPcieCb.ibvExOps.free = RsNdaPcieFree;
     426           32 :     ndaCb->ndaPcieCb.ibvExOps.db_mmap = RsNdaDbMmap;
     427           32 :     ndaCb->ndaPcieCb.ibvExOps.db_unmap = RsNdaDbUnmap;
     428           32 :     ndaCb->ndaPcieCb.ibvExOps.memset_s = RsNdaMemset;
     429           32 :     ndaCb->ndaPcieCb.ibvExOps.memcpy_s = RsNdaMemcpy;
     430              : 
     431           32 :     ndaCb->ndaUbCb.ibvExOps.alloc = RsNdaUbAlloc;
     432           32 :     ndaCb->ndaUbCb.ibvExOps.free = RsNdaUbFree;
     433           32 :     ndaCb->ndaUbCb.ibvExOps.db_mmap = RsNdaDbMmap;
     434           32 :     ndaCb->ndaUbCb.ibvExOps.db_unmap = RsNdaDbUnmap;
     435           32 :     ndaCb->ndaUbCb.ibvExOps.memset_s = RsNdaMemset;
     436           32 :     ndaCb->ndaUbCb.ibvExOps.memcpy_s = RsNdaMemcpy;
     437              : 
     438           32 :     RS_INIT_LIST_HEAD(&ndaCb->ndaPcieCb.ndaDbList);
     439           32 :     RS_INIT_LIST_HEAD(&ndaCb->ndaUbCb.ndaDbList);
     440           32 : }
     441              : 
     442           32 : int RsInitNdaCb(struct RsRdevCb *rdevCb)
     443              : {
     444           32 :     struct RsNdaCb *ndaCb = NULL;
     445           32 :     int count = 0;
     446           32 :     int ret = 0;
     447              : 
     448           32 :     rdevCb->directFlag = RsNdaGetDirectFlagByDevAttr(&rdevCb->deviceAttr);
     449              : 
     450           32 :     rdevCb->ibCtxEx = RsIbvOpenExtend(rdevCb->ibCtx);
     451           32 :     if (rdevCb->ibCtxEx == NULL) {
     452            0 :         hccp_warn("ibCtxEx is null");
     453            0 :         return 0;
     454              :     }
     455              : 
     456           32 :     count = __sync_fetch_and_add(&rdevCb->rsCb->ndaCbRefCnt, 1);
     457           32 :     if (count > 0) {
     458            0 :         hccp_info("RsNdaCb exist, ndaCbRefCnt:%d", rdevCb->rsCb->ndaCbRefCnt);
     459            0 :         return 0;
     460              :     }
     461              : 
     462           32 :     ndaCb = (struct RsNdaCb *)calloc(1, sizeof(struct RsNdaCb));
     463           32 :     if (ndaCb == NULL) {
     464            0 :         hccp_err("calloc for ndaCb failed");
     465            0 :         ret = -ENOMEM;
     466            0 :         goto calloc_err;
     467              :     }
     468              : 
     469           32 :     RsNdaCbInitCb(ndaCb);
     470              : 
     471           32 :     rdevCb->rsCb->ndaCb = (void *)ndaCb;
     472           32 :     return ret;
     473              : 
     474            0 : calloc_err:
     475            0 :     (void)__sync_fetch_and_sub(&rdevCb->rsCb->ndaCbRefCnt, 1);
     476            0 :     (void)RsIbvCloseExtend(rdevCb->ibCtxEx);
     477            0 :     rdevCb->ibCtxEx = NULL;
     478            0 :     return ret;
     479              : }
     480              : 
     481           32 : void RsDeinitNdaCb(struct RsRdevCb *rdevCb)
     482              : {
     483           32 :     if (rdevCb->ibCtxEx == NULL) {
     484            1 :         return;
     485              :     }
     486              : 
     487           31 :     (void)RsIbvCloseExtend(rdevCb->ibCtxEx);
     488           31 :     rdevCb->ibCtxEx = NULL;
     489              : 
     490           31 :     if (__sync_fetch_and_sub(&rdevCb->rsCb->ndaCbRefCnt, 1) > 1) {
     491            0 :         return;
     492              :     }
     493              : 
     494           31 :     free(rdevCb->rsCb->ndaCb);
     495           31 :     rdevCb->rsCb->ndaCb = NULL;
     496              : }
     497              : 
     498            4 : STATIC void RsNdaInitExOps(struct RsNdaCb *ndaCb, uint32_t dmaMode, struct NdaOps *ops, struct ibv_extend_ops **extOps)
     499              : {
     500            4 :     ndaCb->ndaOps.alloc = ops->alloc;
     501            4 :     ndaCb->ndaOps.free = ops->free;
     502            4 :     ndaCb->ndaOps.memset_s = ops->memset_s;
     503            4 :     ndaCb->ndaOps.memcpy_s = ops->memcpy_s;
     504            4 :     if (dmaMode == QBUF_DMA_MODE_DEFAULT) {
     505            2 :         *extOps = &ndaCb->ndaPcieCb.ibvExOps;
     506            2 :     } else if (dmaMode == QBUF_DMA_MODE_INDEP_UB) {
     507            2 :         *extOps = &ndaCb->ndaUbCb.ibvExOps;
     508              :     } else {
     509            0 :         *extOps = NULL;
     510              :     }
     511            4 : }
     512              : 
     513            2 : STATIC void RsNdaCqInitExPrepare(struct NdaCqInitAttr *attr, struct RsNdaCb *ndaCb,
     514              :     struct ibv_cq_init_attr_extend *cqInitAttrEx)
     515              : {
     516            2 :     (void)memcpy_s(&cqInitAttrEx->attr, sizeof(struct ibv_cq_init_attr_ex), &attr->attr,
     517              :         sizeof(struct ibv_cq_init_attr_ex));
     518            2 :     cqInitAttrEx->cq_cap_flag = attr->cqCapFlag;
     519            2 :     cqInitAttrEx->type = attr->dmaMode;
     520            2 :     RsNdaInitExOps(ndaCb, attr->dmaMode, attr->ops, &cqInitAttrEx->ops);
     521            2 : }
     522              : 
     523            1 : STATIC int RsNdaCqCreateEx(struct RsRdevCb *rdevCb, struct ibv_cq_init_attr_extend *cqInitAttrEx,
     524              :     struct NdaCqInfo *info, void **ibvCqExt)
     525              : {
     526            1 :     struct ibv_cq_extend *cqExt = NULL;
     527            1 :     int ret = 0;
     528              : 
     529            1 :     cqExt = RsIbvCreateCqExtend(rdevCb->ibCtxEx, cqInitAttrEx);
     530            1 :     CHK_PRT_RETURN(cqExt == NULL, hccp_err("RsNdaCreateCqExtend failed, errno:%d", errno), -ENOMEM);
     531              : 
     532            1 :     ret = memcpy_s(&info->cqInfo, sizeof(struct queueInfo), &cqExt->cq_info, sizeof(struct queue_info));
     533            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s queue_info failed, ret:%d", ret), -ESAFEFUNC);
     534            1 :     ret = memcpy_s(info->resv, sizeof(info->resv), cqExt->resv, sizeof(cqExt->resv));
     535            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s resv failed, ret:%d", ret), -ESAFEFUNC);
     536            1 :     info->cq = cqExt->cq;
     537            1 :     *ibvCqExt = cqExt;
     538            1 :     return 0;
     539              : }
     540              : 
     541            5 : RS_ATTRI_VISI_DEF int RsNdaCqCreate(unsigned int phyId, unsigned int rdevIndex, struct NdaCqInitAttr *attr,
     542              :     struct NdaCqInfo *info, void **ibvCqExt)
     543              : {
     544            5 :     struct ibv_cq_init_attr_extend cqInitAttrEx = {0};
     545            5 :     struct RsRdevCb *rdevCb = NULL;
     546            5 :     struct RsNdaCb *ndaCb = NULL;
     547            5 :     int ret = 0;
     548              : 
     549            5 :     CHK_PRT_RETURN(attr == NULL || info == NULL || ibvCqExt == NULL,
     550              :         hccp_err("attr or info or ibvCqExt is NULL, phyId:%u", phyId), -EINVAL);
     551            4 :     CHK_PRT_RETURN(attr->dmaMode >= QBUF_DMA_MODE_MAX,
     552              :         hccp_err("param err, dmaMode:%u >= %u, phyId:%u", attr->dmaMode, QBUF_DMA_MODE_MAX, phyId), -EINVAL);
     553              : 
     554            3 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
     555            3 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQueryRdevCb failed, phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret),
     556              :         ret);
     557              : 
     558            2 :     ndaCb = (struct RsNdaCb *)rdevCb->rsCb->ndaCb;
     559            2 :     CHK_PRT_RETURN(ndaCb == NULL, hccp_err("ndaCb is NULL, does not support nda, phyId:%u", phyId), -ENODEV);
     560              : 
     561            2 :     RsNdaCqInitExPrepare(attr, ndaCb, &cqInitAttrEx);
     562              : 
     563            2 :     ret = RsNdaCqCreateEx(rdevCb, &cqInitAttrEx, info, ibvCqExt);
     564            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsNdaCqCreateEx failed, phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret),
     565              :         ret);
     566              : 
     567            1 :     return ret;
     568              : }
     569              : 
     570            1 : RS_ATTRI_VISI_DEF int RsNdaCqDestroy(unsigned int phyId, unsigned int rdevIndex, void *ibvCqExt)
     571              : {
     572            1 :     struct RsRdevCb *rdevCb = NULL;
     573            1 :     int ret = 0;
     574              : 
     575            1 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
     576            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQueryRdevCb failed, phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret),
     577              :         ret);
     578              : 
     579            1 :     ret = RsIbvDestroyCqExtend(rdevCb->ibCtxEx, ibvCqExt);
     580            1 :     CHK_PRT_RETURN(ret != 0,
     581              :         hccp_err("RsIbvDestroyCqExtend failed, phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret), ret);
     582              : 
     583            1 :     return ret;
     584              : }
     585              : 
     586            2 : STATIC int RsBuildUpNdaQpcb(struct RsRdevCb *rdevCb, struct ibv_qp_init_attr *qpInitAttr, struct RsQpCb **qpCb)
     587              : {
     588            2 :     int ret = 0;
     589              : 
     590            2 :     *qpCb = (struct RsQpCb *)calloc(1, sizeof(struct RsQpCb));
     591            2 :     CHK_PRT_RETURN(*qpCb == NULL, hccp_err("RsQpCb calloc failed"), -ENOMEM);
     592              : 
     593            2 :     ret = pthread_mutex_init(&(*qpCb)->qpMutex, NULL);
     594            2 :     if (ret != 0) {
     595            0 :         hccp_err("pthread_mutex_init failed, ret:%d", ret);
     596            0 :         goto qp_mutex_init_err;
     597              :     }
     598              : 
     599            2 :     (*qpCb)->rdevCb = rdevCb;
     600            2 :     RS_INIT_LIST_HEAD(&(*qpCb)->mrList);
     601            2 :     RS_INIT_LIST_HEAD(&(*qpCb)->remMrList);
     602            2 :     (*qpCb)->state = RS_QP_STATUS_DISCONNECT;
     603            2 :     (*qpCb)->ibPd = rdevCb->ibPd;
     604            2 :     (*qpCb)->txDepth = qpInitAttr->cap.max_send_wr;
     605            2 :     (*qpCb)->rxDepth = qpInitAttr->cap.max_recv_wr;
     606              : 
     607            2 :     (*qpCb)->numRecvCqEvents = 0;
     608            2 :     (*qpCb)->numSendCqEvents = 0;
     609            2 :     (*qpCb)->qosAttr.tc = (RS_ROCE_DSCP_33 & RS_DSCP_MASK) << RS_DSCP_OFF;
     610            2 :     (*qpCb)->qosAttr.sl = RS_ROCE_4_SL;
     611            2 :     (*qpCb)->timeout = RS_QP_ATTR_TIMEOUT;
     612            2 :     (*qpCb)->retryCnt = RS_QP_ATTR_RETRY_CNT;
     613              : 
     614            2 :     return ret;
     615              : 
     616            0 : qp_mutex_init_err:
     617            0 :     free(*qpCb);
     618            0 :     *qpCb = NULL;
     619            0 :     return ret;
     620              : }
     621              : 
     622            2 : STATIC void RsNdaQpInitExPrepare(struct RsRdevCb *rdevCb, struct NdaQpInitAttr *attr,
     623              :     struct ibv_qp_init_attr_extend *qpInitAttrEx)
     624              : {
     625            2 :     struct RsNdaCb *ndaCb = (struct RsNdaCb *)rdevCb->rsCb->ndaCb;
     626              : 
     627            2 :     qpInitAttrEx->pd = rdevCb->ibPd;
     628            2 :     (void)memcpy_s(&qpInitAttrEx->attr, sizeof(struct ibv_qp_init_attr), &attr->attr, sizeof(struct ibv_qp_init_attr));
     629            2 :     qpInitAttrEx->qp_cap_flag = attr->qpCapFlag;
     630            2 :     qpInitAttrEx->type = attr->dmaMode;
     631            2 :     RsNdaInitExOps(ndaCb, attr->dmaMode, attr->ops, &qpInitAttrEx->ops);
     632            2 : }
     633              : 
     634            1 : STATIC int RsNdaQpGetQpInfo(struct RsQpCb *qpCb, struct NdaQpInfo *info)
     635              : {
     636            1 :     int ret = 0;
     637              : 
     638            1 :     info->qp = qpCb->ibQp;
     639            1 :     ret = memcpy_s(&info->sqInfo, sizeof(struct queueInfo), &qpCb->ibQpEx->sq_info, sizeof(struct queue_info));
     640            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s sq_info failed, ret:%d", ret), -ESAFEFUNC);
     641            1 :     ret = memcpy_s(&info->rqInfo, sizeof(struct queueInfo), &qpCb->ibQpEx->rq_info, sizeof(struct queue_info));
     642            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s rq_info failed, ret:%d", ret), -ESAFEFUNC);
     643            1 :     ret = memcpy_s(info->resv, sizeof(info->resv), qpCb->ibQpEx->resv, sizeof(qpCb->ibQpEx->resv));
     644            1 :     CHK_PRT_RETURN(ret != 0, hccp_err("memcpy_s resv failed, ret:%d", ret), -ESAFEFUNC);
     645              : 
     646            1 :     return ret;
     647              : }
     648              : 
     649            3 : STATIC int RsNdaQpCreateEx(struct RsQpCb *qpCb, struct ibv_qp_init_attr_extend *qpInitAttrEx, struct NdaQpInfo *info)
     650              : {
     651            3 :     struct ibv_qp_attr qpAttr = {0};
     652            3 :     struct ibv_port_attr attr = {0};
     653            3 :     struct RsRdevCb *rdevCb = NULL;
     654            3 :     int ret = 0;
     655              : 
     656            3 :     rdevCb = qpCb->rdevCb;
     657            3 :     qpCb->ibQpEx = RsIbvCreateQpExtend(rdevCb->ibCtxEx, qpInitAttrEx);
     658            3 :     CHK_PRT_RETURN(qpCb->ibQpEx == NULL, hccp_err("RsNdaCreateQpExtend failed, errno:%d", errno), -ENOMEM);
     659              : 
     660            3 :     qpCb->ibQp = qpCb->ibQpEx->qp;
     661            3 :     ret = RsIbvQueryQp(qpCb->ibQp, &qpAttr, IBV_QP_CAP, &qpInitAttrEx->attr);
     662            3 :     if (ret != 0) {
     663            1 :         hccp_err("query qp attr failed ret:%d", ret);
     664            1 :         ret = -EOPENSRC;
     665            1 :         goto nda_init_qp_err;
     666              :     }
     667              : 
     668            2 :     ret = RsDrvQpInfoRelated(qpCb, rdevCb, &attr, &qpAttr);
     669            2 :     if (ret != 0) {
     670            1 :         hccp_err("qp info related failed ret:%d", ret);
     671            1 :         goto nda_init_qp_err;
     672              :     }
     673              : 
     674            1 :     ret = RsNdaQpGetQpInfo(qpCb, info);
     675            1 :     if (ret != 0) {
     676            0 :         hccp_err("RsNdaQpGetQpInfo failed ret:%d", ret);
     677            0 :         goto nda_init_qp_err;
     678              :     }
     679              : 
     680            1 :     hccp_info("chip_id:%u, rdevIndex:%u, qp:%d create succ", rdevCb->rsCb->chipId, rdevCb->rdevIndex,
     681              :         qpCb->qpInfoLo.qpn);
     682            1 :     return ret;
     683              : 
     684            2 : nda_init_qp_err:
     685            2 :     (void)RsIbvDestroyQpExtend(rdevCb->ibCtxEx, qpCb->ibQpEx);
     686            2 :     qpCb->ibQpEx = NULL;
     687            2 :     return ret;
     688              : }
     689              : 
     690            5 : RS_ATTRI_VISI_DEF int RsNdaQpCreate(unsigned int phyId, unsigned int rdevIndex, struct NdaQpInitAttr *attr,
     691              :     struct NdaQpInfo *info, struct RsQpResp *qpResp)
     692              : {
     693            5 :     struct ibv_qp_init_attr_extend qpInitAttrEx = {0};
     694            5 :     struct RsRdevCb *rdevCb = NULL;
     695            5 :     struct RsNdaCb *ndaCb = NULL;
     696            5 :     struct RsQpCb *qpCb = NULL;
     697            5 :     int ret = 0;
     698              : 
     699            5 :     CHK_PRT_RETURN(attr == NULL || info == NULL || qpResp == NULL,
     700              :         hccp_err("attr or info or qpResp is NULL, phyId:%u", phyId), -EINVAL);
     701            4 :     CHK_PRT_RETURN(attr->dmaMode >= QBUF_DMA_MODE_MAX,
     702              :         hccp_err("param err, dmaMode:%u >= %u, phyId:%u", attr->dmaMode, QBUF_DMA_MODE_MAX, phyId), -EINVAL);
     703              : 
     704            3 :     ret = RsQueryRdevCb(phyId, rdevIndex, &rdevCb);
     705            3 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsQueryRdevCb phyId:%u rdevIndex:%u ret:%d", phyId, rdevIndex, ret), ret);
     706              : 
     707            2 :     ndaCb = (struct RsNdaCb *)rdevCb->rsCb->ndaCb;
     708            2 :     CHK_PRT_RETURN(ndaCb == NULL, hccp_err("ndaCb is NULL, phyId:%u rdevIndex:%u", phyId, rdevIndex), -ENODEV);
     709              : 
     710            2 :     ret = RsBuildUpNdaQpcb(rdevCb, &attr->attr, &qpCb);
     711            2 :     CHK_PRT_RETURN(ret != 0, hccp_err("RsBuildUpNdaQpcb failed, ret:%d", ret), ret);
     712              : 
     713            2 :     RsNdaQpInitExPrepare(rdevCb, attr, &qpInitAttrEx);
     714              : 
     715            2 :     ret = RsNdaQpCreateEx(qpCb, &qpInitAttrEx, info);
     716            2 :     if (ret != 0) {
     717            1 :         hccp_err("create nda qp create extend failed, ret:%d", ret);
     718            1 :         goto create_qp_err;
     719              :     }
     720              : 
     721            1 :     RS_PTHREAD_MUTEX_LOCK(&rdevCb->rdevMutex);
     722            1 :     RsListAddTail(&qpCb->list, &rdevCb->qpList);
     723            1 :     rdevCb->qpCnt++;
     724            1 :     RS_PTHREAD_MUTEX_ULOCK(&rdevCb->rdevMutex);
     725            1 :     qpResp->qpn = (unsigned int)qpCb->qpInfoLo.qpn;
     726            1 :     qpResp->gidIdx = (unsigned int)qpCb->qpInfoLo.gidIdx;
     727            1 :     qpResp->psn = (unsigned int)qpCb->qpInfoLo.psn;
     728            1 :     qpResp->gid = qpCb->qpInfoLo.gid;
     729            1 :     qpResp->directFlag = rdevCb->directFlag;
     730            1 :     return 0;
     731              : 
     732            1 : create_qp_err:
     733            1 :     pthread_mutex_destroy(&qpCb->qpMutex);
     734            1 :     free(qpCb);
     735            1 :     qpCb = NULL;
     736            1 :     return ret;
     737              : }
     738              : 
     739            1 : RS_ATTRI_VISI_DEF int RsNdaQpDestroy(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn)
     740              : {
     741            1 :     struct RsQpCb *qpCb = NULL;
     742            1 :     int ret = 0;
     743              : 
     744            1 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
     745            1 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_err("get qp cb failed, qpn:%u, ret:%d", qpn, ret), ret);
     746              : 
     747            1 :     RS_PTHREAD_MUTEX_LOCK(&qpCb->rdevCb->rdevMutex);
     748            1 :     RsListDel(&qpCb->list);
     749            1 :     qpCb->rdevCb->qpCnt--;
     750            1 :     RS_PTHREAD_MUTEX_ULOCK(&qpCb->rdevCb->rdevMutex);
     751              : 
     752            1 :     RsMrRelease(qpCb);
     753              : 
     754            1 :     ret = RsIbvDestroyQpExtend(qpCb->rdevCb->ibCtxEx, qpCb->ibQpEx);
     755            1 :     if (ret != 0) {
     756            0 :         hccp_err("qp:%u destroy extend failed, ret:%d", qpn, ret);
     757              :     }
     758            1 :     qpCb->ibQpEx = NULL;
     759              : 
     760            1 :     pthread_mutex_destroy(&qpCb->qpMutex);
     761              : 
     762            1 :     free(qpCb);
     763            1 :     qpCb = NULL;
     764            1 :     return ret;
     765              : }
     766              : 
     767            6 : RS_ATTRI_VISI_DEF int RsGetQpHyperFeature(unsigned int phyId, unsigned int rdevIndex, unsigned int qpn,
     768              :     struct HyperFeature *hyperFeature)
     769              : {
     770            6 :     struct ibv_hyroce_feature feature = {0};
     771            6 :     struct RsQpCb *qpCb = NULL;
     772            6 :     int ret = 0;
     773              : 
     774            6 :     CHK_PRT_RETURN(hyperFeature == NULL, hccp_warn("hyperFeature is NULL, phyId:%u", phyId), ret);
     775              : 
     776            6 :     ret = RsQpn2qpcb(phyId, rdevIndex, qpn, &qpCb);
     777            6 :     CHK_PRT_RETURN(ret != 0 || qpCb == NULL, hccp_warn("get qp cb unsuccessful qpn %u, ret %d", qpn, ret), ret);
     778              : 
     779            4 :     if (qpCb->rdevCb->ibCtxEx == NULL) {
     780            1 :         return 0;
     781              :     }
     782              : 
     783            3 :     ret = RsIbvQueryQpSupportedHyroceFeature(qpCb->rdevCb->ibCtxEx, qpCb->ibQp, qpCb->qosAttr.sl, qpCb->qosAttr.tc,
     784              :         &feature);
     785            3 :     CHK_PRT_RETURN(ret != 0,
     786              :         hccp_warn("RsIbvQueryQpSupportedHyroceFeature unsuccessful, qpn %u ret %d errno:%d", qpn, ret, errno), ret);
     787              : 
     788            2 :     ret = memcpy_s(hyperFeature, sizeof(struct HyperFeature), &feature, sizeof(struct ibv_hyroce_feature));
     789            2 :     CHK_PRT_RETURN(ret != 0,
     790              :         hccp_warn("memcpy_s feature unsuccessful, qpn:%u ret:%d HyperFeature len:%zu "
     791              :                   "ibv_hyroce_feature len:%zu",
     792              :             qpn, ret, sizeof(struct HyperFeature), sizeof(struct ibv_hyroce_feature)),
     793              :         ret);
     794              : 
     795            1 :     hccp_dbg("get QpHyperFeature successful qpn %u", qpn);
     796            1 :     return ret;
     797              : }
        

Generated by: LCOV version 2.0-1