X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrsch%2Fsch_common.c;h=51673306c09a2bdf3404d750341a5fa26e57afe4;hb=2e3617064e27b8d7bb5ba74319f8c1c99491b8dd;hp=da6fd9cf07c07827cd71eb6b16e2c9d27af9469a;hpb=47a15faec02b721d3e466815eb388fea0a209e3c;p=o-du%2Fl2.git diff --git a/src/5gnrsch/sch_common.c b/src/5gnrsch/sch_common.c index da6fd9cf0..51673306c 100644 --- a/src/5gnrsch/sch_common.c +++ b/src/5gnrsch/sch_common.c @@ -41,6 +41,7 @@ File: sch_common.c #include "du_app_mac_inf.h" #include "mac_sch_interface.h" #include "sch.h" +#include "sch_tmr.h" #include "sch_utils.h" /** @@ -138,9 +139,9 @@ uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcst } dlBrdcstAlloc->crnti = SI_RNTI; - dmrs = cell->sib1SchCfg.sib1PdcchCfg.dci.pdschCfg.dmrs; - freqAlloc = cell->sib1SchCfg.sib1PdcchCfg.dci.pdschCfg.pdschFreqAlloc; - timeAlloc = cell->sib1SchCfg.sib1PdcchCfg.dci.pdschCfg.pdschTimeAlloc; + dmrs = cell->sib1SchCfg.sib1PdcchCfg.dci[0].pdschCfg.dmrs; + freqAlloc = cell->sib1SchCfg.sib1PdcchCfg.dci[0].pdschCfg.pdschFreqAlloc; + timeAlloc = cell->sib1SchCfg.sib1PdcchCfg.dci[0].pdschCfg.pdschTimeAlloc; schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot]; /* Find total symbols used including DMRS */ @@ -406,20 +407,20 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\ * @return ROK/RFAILED **/ -uint16_t fillPucchResourceInfo(uint8_t ueId, SchPucchInfo *schPucchInfo, Inst inst, SlotTimingInfo slotInfo) +uint16_t fillPucchResourceInfo(SchCellCb *cell, uint8_t ueId, SchPucchInfo *schPucchInfo, SlotTimingInfo slotInfo,\ + SchPdcchAllocInfo *pdcchAllocInfo) { - uint8_t ret = ROK, ueIdx = 0, pucchIdx = 0; - SchCellCb *cell = schCb[inst].cells[inst]; + uint8_t ret = RFAILED, ueIdx = 0, pucchIdx = 0; + uint8_t val_pri = 0, r_pucch = 0, cRSetIdx = 0; + uint16_t startPrb = 0, n_cce = 0, N_cce = 0; SchPucchCfgCmn *pucchCfg = NULLP; - SchBwpParams *ulBwp = NULLP; -#ifdef NR_DRX + SchBwpDlCfg *initialDlBwp = NULLP; + SchBwpUlCfg *initialUlBwp = NULLP; SchUeCb *ueCb = NULLP; -#endif - uint16_t startPrb; ueIdx = ueId -1; -#ifdef NR_DRX ueCb = &(cell->ueCb[ueIdx]); +#ifdef NR_DRX if(ueCb->ueDrxInfoPres) { if(!ueCb->drxUeCb.drxUlUeActiveStatus) @@ -430,27 +431,70 @@ uint16_t fillPucchResourceInfo(uint8_t ueId, SchPucchInfo *schPucchInfo, Inst in { /* fill pucch dedicated cfg */ ret = fillUlSchedPucchDedicatedCfg(cell,\ - &cell->ueCb[ueIdx].ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg, &slotInfo, schPucchInfo); + &cell->ueCb[ueIdx].ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg, &slotInfo, schPucchInfo); if(ret == RFAILED) { memset(schPucchInfo, 0, sizeof(SchPucchInfo)); DU_LOG("\nERROR --> SCH : Filling PUCCH dedicated cfg failed at fillPucchResourceInfo()"); - return ret; + return ret; } } else { /* fill pucch common cfg */ - /* derive pucchResourceSet from schCellCfg */ pucchCfg = &cell->cellCfg.ulCfgCommon.schInitialUlBwp.pucchCommon; pucchIdx = pucchCfg->pucchResourceCommon; - ulBwp = &cell->cellCfg.ulCfgCommon.schInitialUlBwp.bwp; - startPrb = ulBwp->freqAlloc.startPrb + pucchResourceSet[pucchIdx][3]; + initialUlBwp = &cell->cellCfg.ulCfgCommon.schInitialUlBwp; + + /*As per Spec 38.213, Sec 9.2.1, StartPrb is determined by by DCI and PDCCH CCE location + * N_cce = Num of CCEs in COreset used for PDCCH + * n_cce = first index of CCE used for PDCCH + * val_pri = PUCCH resource indicator field in DCI format 1_0/1_1*/ + /* derive pucchResourceSet from schCellCfg */ + if(pdcchAllocInfo != NULLP) + { + for(cRSetIdx = 0; cRSetIdx < MAX_NUM_CRSET; cRSetIdx++ ) + { + if(ueCb->pdcchInfo[cRSetIdx].cRSetRef->cRSetId == pdcchAllocInfo->cRSetId) + { + N_cce = ueCb->pdcchInfo[cRSetIdx].totalCceCount; + break; + } + } + n_cce = pdcchAllocInfo->cceIndex; + } + else + { + initialDlBwp = &cell->cellCfg.dlCfgCommon.schInitialDlBwp; + /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */ + N_cce = coresetIdxTable[initialDlBwp->pdcchCommon.commonSearchSpace.coresetId][1] * \ + coresetIdxTable[initialDlBwp->pdcchCommon.commonSearchSpace.coresetId][2]; + n_cce = 4;/*As per current Implementation, default value of cceIndex for CORESET0 is 4*/ + } + val_pri = PUCCH_RES_IND; + + /*Following calculation are derived from Spec 38.213, Sec 9.2.1*/ + r_pucch = (floor((2 * n_cce)/N_cce)) + (2 * val_pri); + + if((floor(r_pucch/8)) == 0) + { + startPrb = pucchResourceSet[pucchIdx][3] + (floor(r_pucch/pucchResourceSet[pucchIdx][4])); + } + else if((floor(r_pucch/8)) == 1) + { + startPrb = initialUlBwp->bwp.freqAlloc.numPrb - 1 - pucchResourceSet[pucchIdx][3] - \ + (floor((r_pucch - 8)/pucchResourceSet[pucchIdx][4])); + } + else + { + DU_LOG("\nERROR --> SCH: Invalid value of r_pucch:%d (greater than 15) ", r_pucch); + return ret; + } ret = allocatePrbUl(cell, slotInfo, pucchResourceSet[pucchIdx][1], pucchResourceSet[pucchIdx][2],\ &startPrb, PUCCH_NUM_PRB_FORMAT_0_1_4); if (ret == ROK) { - schPucchInfo->fdAlloc.startPrb = ulBwp->freqAlloc.startPrb + pucchResourceSet[pucchIdx][3]; + schPucchInfo->fdAlloc.startPrb = startPrb; schPucchInfo->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4; schPucchInfo->tdAlloc.startSymb = pucchResourceSet[pucchIdx][1]; schPucchInfo->tdAlloc.numSymb = pucchResourceSet[pucchIdx][2]; @@ -460,7 +504,7 @@ uint16_t fillPucchResourceInfo(uint8_t ueId, SchPucchInfo *schPucchInfo, Inst in schPucchInfo->srFlag = true; } } - return ROK; + return ret; } /** @@ -484,6 +528,9 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) UlSchedInfo ulSchedInfo; SchUlSlotInfo *schUlSlotInfo = NULLP; SlotTimingInfo ulTimingInfo; + CmLList *node = NULLP; + TotalPrbUsage *ulTotalPrbUsage = NULLP; + memset(&ulSchedInfo, 0, sizeof(UlSchedInfo)); /* add PHY delta */ @@ -496,7 +543,7 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) /* Schedule resources for PRACH */ if(cell->firstSib1Transmitted) - schPrachResAlloc(cell, &ulSchedInfo, ulTimingInfo); + schPrachResAlloc(cell, &ulSchedInfo, ulTimingInfo); schUlSlotInfo = cell->schUlSlotInfo[ulTimingInfo.slot]; if(schUlSlotInfo->schPuschInfo) @@ -513,35 +560,38 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) #endif ulSchedInfo.dataType |= SCH_DATATYPE_PUSCH; memcpy(&ulSchedInfo.schPuschInfo, schUlSlotInfo->schPuschInfo, - sizeof(SchPuschInfo)); + sizeof(SchPuschInfo)); SCH_FREE(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo)); schUlSlotInfo->schPuschInfo = NULL; } if(schUlSlotInfo->pucchPres) { - GET_CRNTI(ulSchedInfo.crnti, schUlSlotInfo->pucchUe); - ret = fillPucchResourceInfo(schUlSlotInfo->pucchUe, &schUlSlotInfo->schPucchInfo, schInst, ulTimingInfo); - if (ret == ROK) - { - ulSchedInfo.dataType |= SCH_DATATYPE_UCI; - memcpy(&ulSchedInfo.schPucchInfo, &schUlSlotInfo->schPucchInfo, - sizeof(SchPucchInfo)); - } - else - { - return RFAILED; - } + GET_CRNTI(ulSchedInfo.crnti, schUlSlotInfo->pucchUe); + ulSchedInfo.dataType |= SCH_DATATYPE_UCI; + memcpy(&ulSchedInfo.schPucchInfo, &schUlSlotInfo->schPucchInfo, + sizeof(SchPucchInfo)); memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo)); } - //send msg to MAC + /* Send msg to MAC */ ret = sendUlSchInfoToMac(&ulSchedInfo, schInst); if(ret != ROK) { DU_LOG("\nERROR --> SCH : Sending UL Sch info from SCH to MAC failed"); } + /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */ + node = cmLListFirst(&schCb[schInst].statistics.activeKpiList.ulTotPrbUseList); + while(node) + { + ulTotalPrbUsage = (TotalPrbUsage *)node->node; + ulTotalPrbUsage->numPrbUsedForTx += schUlSlotInfo->prbAlloc.numPrbAlloc; + ulTotalPrbUsage->totalPrbAvailForTx += MAX_NUM_RB; + node = node->next; + } + + /* Re-initialize UL Slot */ schInitUlSlot(schUlSlotInfo); return ret; } @@ -643,19 +693,19 @@ uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueI pdcch->coresetCfg.shiftIndex = cell->cellCfg.phyCellId; pdcch->coresetCfg.precoderGranularity = 0; /* sameAsRegBundle */ pdcch->numDlDci = 1; - pdcch->dci.rnti = cell->raCb[ueId-1].tcrnti; - pdcch->dci.scramblingId = cell->cellCfg.phyCellId; - pdcch->dci.scramblingRnti = 0; - pdcch->dci.cceIndex = 4; /* considering SIB1 is sent at cce 0-1-2-3 */ - pdcch->dci.aggregLevel = 4; - pdcch->dci.beamPdcchInfo.numPrgs = 1; - pdcch->dci.beamPdcchInfo.prgSize = 1; - pdcch->dci.beamPdcchInfo.digBfInterfaces = 0; - pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0; - pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0; - pdcch->dci.txPdcchPower.beta_pdcch_1_0 = 0; - pdcch->dci.txPdcchPower.powerControlOffsetSS = 0; - pdsch = &pdcch->dci.pdschCfg; + pdcch->dci[0].rnti = cell->raCb[ueId-1].tcrnti; + pdcch->dci[0].scramblingId = cell->cellCfg.phyCellId; + pdcch->dci[0].scramblingRnti = 0; + pdcch->dci[0].cceIndex = 4; /* considering SIB1 is sent at cce 0-1-2-3 */ + pdcch->dci[0].aggregLevel = 4; + pdcch->dci[0].beamPdcchInfo.numPrgs = 1; + pdcch->dci[0].beamPdcchInfo.prgSize = 1; + pdcch->dci[0].beamPdcchInfo.digBfInterfaces = 0; + pdcch->dci[0].beamPdcchInfo.prg[0].pmIdx = 0; + pdcch->dci[0].beamPdcchInfo.prg[0].beamIdx[0] = 0; + pdcch->dci[0].txPdcchPower.beta_pdcch_1_0 = 0; + pdcch->dci[0].txPdcchPower.powerControlOffsetSS = 0; + pdsch = &pdcch->dci[0].pdschCfg; /* fill the PDSCH PDU */ uint8_t cwCount = 0; @@ -752,15 +802,16 @@ uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueI * Scheduling for Pucch Resource * * @params[in] SchCellCb *cell, SlotTimingInfo pucchTime, crnti - * @params[in] SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP + * @params[in] SchUeCb *ueCb, SchDlHqProcCb *hqP, SchPdcchAllocInfo *pdcchAllocInfo * @return ROK - success * RFAILED - failure * *******************************************************************/ -uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti, - SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP) +uint8_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, SchUeCb *ueCb,\ + SchDlHqProcCb *hqP, SchPdcchAllocInfo *pdcchAllocInfo) { + uint8_t ret = RFAILED; uint16_t pucchSlot = 0; SchUlSlotInfo *schUlSlotInfo = NULLP; @@ -768,13 +819,21 @@ uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16 schUlSlotInfo = cell->schUlSlotInfo[pucchSlot]; memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo)); + ret = fillPucchResourceInfo(cell, schUlSlotInfo->pucchUe, &schUlSlotInfo->schPucchInfo,\ + pucchTime, pdcchAllocInfo); + if(ret != ROK) + { + return ret; + } + schUlSlotInfo->pucchPres = true; + if(ueCb != NULLP) { /* set HARQ flag to true */ schUlSlotInfo->schPucchInfo.harqInfo.harqBitLength = 1; /* 1 bit for HARQ */ ADD_DELTA_TO_TIME(pucchTime, pucchTime, 3, cell->numSlots); /* SLOT_DELAY=3 */ - cmLListAdd2Tail(&(ueCb->hqDlmap[pucchTime.slot]->hqList), &hqP->ulSlotLnk); + cmLListAdd2Tail(&(ueCb->hqDlmap[pucchTime.slot]->hqList), &hqP->dlSlotLnk); } return ROK; } @@ -801,15 +860,16 @@ uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16 * ****************************************************************/ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti, uint32_t tbSize, DlMsgSchInfo *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, - uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP) + uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP, SchPdcchAllocInfo pdcchAllocInfo) { - uint8_t ueId=0; - uint8_t cwCount = 0; + uint8_t ueId=0, ssIdx = 0, cRSetIdx = 0;; + uint8_t cwCount = 0, rbgCount = 0, pdcchStartSymbol = 0; PdcchCfg *pdcch = NULLP; PdschCfg *pdsch = NULLP; BwpCfg *bwp = NULLP; SchUeCb ueCb; SchControlRsrcSet coreset1; + SchSearchSpace searchSpace; SchPdschConfig pdschCfg; uint8_t dmrsStartSymbol, startSymbol, numSymbol; @@ -824,7 +884,25 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c GET_UE_ID(crnti, ueId); ueCb = cell->ueCb[ueId-1]; - coreset1 = ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0]; + + for(cRSetIdx = 0; cRSetIdx < ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.numCRsetToAddMod; cRSetIdx++) + { + if(ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[cRSetIdx].cRSetId\ + == pdcchAllocInfo.cRSetId) + { + coreset1 = ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[cRSetIdx]; + break; + } + } + for(ssIdx = 0; ssIdx < ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.numSearchSpcToAddMod; ssIdx++) + { + if(ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.searchSpcToAddModList[ssIdx].searchSpaceId\ + == pdcchAllocInfo.ssId) + { + searchSpace = ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.searchSpcToAddModList[ssIdx]; + break; + } + } pdschCfg = ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg; /* fill BWP */ @@ -834,33 +912,61 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c bwp->cyclicPrefix = cell->sib1SchCfg.bwp.cyclicPrefix; /* fill the PDCCH PDU */ - //Considering coreset1 also starts from same symbol as coreset0 - pdcch->coresetCfg.startSymbolIndex = coresetIdxTable[0][3]; + /*StartSymbol of PDCCH*/ + pdcchStartSymbol = findSsStartSymbol(searchSpace.mSymbolsWithinSlot); + if(pdcchStartSymbol < MAX_SYMB_PER_SLOT) + pdcch->coresetCfg.startSymbolIndex = pdcchStartSymbol; + else + { + DU_LOG("\nERROR --> SCH : Invalid SymbolIndex in schDlRsrcAllocDlMsg"); + return RFAILED; + } pdcch->coresetCfg.durationSymbols = coreset1.duration; memcpy(pdcch->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE); pdcch->coresetCfg.cceRegMappingType = coreset1.cceRegMappingType; /* non-interleaved */ pdcch->coresetCfg.regBundleSize = 6; /* must be 6 for non-interleaved */ pdcch->coresetCfg.interleaverSize = 0; /* NA for non-interleaved */ pdcch->coresetCfg.coreSetType = 1; /* non PBCH coreset */ - //Considering number of RBs in coreset1 is same as coreset0 - pdcch->coresetCfg.coreSetSize = coresetIdxTable[0][1]; + + /*Size of coreset: Number of PRBs in a coreset*/ + rbgCount = countRBGFrmCoresetFreqRsrc(coreset1.freqDomainRsrc); + if(rbgCount) + { + pdcch->coresetCfg.coreSetSize = ((rbgCount) * NUM_PRBS_PER_RBG); + } + else + { + DU_LOG("\nERROR --> SCH : CORESETSize is zero in schDlRsrcAllocDlMsg"); + return RFAILED; + } + pdcch->coresetCfg.shiftIndex = cell->cellCfg.phyCellId; pdcch->coresetCfg.precoderGranularity = coreset1.precoderGranularity; - pdcch->numDlDci = 1; - pdcch->dci.rnti = ueCb.crnti; - pdcch->dci.scramblingId = cell->cellCfg.phyCellId; - pdcch->dci.scramblingRnti = 0; - pdcch->dci.cceIndex = 0; /* 0-3 for UL and 4-7 for DL */ - pdcch->dci.aggregLevel = 4; - pdcch->dci.beamPdcchInfo.numPrgs = 1; - pdcch->dci.beamPdcchInfo.prgSize = 1; - pdcch->dci.beamPdcchInfo.digBfInterfaces = 0; - pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0; - pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0; - pdcch->dci.txPdcchPower.beta_pdcch_1_0 = 0; - pdcch->dci.txPdcchPower.powerControlOffsetSS = 0; - - pdsch = &pdcch->dci.pdschCfg; + if(pdcch->numDlDci >= MAX_NUM_PDCCH) + { + DU_LOG("\nERROR --> SCH: MAX number of PDCCH allocted for this slot."); + return RFAILED; + } + pdcch->dci[pdcch->numDlDci].rnti = ueCb.crnti; + pdcch->dci[pdcch->numDlDci].scramblingId = cell->cellCfg.phyCellId; + pdcch->dci[pdcch->numDlDci].scramblingRnti = 0; + + /*TODO below assumptions of CCE Index is wrong: + * Range 0 to 135 as per ORAN.WG8.AAD Table 9-35 CORESET configuration and + * it has to be calculated using the formula given in 3GPP TS 38.213, Sec 10.1 */ + pdcch->dci[pdcch->numDlDci].cceIndex = pdcchAllocInfo.cceIndex; + pdcch->dci[pdcch->numDlDci].aggregLevel = pdcchAllocInfo.aggLvl; + pdcch->dci[pdcch->numDlDci].beamPdcchInfo.numPrgs = 1; + pdcch->dci[pdcch->numDlDci].beamPdcchInfo.prgSize = 1; + pdcch->dci[pdcch->numDlDci].beamPdcchInfo.digBfInterfaces = 0; + pdcch->dci[pdcch->numDlDci].beamPdcchInfo.prg[0].pmIdx = 0; + pdcch->dci[pdcch->numDlDci].beamPdcchInfo.prg[0].beamIdx[0] = 0; + pdcch->dci[pdcch->numDlDci].txPdcchPower.beta_pdcch_1_0 = 0; + pdcch->dci[pdcch->numDlDci].txPdcchPower.powerControlOffsetSS = 0; + + pdsch = &pdcch->dci[pdcch->numDlDci].pdschCfg; + pdcch->numDlDci++; + pdsch->pduBitmap = 0; /* PTRS and CBG params are excluded */ pdsch->rnti = ueCb.crnti; pdsch->pduIndex = 0; @@ -920,7 +1026,7 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c /* Allocate the number of PRBs required for DL PDSCH */ if((allocatePrbDl(cell, slotTime, startSymbol, numSymbol,\ - &pdsch->pdschFreqAlloc.startPrb, pdsch->pdschFreqAlloc.numPrb)) != ROK) + &pdsch->pdschFreqAlloc.startPrb, pdsch->pdschFreqAlloc.numPrb)) != ROK) { DU_LOG("\nERROR --> SCH : allocatePrbDl() failed for DL MSG"); SCH_FREE(dlMsgAlloc->dlMsgPdcchCfg, sizeof(PdcchCfg)); @@ -1709,7 +1815,7 @@ void fillDlMsgInfo(DlMsgSchInfo *dlMsgSchInfo, uint16_t crnti, bool isRetx, SchD dlMsgSchInfo->harqProcNum = hqP->procId; dlMsgSchInfo->dlAssignIdx = 0; dlMsgSchInfo->pucchTpc = 0; - dlMsgSchInfo->pucchResInd = 0; + dlMsgSchInfo->pucchResInd = PUCCH_RES_IND; dlMsgSchInfo->harqFeedbackInd = hqP->k1; dlMsgSchInfo->dciFormatId = 1; } @@ -1758,7 +1864,7 @@ uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId } if(findValidK0K1Value(cell, currTime, ueId, false, &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime,\ - &pucchTime, isRetxMsg4, *msg4HqProc) != true ) + &pucchTime, isRetxMsg4, *msg4HqProc, NULLP) != true ) { DU_LOG("\nERROR --> SCH: schProcessMsg4Req() : k0 k1 not found"); return RFAILED; @@ -1804,7 +1910,7 @@ uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = NULLP; return RFAILED; } - memcpy(dciSlotAlloc->dlMsgPdschCfg, &dciSlotAlloc->dlMsgPdcchCfg->dci.pdschCfg, sizeof(PdschCfg)); + memcpy(dciSlotAlloc->dlMsgPdschCfg, &dciSlotAlloc->dlMsgPdcchCfg->dci[0].pdschCfg, sizeof(PdschCfg)); } else { @@ -1835,7 +1941,7 @@ uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId SCH_ALLOC(msg4SlotAlloc->dlMsgPdschCfg, sizeof(PdschCfg)); if(msg4SlotAlloc->dlMsgPdschCfg) { - memcpy(msg4SlotAlloc->dlMsgPdschCfg, &dciSlotAlloc->dlMsgPdcchCfg->dci.pdschCfg, sizeof(PdschCfg)); + memcpy(msg4SlotAlloc->dlMsgPdschCfg, &dciSlotAlloc->dlMsgPdcchCfg->dci[0].pdschCfg, sizeof(PdschCfg)); } else { @@ -1853,12 +1959,9 @@ uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId } } - /* PUCCH resource */ - schAllocPucchResource(cell, pucchTime, cell->raCb[ueId-1].tcrnti, &cell->ueCb[ueId-1], isRetxMsg4, *msg4HqProc); - cell->schDlSlotInfo[pdcchTime.slot]->pdcchUe = ueId; - cell->schDlSlotInfo[pdschTime.slot]->pdschUe = ueId; cell->schUlSlotInfo[pucchTime.slot]->pucchUe = ueId; + cell->raCb[ueId-1].msg4recvd = FALSE; if(isRetxMsg4) { @@ -2284,6 +2387,277 @@ bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, S return k2Found; } +/* + * * @brief : This Function fills the Coreset and SS info based on PDCCH Cfg received for a UE + * + * Function : fillUeCoresetAndSsInfo + * + * For a Coreset, capture the following details which will be used during pdcch allocation + * [Step 1]: Count number of RBG and calculate TotalPRBs which can be used + * [Step 2]: Get the reference pointer for Coreset and Its SearchSpace. + * [Step 3]: A CCE will have 6 RBs in TOTAL. If duration increases, CCE will + * occupy less number of PRBs(1RB x 1 OFDM Symbol). Eg. If duration = 2, then + * instead of 6 PRBs, CCE will only occupy 3 PRBs and 2 OFDM symbols. + * [Step 4]: Based on CoresetSize, fill AggLvl-CQI mapping by calculating the dciSize. + * [Step 5]: Calculate Y value for this coreset and UE + * + * @Params[in]: UeCb, + * [return]: ROK, RFAILED : Memory allocation failure. + **/ +uint8_t fillUeCoresetAndSsInfo(SchUeCb *ue) +{ + uint8_t cRSetIdx = 0,ssIdx = 0; + uint16_t rbgCount = 0; + SchPdcchConfig *pdcchCfg = NULLP; + + pdcchCfg = &ue->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg; + if(pdcchCfg == NULLP) + { + DU_LOG("\nERROR --> SCH: PDCCH Cfg is not received thus skip filling of Coreset & SS info"); + return RFAILED; + } + for(cRSetIdx = 0; cRSetIdx < pdcchCfg->numCRsetToAddMod; cRSetIdx++ ) + { + /*[Step 1]: *//*Size of coreset: Number of PRBs in a coreset*/ + rbgCount = countRBGFrmCoresetFreqRsrc(pdcchCfg->cRSetToAddModList[cRSetIdx].freqDomainRsrc); + if(rbgCount) + { + ue->pdcchInfo[cRSetIdx].totalPrbs = ((rbgCount) * NUM_PRBS_PER_RBG); + } + else + { + DU_LOG("\nERROR --> SCH : CORESETSize is zero in fillCoresetAndSsConfg"); + continue; + } + /*[Step 2]:*/ + ue->pdcchInfo[cRSetIdx].cRSetRef = &pdcchCfg->cRSetToAddModList[cRSetIdx]; + for(ssIdx = 0; ssIdx < pdcchCfg->numSearchSpcToAddMod; ssIdx++) + { + if(pdcchCfg->searchSpcToAddModList[ssIdx].cRSetId == pdcchCfg->cRSetToAddModList[cRSetIdx].cRSetId) + { + ue->pdcchInfo[cRSetIdx].ssRef = &pdcchCfg->searchSpcToAddModList[ssIdx]; + break; + } + } + + /*[Step 3]:*/ + /*nrOfPRBPerCce is Number of PRBs occupied by a CCE based on Duration*/ + ue->pdcchInfo[cRSetIdx].nrOfPRBPerCce = NUM_PRBS_PER_RBG/pdcchCfg->cRSetToAddModList[cRSetIdx].duration; + ue->pdcchInfo[cRSetIdx].totalCceCount = rbgCount * pdcchCfg->cRSetToAddModList[cRSetIdx].duration; + + /*[Step 4]:*/ + fillCqiAggLvlMapping(&ue->pdcchInfo[cRSetIdx]); + + /*[Step 5]:*/ + if(RFAILED == schUpdValY(ue, &ue->pdcchInfo[cRSetIdx])) + { + return RFAILED; + } + } + return ROK; +} + +/* + * @brief: Function will validate a slot for PDCCH allocation + * + * Function: schPdcchSlotValidation + * + * As per 3gpp Spec 38.331, SearchSpace parameter, Every SearchSpace will have + * details of which slot and after how many slot the UE will monitor for PDCCH. + * Thus, while PDCCH allocation we need to ensure the above validation passes. + * + * @param [IN]: PDCCH time, SearchSpace Info, numSlots in Cell + * [RETURN]: Flag depicting the slot validation + * */ +bool schPdcchSlotValidation(SlotTimingInfo pdcchTime, SchSearchSpace *searchSpace, uint16_t numSlots) +{ + bool isSlotValid = false; + uint16_t slotNum = 0, mSlotPeriodicityVal = 0; + + /*Converting the timing info in units of Slots*/ + slotNum = (pdcchTime.sfn * numSlots)+pdcchTime.slot; + + mSlotPeriodicityVal = \ + schConvertSlotPeriodicityEnumToValue(searchSpace->mSlotPeriodicityAndOffset.mSlotPeriodicity); + + if(!mSlotPeriodicityVal) + { + DU_LOG("\nERROR --> SCH: Slot Periodicity is ZERO thus cant proceed with this SearchSpace"); + return false; + } + /*The Monitoring slot begins from offset thus skip the slots which are less + * than offset value*/ + if((slotNum >= searchSpace->mSlotPeriodicityAndOffset.mSlotOffset)) + { + /*A pdcch Slot will start after Slotoffset and will get repeated after every + * SlotPeriodicity*/ + if(((slotNum - searchSpace->mSlotPeriodicityAndOffset.mSlotOffset) % mSlotPeriodicityVal) == 0) + { + DU_LOG("\nINFO --> SCH: SFN:%d/Slot:%d, is a Valid PDCCH slot",pdcchTime.sfn, pdcchTime.slot); + isSlotValid = true; + } + else + { + DU_LOG("\nINFO --> SCH: SFN:%d/Slot:%d, is InValid PDCCH slot",pdcchTime.sfn, pdcchTime.slot); + } + } + return (isSlotValid); +} + +/* + * @brief: Function to check if PDCCH is available for a cceIndex + * + * Function: schCheckPdcchAvail + * + * This function checks if the PRBs available for a particular CCE during + * PDCCH allocation + * [Step 1]: Calculate the rbgIndex from cceIndex which depends on Coreset symbol duration + * i.e. a) If symbolDuration = 1; numPrbs in RBG (6) = numPrbPerCCE thus one on + * one mapping between rbgIndex and cceIndex + * b) if SymbolDuration =2; NumPrbs in RBG(6) = numPrbPerCCE * duration + * as CCE needs 6 REG thus in 3 PRBs whole CCE can contain + * c) and so on + * + * [Step 2]: Again StartPRB for a rbgIndex may not be same for CCE Index which + * depends on duration. If duration=2, then two CCE can be occupied + * in one RBGIndex thus StarPrb for secondCCE will be + * numPrbsPerCCE(3) away. + * + * @params[in]: CellCb, SlotTime, cceIndex, PDcchInfo, aggLvl + * */ +bool schCheckPdcchAvail(SchCellCb *cellCb, SlotTimingInfo slotTime, uint8_t cceIndex,\ + SchPdcchInfo *pdcchInfo, uint8_t aggLvl ) +{ + uint8_t rbgIndex = 0, ret = 0, startSymbol = 0; + uint16_t startPrb = MAX_NUM_RB, numPrb = 0; + + /*[Step 1]: rbgIndex to locate in FreqDomainResource parmaeter in + * SearchSpace*/ + rbgIndex = cceIndex / (pdcchInfo->cRSetRef->duration); + + /*Extract StartPRB for that RBGIndex*/ + startPrb = extractStartPrbForRBG(pdcchInfo->cRSetRef->freqDomainRsrc, rbgIndex); + if(startPrb == MAX_NUM_RB) + { + DU_LOG("\nERROR --> SCH: No RBG is allocated for PDCCH in this Coreset"); + return false; + } + /*[Step 2]: Adjust StartPrb based on CCEIndex and duration*/ + startPrb = startPrb + ((cceIndex % pdcchInfo->cRSetRef->duration) * (pdcchInfo->nrOfPRBPerCce)); + startSymbol = findSsStartSymbol(pdcchInfo->ssRef->mSymbolsWithinSlot); + + /*numPrb will also get adjusted with duration*/ + numPrb = (NUM_PRBS_PER_RBG * aggLvl) / pdcchInfo->cRSetRef->duration; + DU_LOG("\nDEBUG --> SCH: RBG found for cceIndex:%d, AggLvl:%d and SymbolDuration%d with StartPrb:%d, numPrb:%d",\ + cceIndex, aggLvl, pdcchInfo->cRSetRef->duration, startPrb, numPrb); + + ret = allocatePrbDl(cellCb, slotTime, startSymbol,\ + pdcchInfo->cRSetRef->duration, &startPrb, numPrb); + + if(ret == RFAILED) + { + DU_LOG("\nERROR --> SCH: PRBs can't be allocated as they are unavailable"); + return false; + } + return true; + +} + +/* + * @brief: Function to select particular UE based on validation of PDCCH allocation + * + * Function: + * This function will have multiple layers of validation for PDCCH allocation + * based on CORESET and SearchSpace configuration and availability. + * + * [Step 1]: Check if the slot is pdcch Slot or not based on SearchSpace's + * monitoringSlotInfo. + * [Step 2]: Check the CQI for this UE and decide upon which Agg Level has to + * be used for this PDCCH transmission + * [Step 3]: find the AggLevel for this CQI = base aggregation level + * [Step 4]: NextLowerAggLvl will be the next lower aggLevel when PDCCH + * allocation fails for base agg Level. + * [Step 5]: For each candidate , calculate the CCE Index as per TS + * 38.213v15, Sec 10.1 and also check PRBs falling in that CCEIndex is free. + * [Step 6]: If Step 5 fails, move to next candidate and if Candidate gets + * exhausted then fallback to nextAggLevel. Because as we decrease aggLevel, + * numberOfCCEReq decreases so chances of PDCCH allocation increases even + * though lowerAggLevel will not guarantee transmission of PDCCH as per CQI + * reported.(CQI less, AggiLvlRequried is More) + * + * @params[IN]: SchUeCb and PdcchTime + * [RETURN]: isPDCCHAllocted flag(true = UE can be selected as a + * candidate ) + * */ +bool schDlCandidateSelection(SchUeCb *ueCb, SlotTimingInfo pdcchTime, SchPdcchAllocInfo *pdcchAllocInfo) +{ + uint8_t cRSetIdx = 0, cceIndex = 0; + uint8_t cqi = 0, candIdx = 0; + uint8_t baseAggLvl = 0, nextLowerAggLvl = 0, numCandidates = 0; + SchPdcchInfo *pdcchInfo = NULLP; + uint32_t a = 0, b = 0; + + for(cRSetIdx = 0; cRSetIdx < MAX_NUM_CRSET; cRSetIdx++) + { + pdcchInfo = &ueCb->pdcchInfo[cRSetIdx]; + if(pdcchInfo->cRSetRef == NULLP) + { + DU_LOG("\nINFO --> SCH: Coreset is not availabe at Index:%d",cRSetIdx); + continue; + } + /*[Step 1]:*/ + if(false == schPdcchSlotValidation(pdcchTime, pdcchInfo->ssRef, ueCb->cellCb->numSlots)) + { + DU_LOG("\nINFO --> SCH: This slot is not valid for PDCCH in this CORESET:%d.",pdcchInfo->cRSetRef->cRSetId); + break; + } + /*[Step 2]:*/ + /*TODO: CQI is reported in DL_CQI_IND which has to be processed and + * report has to be stored in ueCb.For now, HardCoding the value*/ + cqi = 5; + + /*[Step 3]: */ + baseAggLvl = pdcchInfo->cqiIndxAggLvlMap[cqi]; + + /*[Step 4]:*/ + nextLowerAggLvl = baseAggLvl; + + /*Loop to traverse through each AggLvl from higher value of aggLevel to + * 1 AggLvl*/ + do + { + /*Configured num of candidates for each Agg Level in search space */ + numCandidates = extractNumOfCandForAggLvl(pdcchInfo->ssRef, nextLowerAggLvl); + if(!numCandidates) + { + DU_LOG("\nINFO --> SCH: Num Of Candidates configured for this AggLvel:%d is ZERO",baseAggLvl); + } + + /*[Step 5]:*/ + for(candIdx= 0; candIdx < numCandidates; candIdx++) + { + /*Formula reference 3GPP TS 38.213v15, Sec 10.1, Variable 'a' and + * 'b' is used for segmenting the formulat for readability purpose + * */ + a = pdcchInfo->y[pdcchTime.slot] + \ + ceil((candIdx * pdcchInfo->totalCceCount)/(baseAggLvl * numCandidates)); + b = ceil(pdcchInfo->totalCceCount * baseAggLvl); + cceIndex = baseAggLvl * (a % b); + if(schCheckPdcchAvail(ueCb->cellCb, pdcchTime, cceIndex, pdcchInfo,nextLowerAggLvl) == true) + { + DU_LOG("\nINFO --> SCH: PDCCH allocation is successful at cceIndex:%d",cceIndex); + pdcchAllocInfo->cRSetId = pdcchInfo->cRSetRef->cRSetId; + pdcchAllocInfo->aggLvl = nextLowerAggLvl; + pdcchAllocInfo->cceIndex = cceIndex; + pdcchAllocInfo->ssId = pdcchInfo->ssRef->searchSpaceId; + return true; + } + } + nextLowerAggLvl = nextLowerAggLvl >> 1; + }while(nextLowerAggLvl > 0 && nextLowerAggLvl <= 16); + } + return false; +} /********************************************************************** End of file **********************************************************************/