From 53d1aa768db96eca4c320f5e46da800c08c82006 Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Tue, 26 Oct 2021 18:15:20 +0530 Subject: [PATCH] JIRA ID: ODUHIGH-381 : DL packets Scheduling as per RRM Policy Change-Id: I8a04e5a4872a68912a9b0479b7bf8fdf8e315b0e Signed-off-by: lal.harshita --- src/5gnrrlc/rlc_utl_dl.c | 161 +++++++++++++++---------- src/5gnrsch/sch.c | 117 +++++++++++++++++- src/5gnrsch/sch.h | 53 ++++++++- src/5gnrsch/sch_common.c | 242 ++++++++++++++++++++++++++++++++++++- src/5gnrsch/sch_slot_ind.c | 131 ++++++++++++++++++--- src/5gnrsch/sch_ue_mgr.c | 251 +++++++++++++++++++++++++-------------- src/5gnrsch/sch_utils.c | 288 +++++++++++++++++++++++++++++++++++++++++++++ src/5gnrsch/sch_utils.h | 9 ++ src/cm/common_def.h | 7 +- 9 files changed, 1072 insertions(+), 187 deletions(-) diff --git a/src/5gnrrlc/rlc_utl_dl.c b/src/5gnrrlc/rlc_utl_dl.c index 8722a2eb8..6e681dfaa 100755 --- a/src/5gnrrlc/rlc_utl_dl.c +++ b/src/5gnrrlc/rlc_utl_dl.c @@ -230,14 +230,16 @@ uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo) uint16_t pduLen; /* PDU length */ uint16_t copyLen; /* Number of bytes copied */ uint8_t lcId = 0; + RlcBoStatus *boStatus = NULLP; /* Buffer occupancy status information */ + uint8_t ret = ROK; RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - dlData, sizeof(RlcData)); + dlData, sizeof(RlcData)); if(dlData == NULLP) { DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed for dl data"); RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - datReqInfo, sizeof(RguDDatReqInfo)); + datReqInfo, sizeof(RguDDatReqInfo)); return RFAILED; } memset(dlData, 0, sizeof(RlcData)); @@ -267,31 +269,31 @@ uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo) dlData->pduInfo[dlData->numPdu].lcId = datPerLch.lcId; /* Copy Message to fixed buffer to send */ - ODU_GET_MSG_LEN(datPerLch.pdu.mBuf[pduIdx], (MsgLen *)&pduLen); - RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - dlData->pduInfo[dlData->numPdu].pduBuf, pduLen); - - if (dlData->pduInfo[dlData->numPdu].pduBuf == NULLP ) - { - DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed"); - for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++) - { - RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\ - dlData->pduInfo[pduIdx].pduLen); - } - RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - dlData, sizeof(RlcData)); - RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - datReqInfo, sizeof(RguDDatReqInfo)); - return RFAILED; - } + ODU_GET_MSG_LEN(datPerLch.pdu.mBuf[pduIdx], (MsgLen *)&pduLen); + RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, + dlData->pduInfo[dlData->numPdu].pduBuf, pduLen); + + if (dlData->pduInfo[dlData->numPdu].pduBuf == NULLP ) + { + DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed"); + for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++) + { + RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, dlData->pduInfo[pduIdx].pduBuf,\ + dlData->pduInfo[pduIdx].pduLen); + } + RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, + dlData, sizeof(RlcData)); + RLC_FREE_SHRABL_BUF(post->region, post->pool, + datReqInfo, sizeof(RguDDatReqInfo)); + return RFAILED; + } ODU_COPY_MSG_TO_FIX_BUF(datPerLch.pdu.mBuf[pduIdx], 0, pduLen, \ - dlData->pduInfo[dlData->numPdu].pduBuf, (MsgLen *)©Len); - dlData->pduInfo[dlData->numPdu].pduLen = pduLen; + dlData->pduInfo[dlData->numPdu].pduBuf, (MsgLen *)©Len); + dlData->pduInfo[dlData->numPdu].pduLen = pduLen; /* Free message */ - ODU_PUT_MSG_BUF(datPerLch.pdu.mBuf[pduIdx]); + ODU_PUT_MSG_BUF(datPerLch.pdu.mBuf[pduIdx]); dlData->numPdu++; }/* For per PDU */ @@ -304,6 +306,42 @@ uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo) }/* For Data per Lch */ }/* For Data per Tb */ + /*No Data to send for this UE, Only send the BO REQUEST to SCH */ + if(dlData->numPdu == 0) + { + for(lchIdx = 0; lchIdx < dlData->numLc; lchIdx++) + { + RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, \ + boStatus, sizeof(RlcBoStatus)); + if(boStatus == NULLP) + { + DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Memory allocation failed for boStatus"); + ret = RFAILED; + break; + } + boStatus->cellId = dlData->cellId; + GET_UE_IDX(dlData->rnti, boStatus->ueIdx); + boStatus->commCh = FALSE; + boStatus->lcId = dlData->boStatus[lchIdx].lcId; + boStatus->bo = dlData->boStatus[lchIdx].bo; + + FILL_PST_RLC_TO_MAC(pst, RLC_DL_INST, EVENT_BO_STATUS_TO_MAC); + /* Send Status Response to MAC layer */ + if(RlcSendBoStatusToMac(&pst, boStatus) != ROK) + { + DU_LOG("\nERROR --> RLC_DL : rlcSendDedLcDlData: Failed to send BO status"); + RLC_FREE_SHRABL_BUF(pst.region, pst.pool, boStatus, sizeof(RlcBoStatus)); + ret = RFAILED; + break; + } + DU_LOG("\nINFO --> RLC_DL : rlcSendDedLcDlData: BO Status sent successfully for LCID:%d,BO:%d",\ + boStatus->lcId, boStatus->bo); + } + RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, dlData, sizeof(RlcData)); + RLC_FREE_SHRABL_BUF(post->region, post->pool, datReqInfo, sizeof(RguDDatReqInfo)); + return (ret); + } + RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, dlRrcMsgRsp, sizeof(RlcDlRrcMsgRsp)); if(dlRrcMsgRsp == NULLP) { @@ -311,11 +349,11 @@ uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo) for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++) { RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\ - dlData->pduInfo[pduIdx].pduLen); + dlData->pduInfo[pduIdx].pduLen); } RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData)); RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - datReqInfo, sizeof(RguDDatReqInfo)); + datReqInfo, sizeof(RguDDatReqInfo)); return RFAILED; } dlRrcMsgRsp->cellId = dlData->cellId; @@ -330,10 +368,10 @@ uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo) for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++) { RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData->pduInfo[pduIdx].pduBuf,\ - dlData->pduInfo[pduIdx].pduLen); + dlData->pduInfo[pduIdx].pduLen); } RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlData, sizeof(RlcData)); - RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RguDDatReqInfo)); + RLC_FREE_SHRABL_BUF(post->region, post->pool, datReqInfo, sizeof(RguDDatReqInfo)); RLC_FREE_SHRABL_BUF(pst.region, pst.pool, dlRrcMsgRsp, sizeof(RlcDlRrcMsgRsp)); return RFAILED; } @@ -353,7 +391,7 @@ uint8_t rlcSendDedLcDlData(Pst *post, SpId spId, RguDDatReqInfo *datReqInfo) } } /* For Data per UE */ RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, datReqInfo, sizeof(RguDDatReqInfo)); - + return ROK; }/* End of rlcSendDedLcDlData */ @@ -389,31 +427,32 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) RguDDatReqInfo *datReqInfo; /* Data Request Information */ RlcRguSapCb *rguSap; /* MAC SAP CB */ uint32_t totNumPdu; /* Total number of PDUS */ + MsgLen len = 0; RguStaIndTb *staIndTb = NULLP; RguDatReqTb *datReqTb = NULLP; RguDStaIndPerUe *staInd = NULLP; #ifdef LTE_L2_MEAS uint32_t grantPerLch[RGU_MAX_LC] = {0}; #endif -/* kw005.201 added support for L2 Measurement */ + /* kw005.201 added support for L2 Measurement */ #ifdef LTE_L2_MEAS_LOSS_DELAY uint8_t snIdx1; uint8_t snIdx2; #endif /* LTE_L2_MEAS */ uint32_t idx, ueDataIdx = 0; -//Debug + //Debug uint32_t staIndSz=0,datIndSz = 0; datReqInfo = NULLP; RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_DL, RLC_POOL, - datReqInfo,sizeof(RguDDatReqInfo)); + datReqInfo,sizeof(RguDDatReqInfo)); #if (ERRCLASS & ERRCLS_ADD_RES) - if ( datReqInfo == NULLP ) - { - DU_LOG("\nERROR --> RLC_DL : rlcUtlSendToMac: Memory allocation failed"); - return RFAILED; - } + if ( datReqInfo == NULLP ) + { + DU_LOG("\nERROR --> RLC_DL : rlcUtlSendToMac: Memory allocation failed"); + return RFAILED; + } #endif /* ERRCLASS & ERRCLS_ADD_RES */ for(idx = 0; idx < staIndInfo->nmbOfUeGrantPerTti; idx++) { @@ -424,11 +463,11 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) { /* Fetch UeCb failed */ DU_LOG("\nERROR --> RLC_DL : rlcUtlSendToMac: UeId[%u]:ueCb not found", - staInd->rnti); + staInd->rnti); /* If ueCb is not found for current rnti then continue to look for next rnti*/ continue; } - + /* kw002.201 Removed the allocation of RlcDatReq */ /* kw004.201 Used SSI function to initialize the variable */ memset(&datReq, 0, sizeof(RlcDatReq) ); @@ -445,7 +484,7 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) #ifdef LTE_L2_MEAS /*Calculate the total grant size from MAC */ if((staIndTb->lchStaInd[count].lcId >= RGU_MAX_LC) - || (staIndTb->lchStaInd[count].lcId == 0)) + || (staIndTb->lchStaInd[count].lcId == 0)) { /* TODO : Need to figure out why this is happening */ break; @@ -480,23 +519,9 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) #ifdef LTE_L2_MEAS grantPerLch[staIndTb->lchStaInd[count].lcId] = datReq.totMacGrant; #endif - if ( 0 == datReq.pduInfo.numPdu ) - { - continue; - } - totNumPdu += datReq.pduInfo.numPdu; - memcpy(&(datReqTb->lchData[count].pdu), - &(datReq.pduInfo),sizeof(KwPduInfo)); - - for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++) - { - MsgLen len = 0; - ODU_GET_MSG_LEN(datReqTb->lchData[count].pdu.mBuf[numPdu],&len); - datIndSz += len; - } datReqTb->lchData[count].setMaxUlPrio = FALSE; if (RLC_AM_IS_POLL_BIT_SET(RLC_AMDL) && - (RLC_AMDL.sduQ.count > 1)) + (RLC_AMDL.sduQ.count > 1)) { /* Poll bit is set indicate to MAC*/ datReqTb->lchData[count].setMaxUlPrio = TRUE; @@ -505,7 +530,7 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) #ifdef CCPU_OPT datReqTb->lchData[count].boReport.estRlcHdrSz = - datReq.boRep.estHdrSz; + datReq.boRep.estHdrSz; datReqTb->lchData[count].boReport.staPduPrsnt = datReq.boRep.staPduPrsnt; #endif /* CCPU_OPT */ @@ -525,6 +550,23 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) } #endif + datReqTb->lchData[count].boReport.oldestSduArrTime = + datReq.boRep.oldestSduArrTime; + if ( 0 == datReq.pduInfo.numPdu ) + { + /* kw004.201 Used SSI function to initialize the variable */ + memset(&datReq, 0, sizeof(RlcDatReq) ); + continue; + } + totNumPdu += datReq.pduInfo.numPdu; + memcpy(&(datReqTb->lchData[count].pdu), + &(datReq.pduInfo),sizeof(KwPduInfo)); + + for (;numPdu < datReqTb->lchData[count].pdu.numPdu ; numPdu ++) + { + ODU_GET_MSG_LEN(datReqTb->lchData[count].pdu.mBuf[numPdu],&len); + datIndSz += len; + } /* kw005.201 added support for L2 Measurement */ #ifdef LTE_L2_MEAS_LOSS_DELAY datReqTb->rguSnInfo->lchMap[count].lChId = @@ -547,8 +589,6 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) tbSnMap->prevNumSn = tbSnMap->numSn; } #endif - datReqTb->lchData[count].boReport.oldestSduArrTime = - datReq.boRep.oldestSduArrTime; /* kw004.201 Used SSI function to initialize the variable */ memset(&datReq, 0, sizeof(RlcDatReq) ); } @@ -564,12 +604,7 @@ uint8_t rlcUtlSendToMac(RlcCb *gCb, SuId suId, KwDStaIndInfo *staIndInfo) } #endif datReqTb->nmbLch = staIndTb->nmbLch; - /*adding the check to make sure that lcId is not sent as 0 - * when no data is there in datReq */ - if ( 0 == totNumPdu ) - { - datReqTb->lchData[0].lcId = staIndTb->lchStaInd[0].lcId; - } + /* kw005.201 added support for L2 Measurement */ #ifdef LTE_L2_MEAS_LOSS_DELAY if(tbSnMap->numSn == 0) diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index 504966312..a98832ac3 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -927,7 +927,7 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) { uint8_t lcId = 0; uint16_t ueIdx = 0; - uint16_t slot; + uint16_t slot = 0; #ifdef NR_TDD uint16_t slotIdx = 0; #endif @@ -957,7 +957,15 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) (lcId >= MIN_DRB_LCID && lcId <= MAX_DRB_LCID)) { SET_ONE_BIT(ueIdx, cell->boIndBitMap); - ueCb->dlInfo.dlLcCtxt[lcId].bo = dlBoInfo->dataVolume; + if(ueCb->dlInfo.dlLcCtxt[lcId].lcId == lcId) + { + ueCb->dlInfo.dlLcCtxt[lcId].bo = dlBoInfo->dataVolume; + } + else + { + DU_LOG("ERROR --> SCH: LCID:%d is not configured in SCH Cb",lcId); + return RFAILED; + } } else if(lcId != SRB0_LCID) { @@ -993,7 +1001,7 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) schDlSlotInfo = NULL; return RFAILED; } - + schDlSlotInfo->dlMsgInfo->crnti = dlBoInfo->crnti; schDlSlotInfo->dlMsgInfo->ndi = 1; schDlSlotInfo->dlMsgInfo->harqProcNum = 0; @@ -1355,6 +1363,109 @@ uint8_t allocatePrbUl(SchCellCb *cell, SlotTimingInfo slotTime, \ return ROK; } +/******************************************************************************* + * + * @brief Try to find Best Free Block with Max Num PRB + * + * @details + * + * Function : searchLargestFreeBlockDL + * + * Functionality: + * Finds the FreeBlock with MaxNum of FREE PRB considering SSB/SIB1 ocassions. + * + * @params[in] I/P > prbAlloc table (FreeBlock list) + * I/P > Slot timing Info + * O/P > Start PRB + * + * + * @return Max Number of Free PRB + * If 0, then no Suitable Free Block + * + * ********************************************************************************/ + +uint16_t searchLargestFreeBlockDL(SchCellCb *cell, SlotTimingInfo slotTime,uint16_t *startPrb) +{ + uint16_t broadcastPrbStart=0, broadcastPrbEnd=0, maxFreePRB = 0; + PduTxOccsaion ssbOccasion=0, sib1Occasion=0; + FreePrbBlock *freePrbBlock = NULLP; + CmLList *freePrbNode = NULLP; + + SchDlSlotInfo *schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot]; + SchPrbAlloc *prbAlloc = &schDlSlotInfo->prbAlloc; + + ssbOccasion = schCheckSsbOcc(cell, slotTime); + sib1Occasion = schCheckSib1Occ(cell, slotTime); + + if(ssbOccasion && sib1Occasion) + { + broadcastPrbStart = cell->cellCfg.ssbSchCfg.ssbOffsetPointA; + broadcastPrbEnd = broadcastPrbStart + SCH_SSB_NUM_PRB + cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc.numPrb -1; + } + else if(ssbOccasion) + { + broadcastPrbStart = cell->cellCfg.ssbSchCfg.ssbOffsetPointA; + broadcastPrbEnd = broadcastPrbStart + SCH_SSB_NUM_PRB -1; + } + else if(sib1Occasion) + { + broadcastPrbStart = cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc.startPrb; + broadcastPrbEnd = broadcastPrbStart + cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc.numPrb -1; + } + + + freePrbNode = prbAlloc->freePrbBlockList.first; + *startPrb = 0; /*Initialize the StartPRB to zero*/ + while(freePrbNode) + { + freePrbBlock = (FreePrbBlock *)freePrbNode->node; + + /*For block with same numFreeBlocks, choose the one with HighestPRB range + *Since FreeBLockList are arranged in Descending order of PRB range thus Skipping this block*/ + if(maxFreePRB >= freePrbBlock->numFreePrb) + { + //skip this block + freePrbNode = freePrbNode->next; + continue; + } + + /* If broadcast message is scheduled in this slot, then check if its PRBs belong to the current free block. + * Since SSB/SIB1 PRB location is fixed, these PRBs cannot be allocated to other message in same slot */ + if((ssbOccasion || sib1Occasion) && + ((broadcastPrbStart >= freePrbBlock->startPrb) && (broadcastPrbStart <= freePrbBlock->endPrb)) && \ + ((broadcastPrbEnd >= freePrbBlock->startPrb) && (broadcastPrbEnd <= freePrbBlock->endPrb))) + { + + /* Implmentation is done such that highest-numbered free-RB is Checked first + and freePRB in this block is greater than Max till now */ + if((freePrbBlock->endPrb > broadcastPrbEnd) && ((freePrbBlock->endPrb - broadcastPrbEnd) > maxFreePRB)) + { + /* If sufficient free PRBs are available above broadcast message*/ + *startPrb = broadcastPrbEnd + 1; + maxFreePRB = (freePrbBlock->endPrb - broadcastPrbEnd); + } + /*Also check the other freeBlock (i.e. Above the broadcast message) for MAX FREE PRB*/ + if((broadcastPrbStart > freePrbBlock->startPrb) && ((broadcastPrbStart - freePrbBlock->startPrb) > maxFreePRB)) + { + /* If free PRBs are available below broadcast message*/ + *startPrb = freePrbBlock->startPrb; + maxFreePRB = (broadcastPrbStart - freePrbBlock->startPrb); + } + } + else //Best Block + { + if(maxFreePRB < freePrbBlock->numFreePrb) + { + *startPrb = freePrbBlock->startPrb; + maxFreePRB = freePrbBlock->numFreePrb; + } + + } + freePrbNode = freePrbNode->next; + } + return(maxFreePRB); +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch.h b/src/5gnrsch/sch.h index 6105f915e..3c78a5024 100644 --- a/src/5gnrsch/sch.h +++ b/src/5gnrsch/sch.h @@ -90,6 +90,12 @@ typedef enum WINDOW_EXPIRED }RaRspWindowStatus; +typedef enum +{ + SEARCH, + CREATE, + DELETE +}ActionTypeLcLL; /** * @brief * Structure holding LTE MAC's General Configuration information. @@ -175,11 +181,11 @@ typedef struct schLcCtxt uint32_t bo; uint16_t pduSessionId; /*Pdu Session Id*/ Snssai *snssai; /*S-NSSAI assoc with LCID*/ + bool isDedicated; /*Flag containing Dedicated S-NSSAI or not*/ }SchDlLcCtxt; typedef struct schDlCb { - uint8_t numDlLc; SchDlLcCtxt dlLcCtxt[MAX_NUM_LC]; }SchDlCb; @@ -194,11 +200,11 @@ typedef struct schUlLcCtxt uint8_t bsd; // bucketSizeDuration uint16_t pduSessionId; /*Pdu Session Id*/ Snssai *snssai; /*S-NSSAI assoc with LCID*/ + bool isDedicated; /*Flag containing Dedicated S-NSSAI or not*/ }SchUlLcCtxt; typedef struct schUlCb { - uint8_t numUlLc; SchUlLcCtxt ulLcCtxt[MAX_NUM_LC]; }SchUlCb; @@ -217,6 +223,36 @@ typedef struct schUeCfgCb SchModulationInfo ulModInfo; }SchUeCfgCb; +/*Following structures to keep record and estimations of PRB allocated for each + * LC taking into consideration the RRM policies*/ +typedef struct lcInfo +{ + uint8_t lcId; /*LCID for which BO are getting recorded*/ + uint32_t reqBO; /*Size of the BO requested/to be allocated for this LC*/ + uint32_t allocBO; /*TBS/BO Size which is actually allocated*/ + uint8_t allocPRB; /*PRB count which is allocated based on RRM policy/FreePRB*/ +}LcInfo; + +typedef struct dedicatedLCInfo +{ + CmLListCp dedLcList; /*Linklist of LC assoc with RRMPolicyMemberList*/ + uint16_t rsvdDedicatedPRB; /*Number of PRB reserved for this Dedicated S-NSSAI*/ +}DedicatedLCInfo; + +typedef struct schLcPrbEstimate +{ + /* TODO: For Multiple RRMPolicies, Make DedicatedLcInfo as array/Double Pointer + * and have separate DedLCInfo for each RRMPolcyMemberList*/ + /* Dedicated LC List will be allocated, if any available*/ + DedicatedLCInfo *dedLcInfo; /*Contain LCInfo per RRMPolicy*/ + + CmLListCp defLcList; /*Linklist of LC assoc with Default S-NSSAI(s)*/ + + /* SharedPRB number can be used by any LC. + * Need to calculate in every Slot based on PRB availability*/ + uint16_t sharedNumPrb; +}SchLcPrbEstimate; + /** * @brief * UE control block @@ -232,6 +268,8 @@ typedef struct schUeCb BsrInfo bsrInfo[MAX_NUM_LOGICAL_CHANNEL_GROUPS]; SchUlCb ulInfo; SchDlCb dlInfo; + SchLcPrbEstimate dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/ + SchLcPrbEstimate ulLcPrbEst; /*UL PRB Alloc Estimate among different LC*/ }SchUeCb; /** @@ -317,11 +355,13 @@ uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcst void schProcessRaReq(SlotTimingInfo currTime, SchCellCb *cellCb); uint8_t schFillRar(SchCellCb *cell, SlotTimingInfo rarTime, uint16_t ueIdx, RarAlloc *rarAlloc, uint8_t k0Index); uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo slotTime, DlMsgAlloc *msg4Alloc); -uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti, - uint32_t *accumalatedSize, DlMsgAlloc *dlMsgAlloc); +uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti,\ + uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB); uint16_t schAccumalateLcBoSize(SchCellCb *cell, uint16_t ueIdx); uint8_t allocatePrbDl(SchCellCb *cell, SlotTimingInfo slotTime, uint8_t startSymbol, uint8_t symbolLength, \ uint16_t *startPrb, uint16_t numPrb); +uint16_t searchLargestFreeBlockDL(SchCellCb *cell, SlotTimingInfo slotTime,uint16_t *startPrb); +void updateGrantSizeForBoRpt(CmLListCp *lcLL, DlMsgAlloc *dlMsgAlloc, uint32_t *accumalatedBOSize); /* UL scheduling related function declarations */ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst); @@ -334,6 +374,11 @@ uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo pdcchSlotTime, uint32_t uint8_t allocatePrbUl(SchCellCb *cell, SlotTimingInfo slotTime, uint8_t startSymbol, uint8_t symbolLength, \ uint16_t *startPrb, uint16_t numPrb); +/*Generic Functions*/ +LcInfo* handleLcLList(CmLListCp *lcLL, uint8_t lcId, ActionTypeLcLL action); +void prbAllocUsingRRMPolicy(CmLListCp *lcLL, bool dedicatedPRB, uint16_t mcsIdx,uint8_t numSymbols,\ + uint16_t *sharedPRB, uint16_t *reservedPRB, bool *isTxPayloadLenAdded); + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_common.c b/src/5gnrsch/sch_common.c index 358347dc6..75a65f7bd 100644 --- a/src/5gnrsch/sch_common.c +++ b/src/5gnrsch/sch_common.c @@ -714,10 +714,9 @@ uint16_t schAllocPucchResource(SchCellCb *cell, uint16_t crnti, uint16_t slot) * * ****************************************************************/ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti, - uint32_t *accumalatedSize, DlMsgAlloc *dlMsgAlloc) + uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB) { uint8_t ueIdx; - uint16_t tbSize = 0; PdcchCfg *pdcch = NULLP; PdschCfg *pdsch = NULLP; BwpCfg *bwp = NULLP; @@ -781,9 +780,8 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c pdsch->codeword[cwCount].mcsIndex = ueCb.ueCfg.dlModInfo.mcsIndex; pdsch->codeword[cwCount].mcsTable = ueCb.ueCfg.dlModInfo.mcsTable; pdsch->codeword[cwCount].rvIndex = 0; - tbSize = schCalcTbSize(*accumalatedSize + TX_PAYLOAD_HDR_LEN); - if(tbSize < *accumalatedSize) - *accumalatedSize = tbSize - TX_PAYLOAD_HDR_LEN; + + tbSize +=TX_PAYLOAD_HDR_LEN; pdsch->codeword[cwCount].tbSize = tbSize; } pdsch->dataScramblingId = cell->cellCfg.phyCellId; @@ -805,7 +803,7 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */ pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */ - pdsch->pdschFreqAlloc.freqAlloc.startPrb = MAX_NUM_RB; + pdsch->pdschFreqAlloc.freqAlloc.startPrb = startPRB; /*Start PRB will be already known*/ pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, ueCb.ueCfg.dlModInfo.mcsIndex, \ pdschCfg.timeDomRsrcAllociList[0].symbolLength); @@ -1330,6 +1328,238 @@ SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl) } } +/******************************************************************************************* + * + * @brief Allocate the PRB using RRM policy + * + * @details + * + * Function : prbAllocUsingRRMPolicy + * + * Functionality: + * [Step1]: Traverse each Node in the LC list + * [Step2]: Check whether the LC has ZERO requirement then clean this LC + * [Step3]: Calcualte the maxPRB for this LC. + * a. For Dedicated LC, maxPRB = sum of remainingReservedPRB and + * sharedPRB + * b. For Default, just SharedPRB count + * [Step4]: If the LC is the First one to be allocated for this UE then add + * TX_PAYLODN_LEN to reqBO + * [Step5]: Calculate the estimate PRB and estimate BO to be allocated + * based on reqBO and maxPRB left. + * [Step6]: Based on calculated PRB, Update Reserved PRB and Shared PRB counts + * [Step7]: Deduce the reqBO based on allocBO and move the LC node to last. + * [Step8]: Continue the next loop from List->head + * + * [Loop Exit]: + * [Exit1]: If all the LCs are allocated in list + * [Exit2]: If PRBs are exhausted + * + * @params[in] I/P > lcLinkList pointer (LcInfo list) + * I/P > IsDedicatedPRB (Flag to indicate that RESERVED PRB to use + * I/P > mcsIdx and PDSCH symbols count + * I/P & O/P > Shared PRB , reserved PRB Count + * I/P & O/P > Total TBS size accumulated + * I/P & O/P > isTxPayloadLenAdded : Decision flag to add the TX_PAYLOAD_HDR_LEN + * + * @return void + * + * *******************************************************************************************/ +void prbAllocUsingRRMPolicy(CmLListCp *lcLL, bool isDedicatedPRB, uint16_t mcsIdx,uint8_t numSymbols,\ + uint16_t *sharedPRB, uint16_t *reservedPRB, bool *isTxPayloadLenAdded) +{ + CmLList *node = NULLP; + LcInfo *lcNode = NULLP; + uint16_t remReservedPRB = 0, estPrb = 0, maxPRB = 0; + + if(lcLL == NULLP) + { + DU_LOG("\nERROR --> SCH: LcList not present"); + return; + } + node = lcLL->first; + + /*Only for Dedicated LcList, Valid value will be assigned to remReservedPRB + * For Other LcList, remReservedPRB = 0*/ + if(reservedPRB != NULLP && isDedicatedPRB == TRUE) + { + remReservedPRB = *reservedPRB; + } + + /*[Step1]*/ + while(node) + { +#if 0 + /*For Debugging purpose*/ + printLcLL(lcLL); +#endif + lcNode = (LcInfo *)node->node; + + /* [Step2]: Below condition will hit in rare case as it has been taken care during the cleaning + * process of LCID which was fully allocated. Check is just for safety purpose*/ + if(lcNode->reqBO == 0 && lcNode->allocBO == 0) + { + DU_LOG("\nERROR --> SCH: LCID:%d has no requirement, clearing this node",\ + lcNode->lcId); + deleteNodeFromLList(lcLL, node); + SCH_FREE(lcNode, sizeof(LcInfo)); + node = lcLL->first; + continue; + } + + /*[Exit1]: All LCs are allocated(allocBO = 0 for fully unallocated LC)*/ + if(lcNode->allocBO != 0) + { + DU_LOG("\nWARNING --> SCH: All LC are allocated [SharedPRB:%d]",*sharedPRB); + return; + } + + /*[Exit2]: If PRBs are exhausted*/ + if(isDedicatedPRB) + { + /*Loop Exit: All resources exhausted*/ + if(remReservedPRB == 0 && *sharedPRB == 0) + { + DU_LOG("\nWARNING --> SCH: Dedicated resources exhausted for LC:%d",lcNode->lcId); + return; + } + } + else + { + /*Loop Exit: All resources exhausted*/ + if(*sharedPRB == 0) + { + DU_LOG("\nWARNING --> SCH: Default resources exhausted for LC:%d",lcNode->lcId); + return; + } + } + + /*[Step3]*/ + maxPRB = remReservedPRB + *sharedPRB; + + /*[Step4]*/ + if(!(*isTxPayloadLenAdded)) + { + DU_LOG("\nINFO --> SCH: LC:%d is the First node to be allocated which includes TX_PAYLOAD_HDR_LEN",\ + lcNode->lcId); + *isTxPayloadLenAdded = TRUE; + lcNode->allocBO = calculateEstimateTBSize((lcNode->reqBO + TX_PAYLOAD_HDR_LEN),\ + mcsIdx, numSymbols, maxPRB, &estPrb); + lcNode->allocBO -=TX_PAYLOAD_HDR_LEN; + } + else + { + /*[Step4]*/ + lcNode->allocBO = calculateEstimateTBSize(lcNode->reqBO,\ + mcsIdx, numSymbols, maxPRB, &estPrb); + } + + /*[Step6]:Re-adjust the reservedPRB pool count and *SharedPRB Count based on + * estimated PRB allocated*/ + if((isDedicatedPRB == TRUE) && (estPrb <= remReservedPRB)) + { + remReservedPRB = remReservedPRB - estPrb; + } + else /*LC requirement need PRB share from SharedPRB*/ + { + if(*sharedPRB <= (estPrb - remReservedPRB)) + { + DU_LOG("\nINFO --> SCH: SharedPRB is less"); + *sharedPRB = 0; + } + else + { + *sharedPRB = *sharedPRB - (estPrb - remReservedPRB); + } + remReservedPRB = 0; + } + + /*[Step7]*/ + lcNode->reqBO -= lcNode->allocBO; /*Update the reqBO with remaining bytes unallocated*/ + lcNode->allocPRB = estPrb; + cmLListAdd2Tail(lcLL, cmLListDelFrm(lcLL, node)); + + /*[Step8]:Next loop: First LC to be picked from the list + * because Allocated Nodes are moved to the last*/ + node = lcLL->first; + + } + return; +} + +/******************************************************************************************* + * + * @brief Check the LC List and fill the LC and GrantSize to be sent to MAC as + * BO Report + * + * @details + * + * Function : updateGrantSizeForBoRpt + * + * Functionality: + * Check the LC List and fill the LC and GrantSize to be sent to MAC as + * BO Report in dlMsgAlloc Pointer + * + * @params[in] I/P > lcLinkList pointer (LcInfo list) + * I/P & O/P > dlMsgAlloc(Pending LC to be added in this context) + * I/P & O/P > accumalatedBOSize + * @return void + * + * *******************************************************************************************/ +void updateGrantSizeForBoRpt(CmLListCp *lcLL, DlMsgAlloc *dlMsgAlloc, uint32_t *accumalatedBOSize) +{ + CmLList *node = NULLP, *next = NULLP; + LcInfo *lcNode = NULLP; + + if(lcLL == NULLP) + { + DU_LOG("\nERROR --> SCH: LcList not present"); + return; + } + + if(lcLL->count) + { + node = lcLL->first; + } + else + { + /*lcLL is empty*/ + return; + } + + /*Traverse List*/ + while(node) + { + next = node->next; + lcNode = (LcInfo *)node->node; + if(lcNode != NULLP) + { + DU_LOG("\nINFO --> SCH : LcID:%d, [reqBO, allocBO, allocPRB]:[%d,%d,%d]",\ + lcNode->lcId, lcNode->reqBO, lcNode->allocBO, lcNode->allocPRB); + + /*Add this LC to dlMsgAlloc so that if this LC gets allocated, BO + * report for allocation can be sent to MAC*/ + dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].lcId = lcNode->lcId; + dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].schBytes = lcNode->allocBO; + + /*Calculate the Total Payload/BO size allocated*/ + *accumalatedBOSize += dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].schBytes; + + DU_LOG("\nINFO --> SCH: Added in MAC BO report: LCID:%d,reqBO:%d,Idx:%d, TotalBO Size:%d",\ + lcNode->lcId,lcNode->reqBO, dlMsgAlloc->numLc, *accumalatedBOSize); + + dlMsgAlloc->numLc++; + /*The LC has been fully allocated, clean it*/ + if(lcNode->reqBO == 0) + { + handleLcLList(lcLL, lcNode->lcId, DELETE); + } + } + node = next; + }/*End of while*/ + return; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_slot_ind.c b/src/5gnrsch/sch_slot_ind.c index 76a840d93..52a30673b 100644 --- a/src/5gnrsch/sch_slot_ind.c +++ b/src/5gnrsch/sch_slot_ind.c @@ -193,7 +193,7 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime) * * @details * - * Function : + * Function : schFillBoGrantDlSchedInfo * * Functionality: @@ -205,11 +205,19 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime) * ****************************************************************/ uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlMsgAlloc *dlMsgAlloc) { - uint8_t ueIdx, lcIdx; - uint16_t slot; - uint16_t crnti = 0; + uint8_t ueIdx = 0, lcIdx = 0, pdschSymbols = 0; + uint16_t slot = 0, startPrb = 0, maxFreePRB = 0; + uint16_t crnti = 0, mcsIdx = 0; uint32_t accumalatedSize = 0; SchUeCb *ueCb = NULLP; + CmLListCp *lcLL = NULLP; + SchPdschConfig pdschCfg; + + /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size + * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated. + * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead + * else if only Default list is present then first node in this List will add this overhead len*/ + bool isTxPayloadLenAdded = FALSE; while(cell->boIndBitMap) { @@ -230,28 +238,54 @@ uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlM dlSchedInfo->dlMsgAlloc = dlMsgAlloc; dlMsgAlloc->crnti = crnti; + pdschCfg = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg; + mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex; + + /*TODO: K0Index must be used instead of 0th Index in + * pdschCfg.timeDomRsrcAllociList*/ + pdschSymbols = pdschCfg.timeDomRsrcAllociList[0].symbolLength; /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */ memcpy(&dlMsgAlloc->dlMsgInfo, cell->schDlSlotInfo[slot]->dlMsgInfo, \ - sizeof(DlMsgInfo)); + sizeof(DlMsgInfo)); + /*Re-Initalization per UE*/ /* scheduled LC data fill */ dlMsgAlloc->numLc = 0; + isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/ + accumalatedSize = 0; + for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++) { if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo) { - dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].lcId = lcIdx; - - /* calculation for BO includse RLC and MAC header size */ - dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].schBytes = \ - ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE; - accumalatedSize += dlMsgAlloc->lcSchInfo[dlMsgAlloc->numLc].schBytes; - dlMsgAlloc->numLc++; + /*Check the LC is Dedicated or default and accordingly LCList will + * be used*/ + if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated) + { + lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); + } + else + { + lcLL = &(ueCb->dlLcPrbEst.defLcList); + } + + /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/ + if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\ + (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK) + { + DU_LOG("\nERROR --> SCH : Updation in LC List Failed"); + /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ + SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc)); + dlSchedInfo->dlMsgAlloc = NULLP; + return RFAILED; + } } ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0; - } - - if (!dlMsgAlloc->numLc) + }//End of for loop + + + if ((ueCb->dlLcPrbEst.defLcList.count == 0) && \ + ((ueCb->dlLcPrbEst.dedLcInfo != NULL) && (ueCb->dlLcPrbEst.dedLcInfo->dedLcList.count == 0))) { DU_LOG("\nDEBUG --> SCH : No pending BO for any LC id\n"); /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ @@ -260,15 +294,73 @@ uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlM return ROK; } - /* pdcch and pdsch data is filled */ - if((schDlRsrcAllocDlMsg(cell, dlSchedInfo->schSlotValue.dlMsgTime, crnti, &accumalatedSize, dlMsgAlloc)) != ROK) + /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/ + maxFreePRB = searchLargestFreeBlockDL(cell, dlSchedInfo->schSlotValue.dlMsgTime, &startPrb); + + /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in + * the list based on RRM policy*/ + + /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or + * Num of Free PRB available is not enough to reserve Dedicated PRBs*/ + if(maxFreePRB != 0) + { + if((ueCb->dlLcPrbEst.dedLcInfo == NULLP) + || ((maxFreePRB < ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB))) + { + ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB; + DU_LOG("\nWARNING --> SCH : Only Default Slice is scheduled, sharedPRB Count:%d",\ + ueCb->dlLcPrbEst.sharedNumPrb); + + /*PRB Alloc for Default LCs*/ + prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschSymbols,\ + &(ueCb->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded); + } + else + { + ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB; + + /*PRB Alloc for Dedicated LCs*/ + prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, pdschSymbols,\ + &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded); + + /*PRB Alloc for Default LCs*/ + prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschSymbols, \ + &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded); + } + } + + /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes + * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ + if(ueCb->dlLcPrbEst.dedLcInfo != NULLP) + updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), dlMsgAlloc, &(accumalatedSize)); + + updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.defLcList), dlMsgAlloc, &(accumalatedSize)); + + /*Below case will hit if NO LC(s) are allocated due to resource crunch*/ + if (!accumalatedSize) + { + if(maxFreePRB == 0) + { + DU_LOG("\nERROR --> SCH : NO FREE PRB!!"); + } + else + { + /*Schedule the LC for next slot*/ + DU_LOG("\nDEBUG --> SCH : No LC has been scheduled"); + } + /*Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that + * Allocation can be done in next slot*/ + return ROK; + } + /*[Step6]: pdcch and pdsch data is filled */ + if((schDlRsrcAllocDlMsg(cell, dlSchedInfo->schSlotValue.dlMsgTime, \ + crnti, accumalatedSize, dlMsgAlloc, startPrb)) != ROK) { DU_LOG("\nERROR --> SCH : Scheduling of DL dedicated message failed"); /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */ SCH_FREE(dlMsgAlloc, sizeof(DlMsgAlloc)); dlSchedInfo->dlMsgAlloc = NULLP; return RFAILED; - } /* TODO : Update the scheduling byte report for multiple LC based on QCI @@ -277,10 +369,11 @@ uint8_t schFillBoGrantDlSchedInfo(SchCellCb *cell, DlSchedInfo *dlSchedInfo, DlM * equally amongst all LC with pending data. This is avoid starving of any * LC * */ +#if 0 accumalatedSize = accumalatedSize/dlMsgAlloc->numLc; for(lcIdx = 0; lcIdx < dlMsgAlloc->numLc; lcIdx ++) dlMsgAlloc->lcSchInfo[lcIdx].schBytes = accumalatedSize; - +#endif /* PUCCH resource */ schAllocPucchResource(cell, dlMsgAlloc->crnti, slot); diff --git a/src/5gnrsch/sch_ue_mgr.c b/src/5gnrsch/sch_ue_mgr.c index 38435461f..8be797c36 100644 --- a/src/5gnrsch/sch_ue_mgr.c +++ b/src/5gnrsch/sch_ue_mgr.c @@ -172,79 +172,51 @@ void fillSchUlLcCtxt(SchUlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg) /******************************************************************* * - * @brief Function to update Sch Ul Lc Cb + * @brief Function to update/allocate dedLC Info * * @details * - * Function : updateSchUlCb + * Function : updateDedLcInfo * - * Functionality: Function to update SCH Ul Lc Cb + * Functionality: Function to fill DLDedLcInfo * - * @returns void + * @params[arg] snssai pointer, + * SchRrmPolicy pointer, + * SchLcPrbEstimate pointer , It will be filled + * isDedicated pointer,(Address of isDedicated flag in LC Context) * - * ****************************************************************/ - -void updateSchUlCb(uint8_t delIdx, SchUlCb *ulInfo) -{ - uint8_t lcIdx = 0; - - for(lcIdx = delIdx; lcIdx < ulInfo->numUlLc; lcIdx++) - { - memcpy(&ulInfo->ulLcCtxt[lcIdx], &ulInfo->ulLcCtxt[lcIdx+1], sizeof(SchUlLcCtxt)); - memset(&ulInfo->ulLcCtxt[lcIdx+1], 0, sizeof(SchUlLcCtxt)); - } - /*Leakage of Last Index*/ - /*Last index of ulLcCtxt(before deletion) should be void*/ - if(ulInfo->ulLcCtxt[ulInfo->numUlLc].snssai != NULLP) - { - DU_LOG("ERROR --> SCH: updateSchUlCb Last index:%d (Before Deletion) memory is leaking",\ - ulInfo->numUlLc); - SCH_FREE(ulInfo->ulLcCtxt[ulInfo->numUlLc].snssai, sizeof(Snssai)); - } - else - { - DU_LOG("INFO --> SCH: updateSchUlCb Last index:%d (before deletion) memory is freed successfully",\ - ulInfo->numUlLc); - - } -} - -/******************************************************************* - * - * @brief Function to update SCH Dl Lc Cb - * - * @details - * - * Function : updateSchDlCb - * - * Functionality: Function to update SCH DL Lc Cb - * - * @returns void + * @return ROK >> This LC is part of RRM MemberList. + * RFAILED >> FATAL Error + * ROKIGNORE >> This LC is not part of this RRM MemberList * * ****************************************************************/ -void updateSchDlCb(uint8_t delIdx, SchDlCb *dlInfo) +uint8_t updateDedLcInfo(Snssai *snssai, SchRrmPolicy *rrmPolicy, SchLcPrbEstimate *lcPrbEst,\ + bool *isDedicated) { - uint8_t lcIdx = 0; - - for(lcIdx = delIdx; lcIdx < dlInfo->numDlLc; lcIdx++) + if(memcmp(snssai, &(rrmPolicy->memberList.snssai), sizeof(Snssai))) { - memcpy(&dlInfo->dlLcCtxt[lcIdx], &dlInfo->dlLcCtxt[lcIdx+1], sizeof(SchDlLcCtxt)); - memset(&dlInfo->dlLcCtxt[lcIdx+1], 0, sizeof(SchDlLcCtxt)); - } - /*Leakage of Last Index*/ - /*Last index of ulLcCtxt(before deletion) should be void*/ - if(dlInfo->dlLcCtxt[dlInfo->numDlLc].snssai != NULLP) - { - DU_LOG("ERROR --> SCH: updateSchDlCb Last index:%d (before deletion) memory is leaking: Delete the S-NSSAI memory",\ - dlInfo->numDlLc); - SCH_FREE(dlInfo->dlLcCtxt[dlInfo->numDlLc].snssai, sizeof(Snssai)); + if(lcPrbEst->dedLcInfo == NULLP) + { + SCH_ALLOC(lcPrbEst->dedLcInfo, sizeof(DedicatedLCInfo)); + if(lcPrbEst->dedLcInfo == NULLP) + { + DU_LOG("\nINFO --> SCH : Memory Allocation Failed"); + return RFAILED; + } + } + /*Updating latest RrmPolicy*/ + lcPrbEst->dedLcInfo->rsvdDedicatedPRB = \ + (uint16_t)(((rrmPolicy->policyDedicatedRatio)*(MAX_NUM_RB))/100); + *isDedicated = TRUE; + DU_LOG("\nINFO --> SCH : Updated RRM policy, reservedPOOL:%d",lcPrbEst->dedLcInfo->rsvdDedicatedPRB); } + /*else case: This LcCtxt is either a Default LC or this LC is part of someother RRM_MemberList*/ else { - DU_LOG("INFO --> SCH: updateSchDlCb Last index:%d (before deletion) memory is freed successfully",\ - dlInfo->numDlLc); + DU_LOG("\nINFO --> SCH : This SNSSAI is not a part of this RRMPolicy"); } + return ROK; } /******************************************************************* @@ -269,6 +241,9 @@ uint8_t fillSchUeCb(SchUeCb *ueCb, SchUeCfg *ueCfg) uint8_t freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0}; SchPdschCfgCmn pdschCfg; SchPucchDlDataToUlAck *dlDataToUlAck; + CmLListCp *lcLL = NULLP; + uint8_t retDL = ROK, retUL = ROK; + bool isLcIdValid = FALSE; ueCb->ueCfg.cellId = ueCfg->cellId; ueCb->ueCfg.crnti = ueCfg->crnti; @@ -289,7 +264,7 @@ uint8_t fillSchUeCb(SchUeCb *ueCb, SchUeCfg *ueCfg) memcpy(&ueCb->ueCfg.spCellCfg , &ueCfg->spCellCfg, sizeof(SchSpCellCfg)); covertFreqDomRsrcMapToIAPIFormat(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc,\ - freqDomainResource); + freqDomainResource); memset(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, 0, FREQ_DOM_RSRC_SIZE); memcpy(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, freqDomainResource, FREQ_DOM_RSRC_SIZE); @@ -321,55 +296,130 @@ uint8_t fillSchUeCb(SchUeCb *ueCb, SchUeCfg *ueCfg) //Updating SchUlCb and SchDlCb DB in SchUeCb for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++) { + isLcIdValid = FALSE; /*Re-Initializing*/ + + ueLcIdx = ueCfg->schLcCfg[lcIdx].lcId; + CHECK_LCID(ueLcIdx, isLcIdValid); + if(isLcIdValid == FALSE) + { + DU_LOG("ERROR --> SCH: LCID:%d is not Valid",ueLcIdx); + continue; + } if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_ADD) { - fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueCb->ulInfo.numUlLc], &ueCfg->schLcCfg[lcIdx]); - ueCb->ulInfo.numUlLc++; - fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueCb->dlInfo.numDlLc], &ueCfg->schLcCfg[lcIdx]); - ueCb->dlInfo.numDlLc++; + fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]); + fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]); + + /*Checking whether this LC belong to Dedicated S-NSSAI + * and Create the Dedicated LC List & Update the Reserve PRB number*/ + if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP) + { + retDL = updateDedLcInfo(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, \ + ueCb->cellCb->cellCfg.rrmPolicy, &(ueCb->dlLcPrbEst),\ + &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)); + } + if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP) + { + retUL = updateDedLcInfo(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, \ + ueCb->cellCb->cellCfg.rrmPolicy, &(ueCb->ulLcPrbEst),\ + &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)); + } + + if(retUL == RFAILED || retDL == RFAILED)/*FATAL error*/ + { + DU_LOG("\nERROR --> SCH : Failure in updateDedLcInfo"); + return RFAILED; + } } else { - for(ueLcIdx = 0; ueLcIdx < ueCb->ulInfo.numUlLc; ueLcIdx++) //searching for Lc to be Mod + if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId) { - if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId) + if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD) { - if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD) + fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]); + /*Updating the RRM reserved pool PRB count*/ + if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP) { - fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]); - break; + retUL = updateDedLcInfo(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, \ + ueCb->cellCb->cellCfg.rrmPolicy, &(ueCb->ulLcPrbEst),\ + &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)); } - /*BUG: ueCfg using lcIdx (Looping around numLCs in ueCfg whereas - * ueLcIdx Loops around numUlLc in SCH UL DB*/ - if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_DEL) + if(retUL == RFAILED) { - memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt)); - ueCb->ulInfo.numUlLc--; - updateSchUlCb(ueLcIdx, &ueCb->ulInfo); //moving arr elements one idx ahead - - break; + DU_LOG("\nERROR --> SCH : Failed in updating Ded Lc info"); + return RFAILED; } } - }/*End of inner for loop */ + if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_DEL) + { + /*Delete the LC node from the UL LC List*/ + if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated) + { + if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) + { + lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList); + handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); + if(lcLL->count == 0)/*IF No Node in DedicateLCList to be deleted*/ + { + /*Free the Dedicated LC Info structure*/ + SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); + } + } + } + else/*Default LC list*/ + { + lcLL = &(ueCb->ulLcPrbEst.defLcList); + handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); + } + SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); + memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt)); + } + }/*End of UL LC Ctxt*/ - for(ueLcIdx = 0; ueLcIdx < ueCb->dlInfo.numDlLc; ueLcIdx++) //searching for Lc to be Mod + if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId) { - if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId) + if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD) + { + fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]); + /*Updating the RRM policy*/ + if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP) + { + retDL = updateDedLcInfo(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, \ + ueCb->cellCb->cellCfg.rrmPolicy, &(ueCb->dlLcPrbEst), \ + &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)); + } + if(retDL == RFAILED) + { + DU_LOG("\nERROR --> SCH : Failed in updating Ded Lc info"); + return RFAILED; + } + } + if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_DEL) { - if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD) + /*Delete the LC node from the DL LC List*/ + if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated) { - fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]); - break; + if(ueCb->dlLcPrbEst.dedLcInfo != NULLP) + { + lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); + handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); + if(lcLL->count == 0)/*Last Node in DedicateLCList to be deleted*/ + { + /*Free the Dedicated LC Info structure*/ + SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); + } + } } - if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_DEL) + else { - memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt)); - ueCb->dlInfo.numDlLc--; - updateSchDlCb(ueLcIdx, &ueCb->dlInfo); //moving arr elements one idx ahead - break; + lcLL = &(ueCb->dlLcPrbEst.defLcList); + handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE); } + SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); + memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt)); } - }/*End of inner for loop */ + }/*End of DL LC ctxt*/ } SCH_FREE(ueCfg->schLcCfg[lcIdx].drbQos, sizeof(SchDrbQosInfo)); @@ -856,6 +906,7 @@ void deleteSchUeCb(SchUeCb *ueCb) uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0; SchPucchCfg *pucchCfg = NULLP; SchPdschConfig *pdschCfg = NULLP; + CmLListCp *lcLL = NULLP; if(ueCb) { @@ -892,14 +943,32 @@ void deleteSchUeCb(SchUeCb *ueCb) deleteSchPdschServCellCfg(&ueCb->ueCfg.spCellCfg.servCellCfg.pdschServCellCfg); } /*Need to Free the memory allocated for S-NSSAI*/ - for(ueLcIdx = 0; ueLcIdx < ueCb->ulInfo.numUlLc; ueLcIdx++) + for(ueLcIdx = 0; ueLcIdx < MAX_NUM_LC; ueLcIdx++) { SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); + SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); } - for(ueLcIdx = 0; ueLcIdx < ueCb->dlInfo.numDlLc; ueLcIdx++) + + /*Clearing out Dedicated LC list*/ + if(ueCb->dlLcPrbEst.dedLcInfo != NULLP) { - SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); + lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList); + deleteLcLL(lcLL); + SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); } + if(ueCb->ulLcPrbEst.dedLcInfo != NULLP) + { + lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList); + deleteLcLL(lcLL); + SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo)); + } + /*Deleteing the Default LC list*/ + lcLL = &(ueCb->dlLcPrbEst.defLcList); + deleteLcLL(lcLL); + + lcLL = &(ueCb->ulLcPrbEst.defLcList); + deleteLcLL(lcLL); + memset(ueCb, 0, sizeof(SchUeCb)); } } diff --git a/src/5gnrsch/sch_utils.c b/src/5gnrsch/sch_utils.c index fefeff80a..668d0c298 100644 --- a/src/5gnrsch/sch_utils.c +++ b/src/5gnrsch/sch_utils.c @@ -1319,6 +1319,294 @@ bool fillPrbBitmap(uint64_t *prbBitMap, uint16_t startPrb, uint16_t numPrb) return ROK; } + +/************************************************************************** + * + * @brief Update the LCID Node in LCLL as per ActionType + * + * @details + * + * Function : handleLcLList + * + * Functionality: + * Search LCID in LCLL or if not found, create,Delete, or return + * node for this LCID + * + * @params[in] I/P > lcLinkList pointer (LcInfo list) + * I/P > lcId + * I/P > ActionType (Create,Delete or Just search) + * + * @return lcNode > Pointer to the Node for that LcInfo + * If NULLP, FATAL FAILURE + * + * ***********************************************************************/ +LcInfo* handleLcLList(CmLListCp *lcLL, uint8_t lcId, ActionTypeLcLL action) +{ + CmLList *node = NULLP; + LcInfo *lcNode = NULLP; + bool found = FALSE; + + if(lcLL == NULLP) + { + DU_LOG("\nERROR -->SCH: LcList doesnt exist"); + return NULLP; + } + node = lcLL->first; + + /*Traversing the LC LinkList*/ + while(node) + { + lcNode = (LcInfo *)node->node; + if(lcNode->lcId == lcId) + { + DU_LOG("\nINFO --> SCH : LcID:%d found in LL",lcId); + found = TRUE; + break; + } + node = node->next; + }//end of while + + switch(action) + { + case SEARCH: + { + if(!found) + { + lcNode = NULLP; + } + return lcNode; + } + + case CREATE: + { + if(node != NULLP) + return lcNode; + + /*Need to add a new node for this LC*/ + + /*List is empty; Initialize the LL ControlPointer*/ + if(lcLL->count == 0) + { + DU_LOG("\nINFO --> SCH: First LC:%d to add in this List",lcId); + cmLListInit(lcLL); + } + + lcNode = NULLP; + /*Allocate the List*/ + SCH_ALLOC(lcNode, sizeof(LcInfo)); + if(lcNode) + { + lcNode->lcId = lcId; + lcNode->reqBO = 0; + lcNode->allocBO = 0; + lcNode->allocPRB = 0; + } + else + { + DU_LOG("\nERROR --> SCH : Allocation of List failed,lcId:%d",lcId); + return NULLP; + } + + if(addNodeToLList(lcLL, lcNode, NULLP) == RFAILED) + { + DU_LOG("\nERROR --> SCH : failed to Add Node,lcId:%d",lcId); + SCH_FREE(lcNode, sizeof(LcInfo)); + return NULLP; + } + DU_LOG("\nINFO --> SCH : Added new Node in List for lcId:%d\n",lcId); + return lcNode; + } + + case DELETE: + { + if(!found || lcNode == NULLP) + { + DU_LOG("\nERROR --> SCH: LCID: %d not found; thus Deletion unsuccessful",lcId); + } + else + { + if(deleteNodeFromLList(lcLL, node) == ROK) + SCH_FREE(lcNode, sizeof(LcInfo)); + + DU_LOG("\nINFO --> SCH: LCID: %d Deleted successfully",lcId); + } + return NULLP; + } + default: + { + DU_LOG("\nERROR --> SCH: Action type wrong: %d",action); + break; + } + } + return lcNode; +} + +/************************************************************************** + * + * @brief Update ReqPRB for a partiular LCID in LC Linklist + * + * @details + * + * Function : updateLcListReqPRB + * + * Functionality: + * Update ReqPRB for a partiular LCID in LC Linklist + * + * @params[in] I/P > lcLinkList pointer (LcInfo list) + * I/P > lcId + * I/P > reqPRB + * I/P > payloadSize + * + * @return ROK/RFAILED + * + * ***********************************************************************/ +uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize) +{ + LcInfo *lcNode = NULLP; + + lcNode = handleLcLList(lcLL, lcId, CREATE); + + if(lcNode == NULLP) + { + DU_LOG("\nERROR --> SCH : LC is neither present nor able to create in List lcId:%d",lcId); + return RFAILED; + } + lcNode->reqBO = payloadSize; + lcNode->allocBO = 0; + lcNode->allocPRB = 0; /*Re-Initializing the AllocPRB*/ + DU_LOG("\nINFO --> SCH : LCID:%d, reqBO:%d", lcId, lcNode->reqBO); + return ROK; +} + +/************************************************************************** + * + * @brief Delete entire LC Linklist + * + * @details + * + * Function : deleteLcLL + * + * Functionality: + * Delete entire LC Linklist + * + * @params[in] lcLinkList pointer (LcInfo list) + * + * @return void + * + * ***********************************************************************/ +void deleteLcLL(CmLListCp *lcLL) +{ + CmLList *node = NULLP, *next = NULLP; + LcInfo *lcNode = NULLP; + + if(lcLL == NULLP) + { + DU_LOG("\nINFO --> SCH: LcList doesnt exist"); + return; + } + node = lcLL->first; + + while(node) + { + next = node->next; + lcNode = (LcInfo *)node->node; + if(deleteNodeFromLList(lcLL, node) == ROK) + SCH_FREE(lcNode, sizeof(LcInfo)); + node = next; + } +} + +/**************************************************************************** + * + * @brief Calculate the Estimated TBS Size based on Spec 38.421 , Sec 5.3.1.2 + * + * @details + * + * Function : calculateEstimateTBSize + * + * Functionality: + * TBS Size calculation requires numPRB. Since exactPRB for reqBO is unknown thus + * will give the PRB value(from 0 to maxRB) one by one and + * try to find the TBS size closest to reqBO + * + * @params[in] I/P > reqBO, mcsIdx, num PDSCH symbols, + * I/P > maxRB: Maximum PRB count to reach for calculating the TBS + * O/P > estPrb : Suitable PRB count for reaching the correct TBS + * + * + * @return TBS Size > Size which will can be allocated for this LC + * + * + *************************************************************************/ +uint32_t calculateEstimateTBSize(uint32_t reqBO, uint16_t mcsIdx,uint8_t numSymbols,\ + uint16_t maxPRB, uint16_t *estPrb) +{ + uint32_t tbs = 0, effecBO = 0; + + *estPrb = MIN_PRB; + /*Loop Exit: Either estPRB reaches the maxRB or TBS is found greater than equal to reqBO*/ + do + { + tbs = schCalcTbSizeFromNPrb(*estPrb, mcsIdx, numSymbols); + + /*TBS size calculated in above function is in Bits. + * So to convert it into Bytes , we right shift by 3. + * Eg: tbs=128 bits(1000 0000) ; Right Shift by 3: Tbs = 0001 0000(16 bytes)*/ + tbs = tbs >> 3; + *estPrb += 1; + }while((tbs < reqBO) && (*estPrb < maxPRB)); + + /*Effective BO is the Grant which can be provided for this LC. + * Here,it is decided based on whether we can fully cater its requirment (reqBO) + * or has to provide lesser grant due to resource limitation. + * Thus effective BO/Grant for this LC will be min of TBS calculated and reqBO*/ + effecBO = MIN(tbs,reqBO); + return (effecBO); +} +/*Below function for printing will be used in future so disabling it for now*/ +#if 0 +/**************************************************************************** + * + * @brief Print the LC in list for debugging purpose + * + * @details + * + * Function : printLcLL + * + * Functionality: + * For debugging purpose, for printing the LC in the order and + * parameters + * + * @params[in] LcList pointer + * + * @return void + * + *************************************************************************/ +void printLcLL(CmLListCp *lcLL) +{ + CmLList *node = NULLP; + LcInfo *lcNode = NULLP; + + if(lcLL == NULLP) + { + DU_LOG("\nINFO -->SCH: LcList doesnt exist"); + return; + } + node = lcLL->first; + while(node) + { + lcNode = (LcInfo *)node->node; + if(lcNode) + { + DU_LOG("\nINFO --> SCH : LcID:%d, [reqBO, allocBO, allocPRB]:[%d,%d,%d]",\ + lcNode->lcId,lcNode->reqBO, lcNode->allocBO, lcNode->allocPRB); + } + + node = node->next; + } +} +#endif + #ifdef NR_TDD /** diff --git a/src/5gnrsch/sch_utils.h b/src/5gnrsch/sch_utils.h index 98c3e7e5b..78a0400c4 100644 --- a/src/5gnrsch/sch_utils.h +++ b/src/5gnrsch/sch_utils.h @@ -33,6 +33,7 @@ #define TOTAL_TBSIZE_VALUES 93 #define DEFAULT_UL_ACK_LIST_COUNT 8 /* Max number of pusch time domain uplink allocation */ #define MASK_BIT64_ON 0xFFFFFFFFFFFFFFFF +#define MIN_PRB 1 #define SET_BITS_MSB(_startBit, _numBits, _byte) \ { \ @@ -128,6 +129,14 @@ void removeAllocatedPrbFromFreePrbList(CmLListCp *freePrbBlockList, CmLList *nod uint8_t findDmrsStartSymbol(uint16_t dlDmrsSymbBitMap); void covertFreqDomRsrcMapToIAPIFormat(uint8_t *sourceBitMap, uint8_t *destBitMap); +uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize); +uint32_t calculateEstimateTBSize(uint32_t reqBO, uint16_t mcsIdx,uint8_t numSymbols,\ + uint16_t maxPRB, uint16_t *estPrb); +void deleteLcLL(CmLListCp *lcLL); +#if 0 +/*Will be enabled for debugging*/ +void printLcLL(CmLListCp *lcLL); +#endif /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/common_def.h b/src/cm/common_def.h index a244ee195..89b5d8985 100644 --- a/src/cm/common_def.h +++ b/src/cm/common_def.h @@ -59,7 +59,7 @@ #define MAX_NUM_MU 4 #define MAX_NUM_UE 2 #define MAX_NUM_UE_PER_TTI 1 -#define MAX_NUM_LC 32 /*Spec 38.331: Sec 6.4: maxLC-ID Keyword*/ +#define MAX_NUM_LC MAX_DRB_LCID + 1 /*Spec 38.331: Sec 6.4: maxLC-ID Keyword*/ #define MAX_NUM_SRB 3 /* Max. no of Srbs */ #define MAX_NUM_DRB 29 /* spec 38.331, maxDRB */ @@ -195,6 +195,11 @@ _isCrntiValid = ((_crnti >= ODU_START_CRNTI && _crnti <= ODU_END_CRNTI ) ? 1 : 0); \ } +#define CHECK_LCID(_lcId, _isLcidValid) \ +{\ + _isLcidValid = ((_lcId >= SRB0_LCID && _lcId <= MAX_DRB_LCID) ? 1 : 0);\ +} + typedef enum { UE_CFG_INACTIVE, -- 2.16.6