X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrsch%2Fsch.c;h=8fd6a871da1e62307c5041dce320840be0f0b22f;hb=a733e46886692ec1525a60243fcfe4465da6457b;hp=056842fb1d918b49aa44ebe419f5226e0f01bf1a;hpb=7fb274708be5434e1573315b106c554d5562ac42;p=o-du%2Fl2.git diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index 056842fb1..8fd6a871d 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -48,8 +48,8 @@ #include "sch.h" #include "sch_utils.h" -SchCb schCb[SCH_MAX_INST]; void SchFillCfmPst(Pst *reqPst,Pst *cfmPst,RgMngmt *cfm); + /* local defines */ SchCellCfgCfmFunc SchCellCfgCfmOpts[] = { @@ -528,8 +528,8 @@ void fillSsbStartSymb(SchCellCb *cellCb) for(uint8_t idx=0; idx SCH : Memory allocation failed in schInitCellCb"); - return RFAILED; + DU_LOG("\nERROR --> SCH : Memory allocation failed in schInitCellCb"); + return RFAILED; } /* UL Alloc */ @@ -700,10 +700,8 @@ void fillSchSib1Cfg(uint8_t mu, uint8_t bandwidth, uint8_t numSlots, SchSib1Cfg uint8_t mValue = 0; uint8_t firstSymbol = 0; /* need to calculate using formula mentioned in 38.213 */ uint8_t slotIndex = 0; - /* TODO : This should be filled through freqDomRscAllocType0() */ - uint8_t FreqDomainResource[6] = {15, 0, 0, 0, 0, 0}; + uint8_t FreqDomainResource[FREQ_DOM_RSRC_SIZE] = {0}; uint16_t tbSize = 0; - uint8_t numPdschSymbols = 11; /* considering pdsch region from symbols 3 to 13 */ uint8_t ssbIdx = 0; PdcchCfg *pdcch = &(sib1SchCfg->sib1PdcchCfg); @@ -733,9 +731,6 @@ void fillSchSib1Cfg(uint8_t mu, uint8_t bandwidth, uint8_t numSlots, SchSib1Cfg slotIndex = (int)((oValue*pow(2, mu)) + floor(ssbIdx*mValue))%numSlots; sib1SchCfg->n0 = slotIndex; - /* calculate the PRBs */ - //freqDomRscAllocType0(((offsetPointA-offset)/6), (numRbs/6), FreqDomainResource); - /* fill BWP */ switch(bandwidth) { @@ -761,7 +756,11 @@ void fillSchSib1Cfg(uint8_t mu, uint8_t bandwidth, uint8_t numSlots, SchSib1Cfg pdcch->coresetCfg.coreSetSize = numRbs; pdcch->coresetCfg.startSymbolIndex = firstSymbol; pdcch->coresetCfg.durationSymbols = numSymbols; - memcpy(pdcch->coresetCfg.freqDomainResource,FreqDomainResource,6); + + /* Fill Bitmap for PRBs in coreset */ + fillCoresetFeqDomAllocMap(((offsetPointA-offset)/6), (numRbs/6), FreqDomainResource); + covertFreqDomRsrcMapToIAPIFormat(FreqDomainResource, pdcch->coresetCfg.freqDomainResource); + pdcch->coresetCfg.cceRegMappingType = 1; /* coreset0 is always interleaved */ pdcch->coresetCfg.regBundleSize = 6; /* spec-38.211 sec 7.3.2.2 */ pdcch->coresetCfg.interleaverSize = 2; /* spec-38.211 sec 7.3.2.2 */ @@ -816,14 +815,14 @@ void fillSchSib1Cfg(uint8_t mu, uint8_t bandwidth, uint8_t numSlots, SchSib1Cfg pdsch->dmrs.dmrsAddPos = DMRS_ADDITIONAL_POS; pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */ - pdsch->pdschFreqAlloc.freqAlloc.startPrb = offsetPointA + SCH_SSB_NUM_PRB + 1; /* the RB numbering starts from coreset0, - and PDSCH is always above SSB */ - pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize,sib1SchCfg->sib1Mcs,numPdschSymbols); + /* the RB numbering starts from coreset0, and PDSCH is always above SSB */ + pdsch->pdschFreqAlloc.freqAlloc.startPrb = offsetPointA + SCH_SSB_NUM_PRB; + pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize,sib1SchCfg->sib1Mcs, NUM_PDSCH_SYMBOL); pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */ pdsch->pdschTimeAlloc.rowIndex = 1; /* This is Intel's requirement. PDSCH should start after PDSCH DRMS symbol */ pdsch->pdschTimeAlloc.timeAlloc.startSymb = 3; /* spec-38.214, Table 5.1.2.1-1 */ - pdsch->pdschTimeAlloc.timeAlloc.numSymb = numPdschSymbols; + pdsch->pdschTimeAlloc.timeAlloc.numSymb = NUM_PDSCH_SYMBOL; pdsch->beamPdschInfo.numPrgs = 1; pdsch->beamPdschInfo.prgSize = 1; pdsch->beamPdschInfo.digBfInterfaces = 0; @@ -856,6 +855,10 @@ uint8_t SchHdlCellCfgReq(Pst *pst, SchCellCfg *schCellCfg) SchCellCfgCfm schCellCfgCfm; Pst rspPst; Inst inst = pst->dstInst-1; + uint8_t coreset0Idx = 0; + uint8_t numRbs = 0; + uint8_t offset = 0; + uint8_t freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0}; SchPdschConfig pdschCfg; #ifdef CALL_FLOW_DEBUG_LOG @@ -872,6 +875,14 @@ uint8_t SchHdlCellCfgReq(Pst *pst, SchCellCfg *schCellCfg) schCellCfg->ssbSchCfg.ssbOffsetPointA); memcpy(&cellCb->cellCfg, schCellCfg, sizeof(SchCellCfg)); + /* Fill coreset frequencyDomainResource bitmap */ + coreset0Idx = cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.coresetId; + numRbs = coresetIdxTable[coreset0Idx][1]; + offset = coresetIdxTable[coreset0Idx][3]; + fillCoresetFeqDomAllocMap(((cellCb->cellCfg.ssbSchCfg.ssbOffsetPointA - offset)/6), (numRbs/6), freqDomainResource); + covertFreqDomRsrcMapToIAPIFormat(freqDomainResource, \ + cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.freqDomainRsrc); + /* Fill K0 - K1 table for common cfg*/ BuildK0K1Table(cellCb, &cellCb->cellCfg.schInitialDlBwp.k0K1InfoTbl, true, cellCb->cellCfg.schInitialDlBwp.pdschCommon, pdschCfg, DEFAULT_UL_ACK_LIST_COUNT, defaultUlAckTbl); @@ -916,10 +927,11 @@ 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 + DlMsgInfo dlMsgInfo; SchUeCb *ueCb = NULLP; SchCellCb *cell = NULLP; SchDlSlotInfo *schDlSlotInfo = NULLP; @@ -942,59 +954,76 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo) ueCb = &cell->ueCb[ueIdx-1]; lcId = dlBoInfo->lcId; - if(lcId == SRB1_LCID || lcId == SRB2_LCID || lcId == SRB3_LCID || \ - (lcId >= MIN_DRB_LCID && lcId <= MAX_DRB_LCID)) + memset(&dlMsgInfo, 0, sizeof(DlMsgInfo)); + dlMsgInfo.crnti = dlBoInfo->crnti; + dlMsgInfo.ndi = 1; + dlMsgInfo.harqProcNum = 0; + dlMsgInfo.dlAssignIdx = 0; + dlMsgInfo.pucchTpc = 0; + dlMsgInfo.pucchResInd = 0; + dlMsgInfo.harqFeedbackInd = 0; + dlMsgInfo.dciFormatId = 1; + + if(lcId == SRB0_LCID) { - SET_ONE_BIT(ueIdx, cell->boIndBitMap); - ueCb->dlInfo.dlLcCtxt[lcId].bo = dlBoInfo->dataVolume; + cell->raCb[ueIdx -1].msg4recvd = true; + dlMsgInfo.dlMsgPduLen = dlBoInfo->dataVolume; + cell->raCb[ueIdx -1].dlMsgInfo = dlMsgInfo; } - else if(lcId != SRB0_LCID) + else { - DU_LOG("\nERROR --> SCH : Invalid LC Id %d in MacSchDlRlcBoInfo", lcId); - return RFAILED; - } + /* TODO : These part of changes will be corrected during DL scheduling as + * per K0 - K1 -K2 */ + if(lcId == SRB1_LCID || lcId == SRB2_LCID || lcId == SRB3_LCID || \ + (lcId >= MIN_DRB_LCID && lcId <= MAX_DRB_LCID)) + { + SET_ONE_BIT(ueIdx, cell->boIndBitMap); + 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) + { + DU_LOG("\nERROR --> SCH : Invalid LC Id %d in MacSchDlRlcBoInfo", lcId); + return RFAILED; + } - slot = (cell->slotInfo.slot + SCHED_DELTA + PHY_DELTA_DL + BO_DELTA) % cell->numSlots; + slot = (cell->slotInfo.slot + SCHED_DELTA + PHY_DELTA_DL + BO_DELTA) % cell->numSlots; #ifdef NR_TDD - while(schGetSlotSymbFrmt(cell->slotFrmtBitMap, slot) != DL_SLOT) - { - slot = (slot + 1)%cell->numSlots; - slotIdx++; - if(slotIdx==cell->numSlots) + while(schGetSlotSymbFrmt(cell->slotFrmtBitMap, slot) != DL_SLOT) { - DU_LOG("\nERROR --> SCH : No DL Slot available"); - return RFAILED; + slot = (slot + 1)%cell->numSlots; + slotIdx++; + if(slotIdx==cell->numSlots) + { + DU_LOG("\nERROR --> SCH : No DL Slot available"); + return RFAILED; + } } - } #endif - schDlSlotInfo = cell->schDlSlotInfo[slot]; + schDlSlotInfo = cell->schDlSlotInfo[slot]; + if(schDlSlotInfo == NULLP) + { + DU_LOG("\nERROR --> SCH : MacSchDlRlcBoInfo(): schDlSlotInfo does not exists"); + return RFAILED; + } - if(schDlSlotInfo == NULLP) - { - DU_LOG("\nERROR --> SCH : MacSchDlRlcBoInfo(): schDlSlotInfo does not exists"); - return RFAILED; - } - SCH_ALLOC(schDlSlotInfo->dlMsgInfo, sizeof(DlMsgInfo)); - if(schDlSlotInfo->dlMsgInfo == NULLP) - { - DU_LOG("\nERROR --> SCH : Memory allocation failed for dlMsgInfo"); - schDlSlotInfo = NULL; - return RFAILED; - } - - schDlSlotInfo->dlMsgInfo->crnti = dlBoInfo->crnti; - schDlSlotInfo->dlMsgInfo->ndi = 1; - schDlSlotInfo->dlMsgInfo->harqProcNum = 0; - schDlSlotInfo->dlMsgInfo->dlAssignIdx = 0; - schDlSlotInfo->dlMsgInfo->pucchTpc = 0; - schDlSlotInfo->dlMsgInfo->pucchResInd = 0; - schDlSlotInfo->dlMsgInfo->harqFeedbackInd = 0; - schDlSlotInfo->dlMsgInfo->dciFormatId = 1; - if(lcId == SRB0_LCID) - { - schDlSlotInfo->dlMsgInfo->isMsg4Pdu = true; - schDlSlotInfo->dlMsgInfo->dlMsgPduLen = dlBoInfo->dataVolume; + SCH_ALLOC(schDlSlotInfo->dlMsgAlloc, sizeof(DlMsgAlloc)); + if(schDlSlotInfo->dlMsgAlloc == NULLP) + { + DU_LOG("\nERROR --> SCH : Memory allocation failed for dlMsgInfo"); + schDlSlotInfo = NULL; + return RFAILED; + } + + schDlSlotInfo->dlMsgAlloc->dlMsgInfo = dlMsgInfo; } return ROK; } @@ -1078,6 +1107,375 @@ uint8_t MacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd) } return ROK; } + +/******************************************************************* + * + * @brief Allocates requested PRBs for DL + * + * @details + * + * Function : allocatePrbDl + * + * Functionality: + * Allocates requested PRBs in DL + * Keeps track of allocated PRB (using bitmap) and remaining PRBs + * + * @params[in] prbAlloc table + * Start symbol + * Number of symbols + * Start PRB + * Number of PRBs + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t allocatePrbDl(SchCellCb *cell, SlotTimingInfo slotTime, \ + uint8_t startSymbol, uint8_t symbolLength, uint16_t *startPrb, uint16_t numPrb) +{ + uint8_t symbol = 0; + uint16_t broadcastPrbStart=0, broadcastPrbEnd=0; + FreePrbBlock *freePrbBlock = NULLP; + CmLList *freePrbNode = NULLP; + PduTxOccsaion ssbOccasion=0, sib1Occasion=0; + SchDlSlotInfo *schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot]; + SchPrbAlloc *prbAlloc = &schDlSlotInfo->prbAlloc; + + /* If startPrb is set to MAX_NUM_RB, it means startPrb is not known currently. + * Search for an appropriate location in PRB grid and allocate requested resources */ + if(*startPrb == MAX_NUM_RB) + { + /* Check if SSB/SIB1 is also scheduled in this slot */ + 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; + } + + /* Iterate through all free PRB blocks */ + freePrbNode = prbAlloc->freePrbBlockList.first; + while(freePrbNode) + { + freePrbBlock = (FreePrbBlock *)freePrbNode->node; + + /* 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 allocated first */ + if((freePrbBlock->endPrb > broadcastPrbEnd) && ((freePrbBlock->endPrb - broadcastPrbEnd) >= numPrb)) + { + /* If sufficient free PRBs are available above bradcast message then, + * endPrb = freePrbBlock->endPrb + * startPrb = endPrb - numPrb +1; + */ + *startPrb = freePrbBlock->endPrb - numPrb +1; + break; + } + else if((broadcastPrbStart > freePrbBlock->startPrb) && ((broadcastPrbStart - freePrbBlock->startPrb) >= numPrb)) + { + /* If free PRBs are available below broadcast message then, + * endPrb = broadcastPrbStart - 1 + * startPrb = endPrb - numPrb +1 + */ + *startPrb = broadcastPrbStart - numPrb; + break; + } + else + { + freePrbNode = freePrbNode->next; + continue; + } + } + else + { + /* Check if requested number of blocks can be allocated from the current block */ + if (freePrbBlock->numFreePrb < numPrb) + { + freePrbNode = freePrbNode->next; + continue; + } + *startPrb = freePrbBlock->endPrb - numPrb +1; + break; + } + } + + /* If no free block can be used to allocated request number of RBs */ + if(*startPrb == MAX_NUM_RB) + return RFAILED; + } + + /* If startPrb is known already, check if requested PRBs are available for allocation */ + else + { + freePrbNode = isPrbAvailable(&prbAlloc->freePrbBlockList, *startPrb, numPrb); + if(!freePrbNode) + { + DU_LOG("\nERROR --> SCH: Requested DL PRB unavailable"); + return RFAILED; + } + } + + /* Update bitmap to allocate PRBs */ + for(symbol=startSymbol; symbol < (startSymbol+symbolLength); symbol++) + { + if(fillPrbBitmap(prbAlloc->prbBitMap[symbol], *startPrb, numPrb) != ROK) + { + DU_LOG("\nERROR --> SCH: fillPrbBitmap() failed for symbol [%d] in DL", symbol); + return RFAILED; + } + } + + /* Update the remaining number for free PRBs */ + removeAllocatedPrbFromFreePrbList(&prbAlloc->freePrbBlockList, freePrbNode, *startPrb, numPrb); + + return ROK; +} + +/******************************************************************* + * + * @brief Allocates requested PRBs for UL + * + * @details + * + * Function : allocatePrbUl + * + * Functionality: + * Allocates requested PRBs in UL + * Keeps track of allocated PRB (using bitmap) and remaining PRBs + * + * @params[in] prbAlloc table + * Start symbol + * Number of symbols + * Start PRB + * Number of PRBs + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t allocatePrbUl(SchCellCb *cell, SlotTimingInfo slotTime, \ + uint8_t startSymbol, uint8_t symbolLength, uint16_t *startPrb, uint16_t numPrb) +{ + uint8_t symbol = 0; + uint16_t prachStartPrb, prachNumPrb, prachEndPrb; + bool isPrachOccasion; + FreePrbBlock *freePrbBlock = NULLP; + CmLList *freePrbNode = NULLP; + SchPrbAlloc *prbAlloc = &cell->schUlSlotInfo[slotTime.slot]->prbAlloc; + + /* If startPrb is set to MAX_NUM_RB, it means startPrb is not known currently. + * Search for an appropriate location in PRB grid and allocate requested resources */ + if(*startPrb == MAX_NUM_RB) + { + /* Check if PRACH is also scheduled in this slot */ + isPrachOccasion = schCheckPrachOcc(cell, slotTime); + if(isPrachOccasion) + { + prachStartPrb = cell->cellCfg.schRachCfg.msg1FreqStart; + prachNumPrb = schCalcPrachNumRb(cell); + prachEndPrb = prachStartPrb + prachNumPrb -1; + } + + /* Iterate through all free PRB blocks */ + freePrbNode = prbAlloc->freePrbBlockList.first; + while(freePrbNode) + { + freePrbBlock = (FreePrbBlock *)freePrbNode->node; + + /* If PRACH is scheduled in this slot, then check if its PRBs belong to the current free block. + * PRBs required for PRACH cannot be allocated to any other message */ + if((isPrachOccasion) && + ((prachStartPrb >= freePrbBlock->startPrb) && (prachStartPrb <= freePrbBlock->endPrb)) && + ((prachEndPrb >= freePrbBlock->startPrb) && (prachEndPrb <= freePrbBlock->endPrb))) + { + /* Implmentation is done such that highest-numbered free-RB is allocated first */ + if((freePrbBlock->endPrb > prachEndPrb) && ((freePrbBlock->endPrb - prachEndPrb) >= numPrb)) + { + /* If sufficient free PRBs are available above PRACH message then, + * endPrb = freePrbBlock->endPrb + * startPrb = endPrb - numPrb +1; + */ + *startPrb = freePrbBlock->endPrb - numPrb +1; + break; + } + else if((prachStartPrb > freePrbBlock->startPrb) && ((prachStartPrb - freePrbBlock->startPrb) >= numPrb)) + { + /* If free PRBs are available below PRACH message then, + * endPrb = prachStartPrb - 1 + * startPrb = endPrb - numPrb +1 + */ + *startPrb = prachStartPrb - numPrb; + break; + } + else + { + freePrbNode = freePrbNode->next; + continue; + } + } + else + { + /* Check if requested number of PRBs can be allocated from currect block */ + if(freePrbBlock->numFreePrb < numPrb) + { + freePrbNode = freePrbNode->next; + continue; + } + *startPrb = freePrbBlock->endPrb - numPrb +1; + break; + } + } + + /* If no free block can be used to allocated requested number of RBs */ + if(*startPrb == MAX_NUM_RB) + return RFAILED; + } + else + { + /* If startPrb is known already, check if requested PRBs are available for allocation */ + freePrbNode = isPrbAvailable(&prbAlloc->freePrbBlockList, *startPrb, numPrb); + if(!freePrbNode) + { + DU_LOG("\nERROR --> SCH: Requested UL PRB unavailable"); + return RFAILED; + } + } + + /* Update bitmap to allocate PRBs */ + for(symbol=startSymbol; symbol < (startSymbol+symbolLength); symbol++) + { + if(fillPrbBitmap(prbAlloc->prbBitMap[symbol], *startPrb, numPrb) != ROK) + { + DU_LOG("\nERROR --> SCH: fillPrbBitmap() failed for symbol [%d] in UL", symbol); + return RFAILED; + } + } + + /* Update the remaining number for free PRBs */ + removeAllocatedPrbFromFreePrbList(&prbAlloc->freePrbBlockList, freePrbNode, *startPrb, numPrb); + + 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 **********************************************************************/