X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=o-du%2Fphy.git;a=blobdiff_plain;f=fhi_lib%2Flib%2Fsrc%2Fxran_cp_proc.c;fp=fhi_lib%2Flib%2Fsrc%2Fxran_cp_proc.c;h=789c6fdf963ec115f1dc8bf8c3fe0c7176c8f6c6;hp=e40ce7256752a4f3f470ef32dd8c6f600170e706;hb=892daba4c616407f16506415d5a69549519ef11d;hpb=76b4495d593ccf45d712db1a3ec96fa9d2d8f5f5 diff --git a/fhi_lib/lib/src/xran_cp_proc.c b/fhi_lib/lib/src/xran_cp_proc.c index e40ce72..789c6fd 100644 --- a/fhi_lib/lib/src/xran_cp_proc.c +++ b/fhi_lib/lib/src/xran_cp_proc.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "xran_fh_o_du.h" @@ -60,7 +61,6 @@ #include "xran_dev.h" #include "xran_frame_struct.h" #include "xran_printf.h" -#include "xran_app_frag.h" #include "xran_cp_proc.h" #include "xran_tx_proc.h" @@ -76,9 +76,11 @@ struct xran_recv_packet_info parse_recv[XRAN_PORTS_NUM]; ////////////////////////////////////////// // For RU emulation -struct xran_section_recv_info *recvSections[XRAN_PORTS_NUM] = {NULL,NULL,NULL,NULL}; +struct xran_section_recv_info *recvSections[XRAN_PORTS_NUM] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; struct xran_cp_recv_params recvCpInfo[XRAN_PORTS_NUM]; +extern int32_t first_call; + static void extbuf_free_callback(void *addr __rte_unused, void *opaque __rte_unused) { @@ -141,14 +143,14 @@ xran_init_seqid(void *pHandle) int32_t process_cplane(struct rte_mbuf *pkt, void* handle) { + uint32_t mb_free = MBUF_FREE; struct xran_device_ctx * p_xran_dev_ctx = (struct xran_device_ctx *)handle; - if(p_xran_dev_ctx) { + if(p_xran_dev_ctx && xran_if_current_state == XRAN_RUNNING) { if(xran_dev_get_ctx_by_id(0)->fh_cfg.debugStop) /* check CP with standard tests only */ - xran_parse_cp_pkt(pkt, &recvCpInfo[p_xran_dev_ctx->xran_port_id], &parse_recv[p_xran_dev_ctx->xran_port_id]); + xran_parse_cp_pkt(pkt, &recvCpInfo[p_xran_dev_ctx->xran_port_id], &parse_recv[p_xran_dev_ctx->xran_port_id],(void*)p_xran_dev_ctx, &mb_free); } - - return (MBUF_FREE); + return (mb_free); } int32_t @@ -188,23 +190,21 @@ xran_check_symbolrange(int symbol_type, uint32_t PortId, int cc_id, int tti, } struct rte_mbuf * -xran_attach_cp_ext_buf(uint16_t vf_id, int8_t* p_ext_buff_start, int8_t* p_ext_buff, uint16_t ext_buff_len, +xran_attach_cp_ext_buf(uint16_t vf_id, int8_t* p_ext_buff_start/*ext_start*/, int8_t* p_ext_buff/*ext-section*/, uint16_t ext_buff_len, struct rte_mbuf_ext_shared_info * p_share_data) { struct rte_mbuf *mb_oran_hdr_ext = NULL; - struct rte_mbuf *tmp = NULL; + //struct rte_mbuf *tmp = NULL; int8_t *ext_buff = NULL; rte_iova_t ext_buff_iova = 0; ext_buff = p_ext_buff - (RTE_PKTMBUF_HEADROOM + sizeof(struct xran_ecpri_hdr) + - sizeof(struct xran_cp_radioapp_section1_header) + - sizeof(struct xran_cp_radioapp_section1)); + sizeof(struct xran_cp_radioapp_section1_header)); ext_buff_len += (RTE_PKTMBUF_HEADROOM + sizeof(struct xran_ecpri_hdr) + - sizeof(struct xran_cp_radioapp_section1_header) + - sizeof(struct xran_cp_radioapp_section1)) + 18; + sizeof(struct xran_cp_radioapp_section1_header) + 18); // mb_oran_hdr_ext = rte_pktmbuf_alloc(_eth_mbuf_pool_small); mb_oran_hdr_ext = xran_ethdi_mbuf_indir_alloc(); @@ -237,59 +237,154 @@ xran_attach_cp_ext_buf(uint16_t vf_id, int8_t* p_ext_buff_start, int8_t* p_ext_b return mb_oran_hdr_ext; } +/* TO DO: __thread is slow. We should allocate global 2D array and index it using current core index + * for better performance. + */ +__thread struct xran_section_gen_info sect_geninfo[XRAN_MAX_SECTIONS_PER_SLOT]; + int32_t xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id, - struct xran_prb_map *prbMap, enum xran_category category, uint8_t ctx_id) + struct xran_prb_map *prbMap, struct xran_prb_elm_proc_info_t *prbElmProcInfo, enum xran_category category, uint8_t ctx_id) { int32_t ret = 0; struct xran_device_ctx *p_x_ctx = (struct xran_device_ctx *)pHandle; struct xran_common_counters *pCnt = &p_x_ctx->fh_counters; struct xran_cp_gen_params params; - struct xran_section_gen_info sect_geninfo[1]; struct rte_mbuf *mbuf; uint32_t interval = p_x_ctx->interval_us_local; uint8_t PortId = p_x_ctx->xran_port_id; + int16_t numCPSections=0, ext_offset=0, start_sect_id=0; - - uint32_t i, j, loc_sym; + uint32_t i, j, loc_sym,idx; uint32_t nsection = 0; struct xran_prb_elm *pPrbMapElem = NULL; - struct xran_prb_elm *pPrbMapElemPrev = NULL; + // struct xran_prb_elm *pPrbMapElemPrev = NULL; uint32_t slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME(interval)); uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME(interval), SUBFRAMES_PER_SYSTEMFRAME); uint32_t frame_id = XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME(interval)); uint8_t seq_id = 0; - uint16_t vf_id = 0; + uint16_t vf_id = 0 , curr_sec_id = 0 , prb_per_section, start_Prb; + int32_t startSym = 0, numSyms = 0; - int next; + int next=0; struct xran_sectionext1_info ext1; struct xran_sectionext4_info ext4 = {0}; + struct xran_sectionext9_info ext9; struct xran_sectionext11_info ext11; - //frame_id = (frame_id & 0xff); /* ORAN frameId, 8 bits, [0, 255] */ - frame_id = ((frame_id + ((0 == tti)?NUM_OF_FRAMES_PER_SECOND:0)) & 0xff); /* ORAN frameId, 8 bits, [0, 255] */ + frame_id = (frame_id & 0xff); /* ORAN frameId, 8 bits, [0, 255] */ + if(unlikely((category != XRAN_CATEGORY_A) && (category != XRAN_CATEGORY_B))) + { + print_err("Unsupported Category %d\n", category); + return (-1); + } + + /* Generate a C-Plane message per each section, + * not a C-Plane message with multi sections */ + if(0 == p_x_ctx->RunSlotPrbMapBySymbolEnable) + { if(prbMap) { + + nsection = prbMap->nPrbElm; + i=0; + if(XRAN_DIR_DL == dir) + { + if(0 == p_x_ctx->numSymsForDlCP) + { + print_dbg("No symbol available for DL CP transmission\n"); + return (-1); + } + + if(prbMap->nPrbElm == prbElmProcInfo->nPrbElmProcessed && 0 != prbElmProcInfo->numSymsRemaining) + { + prbElmProcInfo->numSymsRemaining--; + print_dbg("All sections already processed\n"); + return (-1); + } + + if(0== prbElmProcInfo->numSymsRemaining) + { /* new slot */ + prbElmProcInfo->numSymsRemaining = p_x_ctx->numSymsForDlCP; + prbElmProcInfo->nPrbElmPerSym = prbMap->nPrbElm/p_x_ctx->numSymsForDlCP; + prbElmProcInfo->nPrbElmProcessed = 0; + } + + if(1 == prbElmProcInfo->numSymsRemaining) + {/* last symbol:: send all remaining */ nsection = prbMap->nPrbElm; + } + else + { + if(0 == prbElmProcInfo->nPrbElmPerSym) + nsection=prbElmProcInfo->nPrbElmProcessed + 1; + else + nsection = prbElmProcInfo->nPrbElmProcessed + prbElmProcInfo->nPrbElmPerSym; + } + + i=prbElmProcInfo->nPrbElmProcessed; + prbElmProcInfo->numSymsRemaining--; + + } //dir = DL + else + { + nsection = prbMap->nPrbElm; + i=0; + } //dir = UL + pPrbMapElem = &prbMap->prbMap[0]; - } else { + } + else + { print_err("prbMap is NULL\n"); return (-1); } + + curr_sec_id = 0; + if(pPrbMapElem->bf_weight.extType == 1) + { + for(j=0;jprbMap[j].bf_weight.numSetBFWs; + } + else + curr_sec_id = i; + + // start_id=curr_sec_id; + uint8_t generateCpPkt=0; + uint8_t replacePrbStartNSize=0; /* In case of application fragmentation, we send 1 cplane packets for multiple + uplane packets i.e. 1 cp packet for multiple PRBs. This flag is used to + achieve that by setting different values for cp packet preparation and for + cp-up database update */ + /* Generate a C-Plane message per each section, * not a C-Plane message with multi sections */ - for (i = 0; i < nsection; i++) { + for (; i < nsection; i++) { int startSym, numSyms; pPrbMapElem = &prbMap->prbMap[i]; + prb_per_section = pPrbMapElem->bf_weight.numBundPrb; + start_Prb = pPrbMapElem->nRBStart; + + if((pPrbMapElem->bf_weight.extType == 1) && + (((i+1)prbMap[i+1].IsNewSect==1) || + (i+1) == nsection)) + { /*ext1*/ + generateCpPkt=1; + } + else if(pPrbMapElem->IsNewSect) + generateCpPkt=1; + else + generateCpPkt=0; + /* For Special Subframe, * Check validity of given symbol range with slot configuration * and adjust symbol range accordingly. */ if(xran_fs_get_slot_type(PortId, cc_id, tti, XRAN_SLOT_TYPE_FDD) != 1 - && xran_fs_get_slot_type(PortId, cc_id, tti, XRAN_SLOT_TYPE_SP) == 1) { + && xran_fs_get_slot_type(PortId, cc_id, tti, XRAN_SLOT_TYPE_SP) == 1) + { /* This function cannot handle two or more groups of consecutive same type of symbol. * If there are two or more, then it might cause an error */ startSym = xran_check_symbolrange( @@ -297,7 +392,8 @@ xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int PortId, cc_id, tti, pPrbMapElem->nStartSymb, pPrbMapElem->numSymb, &numSyms); - if(startSym < 0 || numSyms == 0) { + if(startSym < 0 || numSyms == 0) + { /* if start symbol is not valid, then skip this section */ print_err("Skip section %d due to invalid symbol range - [%d:%d], [%d:%d]", i, @@ -305,7 +401,9 @@ xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int startSym, numSyms); continue; } - } else { + } + else + { startSym = pPrbMapElem->nStartSymb; numSyms = pPrbMapElem->numSymb; } @@ -324,135 +422,189 @@ xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int print_dbg("cp[%d:%d:%d] ru_port_id %d dir=%d\n", frame_id, subframe_id, slot_id, ru_port_id, dir); - seq_id = xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ru_port_id); - - sect_geninfo[0].info.type = params.sectionType; - sect_geninfo[0].info.startSymId = params.hdr.startSymId; - sect_geninfo[0].info.iqWidth = params.hdr.iqWidth; - sect_geninfo[0].info.compMeth = params.hdr.compMeth; - - sect_geninfo[0].info.id = i; /* do not revert 'i' to - xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id); */ - - if(sect_geninfo[0].info.id > XRAN_MAX_SECTIONS_PER_SLOT) - print_err("sectinfo->id %d\n", sect_geninfo[0].info.id); -#if 0 - if (dir == XRAN_DIR_UL) { - for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) { - int32_t sec_desc_idx = pPrbMapElem->nSecDesc[loc_sym]; - struct xran_section_desc *p_sec_desc = pPrbMapElem->p_sec_desc[loc_sym][0]; - if(p_sec_desc) { - p_sec_desc->section_id = sect_geninfo[0].info.id; - if(p_sec_desc->pCtrl) { - rte_pktmbuf_free(p_sec_desc->pCtrl); - p_sec_desc->pCtrl = NULL; - p_sec_desc->pData = NULL; + if(pPrbMapElem->bf_weight.extType == 1) + { + /* Send multiple CP sections per prbElement for ext-1 */ + numCPSections = pPrbMapElem->bf_weight.numSetBFWs; + } + else + { + numCPSections = 1; + replacePrbStartNSize = 1; /* in case of no app fragmentation, UP_nRBSize will be same as nRBSize. So, + always replacing the elements when ext1 is not in use */ + } + + /** Prepare section info for multiple sections in a PRB element */ + for(idx=0; idx < numCPSections; idx++) { + + sect_geninfo[curr_sec_id].exDataSize=0; + sect_geninfo[curr_sec_id].info = xran_cp_get_section_info_ptr(pHandle, dir, cc_id, ru_port_id, ctx_id); + if(unlikely(sect_geninfo[curr_sec_id].info == NULL)) + { + rte_panic("xran_cp_get_section_info_ptr failed\n"); } + + struct xran_section_info *info = sect_geninfo[curr_sec_id].info; + info->prbElemBegin = (idx == 0 ) ? 1 : 0; + info->prbElemEnd = (idx + 1 == numCPSections) ? 1 : 0; + info->ef = 0; + info->freqOffset = 0; + info->ueId = 0; + info->regFactor = 0; + + if((idx+1)*prb_per_section > pPrbMapElem->nRBSize){ + prb_per_section = pPrbMapElem->nRBSize - idx*prb_per_section; } - else { - print_err("section desc is NULL\n"); + + if(numCPSections == 1) + { + info->startPrbc = pPrbMapElem->nRBStart; + info->numPrbc = pPrbMapElem->nRBSize; } - sec_desc_idx--; - pPrbMapElem->nSecDesc[loc_sym] = 0; + else + { + info->startPrbc = start_Prb; + info->numPrbc = prb_per_section; + start_Prb += prb_per_section; } + + info->type = params.sectionType; + info->startSymId = params.hdr.startSymId; + info->iqWidth = params.hdr.iqWidth; + info->compMeth = params.hdr.compMeth; + info->id = curr_sec_id; + + if(info->prbElemBegin && pPrbMapElem->IsNewSect==1) + { + start_sect_id = info->id; } -#endif - sect_geninfo[0].info.rb = XRAN_RBIND_EVERY; - sect_geninfo[0].info.startPrbc = pPrbMapElem->nRBStart; - sect_geninfo[0].info.numPrbc = pPrbMapElem->nRBSize; - sect_geninfo[0].info.numSymbol = numSyms; - sect_geninfo[0].info.reMask = 0xfff; - sect_geninfo[0].info.beamId = pPrbMapElem->nBeamIndex; - sect_geninfo[0].info.symInc = XRAN_SYMBOLNUMBER_NOTINC; - - for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) { - struct xran_section_desc *p_sec_desc = pPrbMapElem->p_sec_desc[loc_sym][0]; - if(p_sec_desc) { - p_sec_desc->section_id = sect_geninfo[0].info.id; - - sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_offset = p_sec_desc->iq_buffer_offset; - sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_len = p_sec_desc->iq_buffer_len; - } else { - print_err("section desc is NULL\n"); + if(unlikely(info->id > XRAN_MAX_SECTIONS_PER_SLOT)) + print_err("sectinfo->id %d\n", info->id); + + info->rb = XRAN_RBIND_EVERY; + info->numSymbol = numSyms; + info->reMask = 0xfff; + info->beamId = pPrbMapElem->nBeamIndex; + info->symInc = XRAN_SYMBOLNUMBER_NOTINC; + + for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) + { + struct xran_section_desc *p_sec_desc = &pPrbMapElem->sec_desc[loc_sym][0]; + + if(p_sec_desc) + { + info->sec_desc[loc_sym].iq_buffer_offset = p_sec_desc->iq_buffer_offset; + info->sec_desc[loc_sym].iq_buffer_len = p_sec_desc->iq_buffer_len; + + p_sec_desc->section_id = info->id; } + else + { + print_err("section desc is NULL\n"); } - if(unlikely((category != XRAN_CATEGORY_A) && (category != XRAN_CATEGORY_B))) { - print_err("Unsupported Category %d\n", category); - return (-1); - } + } /* for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) */ /* Add extentions if required */ + if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) + { + if(pPrbMapElem->bf_weight.extType == 1) /* Prepare section data for ext-1 */ + { next = 0; - sect_geninfo[0].exDataSize = 0; + sect_geninfo[curr_sec_id].exDataSize = 0; + memset(&ext1, 0, sizeof (struct xran_sectionext1_info)); + ext1.bfwNumber = pPrbMapElem->bf_weight.nAntElmTRx; + ext1.bfwIqWidth = pPrbMapElem->iqWidth; + ext1.bfwCompMeth = pPrbMapElem->compMethod; + /* ext-1 buffer contains CP sections */ + ext1.bfwIQ_sz = ONE_EXT_LEN(pPrbMapElem); //76 + + ext_offset = (idx*ONE_CPSEC_EXT_LEN(pPrbMapElem)) + sizeof(struct xran_cp_radioapp_section1); + ext1.p_bfwIQ = (int8_t*)(pPrbMapElem->bf_weight.p_ext_section + ext_offset); + + sect_geninfo[curr_sec_id].exData[next].type = XRAN_CP_SECTIONEXTCMD_1; + sect_geninfo[curr_sec_id].exData[next].len = sizeof(ext1); + sect_geninfo[curr_sec_id].exData[next].data = &ext1; + + info->ef = 1; + sect_geninfo[curr_sec_id].exDataSize++; + next++; + } + else + { + /*ext-11*/ + } + + } /* if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) */ + + curr_sec_id++; + } /* for(idx=0; idx < numCPSections;idx++) */ + + if (dir==XRAN_DIR_UL || generateCpPkt) //only send actual new CP section + { /* Extension 4 for modulation compression */ - if(pPrbMapElem->compMethod == XRAN_COMPMETHOD_MODULATION) { + if(pPrbMapElem->compMethod == XRAN_COMPMETHOD_MODULATION) + { mbuf = xran_ethdi_mbuf_alloc(); ext4.csf = 0; //no shift for now only ext4.modCompScaler = pPrbMapElem->ScaleFactor; + /* TO DO: Should this be the current section id? */ sect_geninfo[0].exData[next].type = XRAN_CP_SECTIONEXTCMD_4; sect_geninfo[0].exData[next].len = sizeof(ext4); sect_geninfo[0].exData[next].data = &ext4; - sect_geninfo[0].info.ef = 1; + sect_geninfo[0].info->ef = 1; sect_geninfo[0].exDataSize++; next++; } /* Extension 1 or 11 for Beam forming weights */ - if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) { - /* add extantion section for BF Weights if update is needed */ - if(pPrbMapElem->bf_weight.numBundPrb == 0) { - /* No bundled PRBs, using Extension 1 */ - struct rte_mbuf_ext_shared_info * p_share_data = &p_x_ctx->cp_share_data.sh_data[tti % XRAN_N_FE_BUF_LEN][cc_id][ru_port_id][sect_geninfo[0].info.id]; - - /*add extention section for BF Weights if update is needed */ - if(pPrbMapElem->bf_weight.p_ext_start) { + /* add section extention for BF Weights if update is needed */ + if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) + { + if(pPrbMapElem->bf_weight.extType == 1) /* Using Extension 1 */ + { + //TODO: Should this change ? + struct rte_mbuf_ext_shared_info * p_share_data = + &p_x_ctx->cp_share_data.sh_data[tti % XRAN_N_FE_BUF_LEN][cc_id][ru_port_id][sect_geninfo[0].info->id]; + + if(pPrbMapElem->bf_weight.p_ext_start) + { /* use buffer with BF Weights for mbuf */ mbuf = xran_attach_cp_ext_buf(vf_id, pPrbMapElem->bf_weight.p_ext_start, pPrbMapElem->bf_weight.p_ext_section, pPrbMapElem->bf_weight.ext_section_sz, p_share_data); - } else { + } + else + { print_err("p %d cc %d dir %d Alloc fail!\n", PortId, cc_id, dir); - return (-1); + ret=-1; + goto _create_and_send_section_error; } - - memset(&ext1, 0, sizeof (struct xran_sectionext1_info)); - ext1.bfwNumber = pPrbMapElem->bf_weight.nAntElmTRx; - ext1.bfwIqWidth = pPrbMapElem->iqWidth; - ext1.bfwCompMeth = pPrbMapElem->compMethod; - ext1.p_bfwIQ = (int16_t*)pPrbMapElem->bf_weight.p_ext_section; - ext1.bfwIQ_sz = pPrbMapElem->bf_weight.ext_section_sz; - - sect_geninfo[0].exData[next].type = XRAN_CP_SECTIONEXTCMD_1; - sect_geninfo[0].exData[next].len = sizeof(ext1); - sect_geninfo[0].exData[next].data = &ext1; - - sect_geninfo[0].info.ef = 1; - sect_geninfo[0].exDataSize++; - next++; - } else { /* if(pPrbMapElem->bf_weight.numBundPrb == 0) */ + } /* if(pPrbMapElem->bf_weight.extType == 1) */ + else + { /* Using Extension 11 */ struct rte_mbuf_ext_shared_info *shared_info; + next = 0; - shared_info = &p_x_ctx->bfw_share_data.sh_data[tti % XRAN_N_FE_BUF_LEN][cc_id][ru_port_id][sect_geninfo[0].info.id]; - - + shared_info = &p_x_ctx->bfw_share_data.sh_data[tti % XRAN_N_FE_BUF_LEN][cc_id][ru_port_id][sect_geninfo[0].info->id]; shared_info->free_cb = NULL; shared_info->fcb_opaque = NULL; mbuf = xran_ethdi_mbuf_indir_alloc(); if(unlikely(mbuf == NULL)) { rte_panic("Alloc fail!\n"); - return (-1); } //mbuf = rte_pktmbuf_alloc(_eth_mbuf_pool_vf_small[vf_id]); - if(xran_cp_attach_ext_buf(mbuf, (uint8_t *)pPrbMapElem->bf_weight.p_ext_start, pPrbMapElem->bf_weight.maxExtBufSize, shared_info) < 0) { + if(xran_cp_attach_ext_buf(mbuf, (uint8_t *)pPrbMapElem->bf_weight.p_ext_start, pPrbMapElem->bf_weight.maxExtBufSize, shared_info) < 0) + { rte_pktmbuf_free(mbuf); - return (-1); + ret=-1; + goto _create_and_send_section_error; } rte_mbuf_ext_refcnt_update(shared_info, 0); @@ -476,29 +628,64 @@ xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int sect_geninfo[0].exData[next].len = sizeof(ext11); sect_geninfo[0].exData[next].data = &ext11; - sect_geninfo[0].info.ef = 1; + sect_geninfo[0].info->ef = 1; sect_geninfo[0].exDataSize++; next++; } - } else { /* if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) */ + } /* if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) */ + else + { mbuf = xran_ethdi_mbuf_alloc(); - sect_geninfo[0].info.ef = 0; + + sect_geninfo[0].info->ef = 0; sect_geninfo[0].exDataSize = 0; + + if(p_x_ctx->dssEnable == 1) { + uint8_t dssSlot = 0; + dssSlot = tti % (p_x_ctx->dssPeriod); + + ext9.technology = p_x_ctx->technology[dssSlot]; + ext9.reserved = 0; + + sect_geninfo[0].exData[next].type = XRAN_CP_SECTIONEXTCMD_9; + sect_geninfo[0].exData[next].len = sizeof(ext9); + sect_geninfo[0].exData[next].data = &ext9; + + sect_geninfo[0].info->ef = 1; + sect_geninfo[0].exDataSize++; + next++; + } } - if(unlikely(mbuf == NULL)) { + if(unlikely(mbuf == NULL)) + { print_err("Alloc fail!\n"); - return (-1); + ret=-1; + goto _create_and_send_section_error; } - params.numSections = 1;//nsection; + params.numSections = numCPSections; params.sections = sect_geninfo; - ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id); - if(ret < 0) { + seq_id = xran_get_cp_seqid(pHandle, ((XRAN_DIR_DL == dir)? XRAN_DIR_DL : XRAN_DIR_UL), cc_id, ru_port_id); + ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id,start_sect_id); + } /* if (dir==XRAN_DIR_UL || generateCpPkt) */ + + if(replacePrbStartNSize && XRAN_DIR_DL == dir) + { + sect_geninfo[curr_sec_id-1].info->startPrbc = pPrbMapElem->UP_nRBStart; + sect_geninfo[curr_sec_id-1].info->numPrbc = pPrbMapElem->UP_nRBSize; + } + + if(ret < 0) + { print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n", frame_id, subframe_id, slot_id, dir); - } else { + } + else + { + if((dir==XRAN_DIR_UL) || generateCpPkt) //only send actual new CP section + { int32_t cp_sent = 0; int32_t pkt_len = 0; /* add in the ethernet header */ @@ -508,14 +695,255 @@ xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int pCnt->tx_bytes_counter += pkt_len; //rte_pktmbuf_pkt_len(mbuf); if(pkt_len > p_x_ctx->fh_init.mtu) rte_panic("section %d: pkt_len = %d maxExtBufSize %d\n", i, pkt_len, pPrbMapElem->bf_weight.maxExtBufSize); - //rte_mbuf_sanity_check(mbuf, 0); + cp_sent = p_x_ctx->send_cpmbuf2ring(mbuf, ETHER_TYPE_ECPRI, vf_id); - if(cp_sent != 1) { + if(cp_sent != 1) + { rte_pktmbuf_free(mbuf); } - xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id, ctx_id, §_geninfo[0].info); + } } } /* for (i=0; inPrbElm) + { + print_dbg("prbMap->nPrbElm is %d\n",prbMap->nPrbElm); + return 0; + } + + nsection = prbMap->nPrbElm; + i=0; + if(XRAN_DIR_DL == dir) + { + prbElmProcInfo->numSymsRemaining = 0; + prbElmProcInfo->nPrbElmProcessed = 0; + prbElmProcInfo->nPrbElmPerSym = prbMap->nPrbElm; + nsection = prbMap->nPrbElm; + } //dir = DL + else + { + nsection = prbMap->nPrbElm; + } //dir = UL + } + else + { + print_err("prbMap is NULL\n"); + return (-1); + } + + pPrbMapElem = &prbMap->prbMap[0]; + + if(xran_fs_get_slot_type(PortId, cc_id, tti, XRAN_SLOT_TYPE_FDD) != 1 + && xran_fs_get_slot_type(PortId, cc_id, tti, XRAN_SLOT_TYPE_SP) == 1) + { + startSym = xran_check_symbolrange( + ((dir==XRAN_DIR_DL)?XRAN_SYMBOL_TYPE_DL:XRAN_SYMBOL_TYPE_UL), + PortId, cc_id, tti, + pPrbMapElem->nStartSymb, + pPrbMapElem->numSymb, &numSyms); + + if(startSym < 0 || numSyms == 0) + { + /* if start symbol is not valid, then skip this section */ + print_err("Skip section %d due to invalid symbol range - [%d:%d], [%d:%d]", + i, + pPrbMapElem->nStartSymb, pPrbMapElem->numSymb, + startSym, numSyms); + } + } + else + { + startSym = pPrbMapElem->nStartSymb; + numSyms = pPrbMapElem->numSymb; + } + + vf_id = xran_map_ecpriRtcid_to_vf(p_x_ctx, dir, cc_id, ru_port_id); + params.dir = dir; + params.sectionType = XRAN_CP_SECTIONTYPE_1; + params.hdr.filterIdx = XRAN_FILTERINDEX_STANDARD; + params.hdr.frameId = frame_id; + params.hdr.subframeId = subframe_id; + params.hdr.slotId = slot_id; + params.hdr.startSymId = startSym; + params.hdr.iqWidth = pPrbMapElem->iqWidth; + params.hdr.compMeth = pPrbMapElem->compMethod; + params.sections = sect_geninfo; + + for (i = 0, j = 0; j < nsection; j++) + { + sect_geninfo[i].exDataSize=0; + sect_geninfo[i].info = xran_cp_get_section_info_ptr(pHandle, dir, cc_id, ru_port_id, ctx_id); + sect_geninfo[i].info->prbElemBegin = ((j == 0 ) ? 1 : 0); + sect_geninfo[i].info->prbElemEnd = ((j + 1 == nsection) ? 1 : 0); + if(sect_geninfo[i].info == NULL) + { + rte_panic("xran_cp_get_section_info_ptr failed\n"); + } + pPrbMapElem = &prbMap->prbMap[j]; + + sect_geninfo[i].info->type = XRAN_CP_SECTIONTYPE_1; + sect_geninfo[i].info->startSymId = pPrbMapElem->nStartSymb; + sect_geninfo[i].info->iqWidth = params.hdr.iqWidth; + sect_geninfo[i].info->compMeth = params.hdr.compMeth; + sect_geninfo[i].info->id = pPrbMapElem->nSectId; + + if(sect_geninfo[i].info->id > XRAN_MAX_SECTIONS_PER_SLOT) + print_err("sectinfo->id %d\n", sect_geninfo[i].info->id); + + sect_geninfo[i].info->rb = XRAN_RBIND_EVERY; + sect_geninfo[i].info->startPrbc = pPrbMapElem->UP_nRBStart; + sect_geninfo[i].info->numPrbc = pPrbMapElem->UP_nRBSize; + sect_geninfo[i].info->numSymbol = pPrbMapElem->numSymb; + sect_geninfo[i].info->reMask = 0xfff; + sect_geninfo[i].info->beamId = pPrbMapElem->nBeamIndex; + + if(startSym == pPrbMapElem->nStartSymb) + sect_geninfo[i].info->symInc = XRAN_SYMBOLNUMBER_NOTINC; + else + { + if((startSym + numSyms) == pPrbMapElem->nStartSymb) + { + sect_geninfo[i].info->symInc = XRAN_SYMBOLNUMBER_INC; + startSym = pPrbMapElem->nStartSymb; + numSyms = pPrbMapElem->numSymb; + } + else + { + sect_geninfo[i].info->startSymId = startSym; + sect_geninfo[i].info->numSymbol = numSyms; + print_dbg("Last startSym is %d. Last numSyms is %d. But current pPrbMapElem->nStartSymb is %d.\n", startSym, numSyms, pPrbMapElem->nStartSymb); + } + } + + + for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) + { + struct xran_section_desc *p_sec_desc = &pPrbMapElem->sec_desc[loc_sym][0]; + if(p_sec_desc) + { + p_sec_desc->section_id = sect_geninfo[i].info->id; + + sect_geninfo[i].info->sec_desc[loc_sym].iq_buffer_offset = p_sec_desc->iq_buffer_offset; + sect_geninfo[i].info->sec_desc[loc_sym].iq_buffer_len = p_sec_desc->iq_buffer_len; + } + else + { + print_err("section desc is NULL\n"); + } + } + + next = 0; + sect_geninfo[i].exDataSize = 0; + + /* Extension 4 for modulation compression */ + if(pPrbMapElem->compMethod == XRAN_COMPMETHOD_MODULATION) + { + // print_dbg("[%s]:%d Modulation Compression need to verify for this code branch and may not be available\n"); + print_err("[%s]:%d Modulation Compression need to verify for this code branch and may not be available\n",__FUNCTION__, __LINE__); + } + /* Extension 1 or 11 for Beam forming weights */ + /* add section extention for BF Weights if update is needed */ + if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) + { + // print_dbg("[%s]:%d Category B need to verify for this code branch and may not be available\n"); + print_err("[%s]:%d Category B need to verify for this code branch and may not be available\n",__FUNCTION__, __LINE__); + } /* if((category == XRAN_CATEGORY_B) && (pPrbMapElem->bf_weight_update)) */ + else + { + sect_geninfo[i].info->ef = 0; + sect_geninfo[i].exDataSize = 0; + + if(p_x_ctx->dssEnable == 1) { + uint8_t dssSlot = 0; + dssSlot = tti % (p_x_ctx->dssPeriod); + + ext9.technology = p_x_ctx->technology[dssSlot]; + ext9.reserved = 0; + + sect_geninfo[i].exData[next].type = XRAN_CP_SECTIONEXTCMD_9; + sect_geninfo[i].exData[next].len = sizeof(ext9); + sect_geninfo[i].exData[next].data = &ext9; + + sect_geninfo[i].info->ef = 1; + sect_geninfo[i].exDataSize++; + next++; + } + } + + // xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id, ctx_id, §_geninfo[i].info); + + if(pPrbMapElem->IsNewSect == 1) + { + sect_geninfo[i].info->startPrbc = pPrbMapElem->nRBStart; + sect_geninfo[i].info->numPrbc = pPrbMapElem->nRBSize; + i++; + } + } + + params.numSections = i; + + mbuf = xran_ethdi_mbuf_alloc(); + if(unlikely(mbuf == NULL)) + { + print_err("Alloc fail!\n"); + ret=-1; + goto _create_and_send_section_error; + } + + seq_id = xran_get_cp_seqid(pHandle, ((XRAN_DIR_DL == dir)? XRAN_DIR_DL : XRAN_DIR_UL), cc_id, ru_port_id); + ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id,start_sect_id); + + if(ret < 0) + { + print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n", + frame_id, subframe_id, slot_id, dir); + } + else + { + + int32_t cp_sent = 0; + int32_t pkt_len = 0; + /* add in the ethernet header */ + struct rte_ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h)); + pkt_len = rte_pktmbuf_pkt_len(mbuf); + pCnt->tx_counter++; + pCnt->tx_bytes_counter += pkt_len; //rte_pktmbuf_pkt_len(mbuf); + if(pkt_len > p_x_ctx->fh_init.mtu) + rte_panic("section %d: pkt_len = %d maxExtBufSize %d\n", i, pkt_len, pPrbMapElem->bf_weight.maxExtBufSize); + + cp_sent = p_x_ctx->send_cpmbuf2ring(mbuf, ETHER_TYPE_ECPRI, vf_id); + if(cp_sent != 1) + { + rte_pktmbuf_free(mbuf); + } + } + + struct xran_section_info *info; + for (j = 0; j < nsection; j++) + { + pPrbMapElem = &prbMap->prbMap[j]; + info = xran_cp_find_section_info(pHandle, dir, cc_id, ru_port_id, ctx_id,j); + if(info == NULL) + { + rte_panic("xran_cp_get_section_info_ptr failed\n"); + } + info->startPrbc = pPrbMapElem->UP_nRBStart; + info->numPrbc = pPrbMapElem->UP_nRBSize; + } + } +#endif +_create_and_send_section_error: + if(XRAN_DIR_DL == dir) + { + prbElmProcInfo->nPrbElmProcessed = nsection; + } return ret; } @@ -541,7 +969,7 @@ xran_ruemul_init(void *pHandle) } recvSections[xran_port_id] = malloc(sizeof(struct xran_section_recv_info) * XRAN_MAX_NUM_SECTIONS); - if(recvSections == NULL) { + if(recvSections[xran_port_id] == NULL) { print_err("Fail to allocate memory!"); return (-1); }