X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrsch%2Fsch_common.c;h=c9967d888450c44f066d712456f4622fc41e4f2f;hb=e96cb439cd4a7a6f55e3fab7caed978e38bd62b4;hp=6a10e8b20181d8393e6e050a865e822ac31d0093;hpb=f1f733a2f14d22b8725e121fa0f5e70a7febc9af;p=o-du%2Fl2.git diff --git a/src/5gnrsch/sch_common.c b/src/5gnrsch/sch_common.c index 6a10e8b20..c9967d888 100644 --- a/src/5gnrsch/sch_common.c +++ b/src/5gnrsch/sch_common.c @@ -139,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 */ @@ -407,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) @@ -431,27 +431,71 @@ 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); + memset(schPucchInfo, 0, sizeof(SchPucchInfo)); + 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]; @@ -461,7 +505,7 @@ uint16_t fillPucchResourceInfo(uint8_t ueId, SchPucchInfo *schPucchInfo, Inst in schPucchInfo->srFlag = true; } } - return ROK; + return ret; } /** @@ -479,9 +523,7 @@ uint16_t fillPucchResourceInfo(uint8_t ueId, SchPucchInfo *schPucchInfo, Inst in uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) { int ret = ROK; -#ifdef NR_DRX - SchUeCb *ueCb; -#endif + uint8_t ueIdx = 0; UlSchedInfo ulSchedInfo; SchUlSlotInfo *schUlSlotInfo = NULLP; SlotTimingInfo ulTimingInfo; @@ -491,7 +533,7 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) memset(&ulSchedInfo, 0, sizeof(UlSchedInfo)); /* add PHY delta */ - ADD_DELTA_TO_TIME(cell->slotInfo,ulTimingInfo,PHY_DELTA_UL+SCHED_DELTA, cell->numSlots); + ADD_DELTA_TO_TIME(cell->slotInfo,ulTimingInfo,gConfigInfo.gPhyDeltaUl+SCHED_DELTA, cell->numSlots); ulSchedInfo.cellId = cell->cellId; ulSchedInfo.slotIndInfo.cellId = ulSchedInfo.cellId; @@ -500,50 +542,41 @@ 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) + if(schUlSlotInfo->puschPres) { - GET_CRNTI(ulSchedInfo.crnti, schUlSlotInfo->puschUe); /* Check the ue drx status if the UE is active for uplink scheduling or not */ -#ifdef NR_DRX - ueCb = schGetUeCb(cell, ulSchedInfo.crnti); - if(ueCb->ueDrxInfoPres) + ulSchedInfo.dataType |= SCH_DATATYPE_PUSCH; + for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) { - if(!ueCb->drxUeCb.drxUlUeActiveStatus) - return RFAILED; + if(schUlSlotInfo->schPuschInfo[ueIdx] != NULLP) + { + memcpy(&ulSchedInfo.schPuschInfo[ueIdx], schUlSlotInfo->schPuschInfo[ueIdx], + sizeof(SchPuschInfo)); + SCH_FREE(schUlSlotInfo->schPuschInfo[ueIdx], sizeof(SchPuschInfo)); + schUlSlotInfo->schPuschInfo[ueIdx] = NULL; + } } -#endif - ulSchedInfo.dataType |= SCH_DATATYPE_PUSCH; - memcpy(&ulSchedInfo.schPuschInfo, schUlSlotInfo->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; - } - memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo)); + ulSchedInfo.dataType |= SCH_DATATYPE_UCI; + memcpy(&ulSchedInfo.schPucchInfo, &schUlSlotInfo->schPucchInfo, + (sizeof(SchPucchInfo) * MAX_NUM_UE)); + memset(&schUlSlotInfo->schPucchInfo, 0, (sizeof(SchPucchInfo) * MAX_NUM_UE)); } - /* Send msg to MAC */ - ret = sendUlSchInfoToMac(&ulSchedInfo, schInst); - if(ret != ROK) + if(ulSchedInfo.dataType > 0) { - DU_LOG("\nERROR --> SCH : Sending UL Sch info from SCH to MAC failed"); + /* 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 */ @@ -658,19 +691,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; @@ -767,29 +800,36 @@ 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, uint8_t ueId, SlotTimingInfo pucchTime, SchUeCb *ueCb,\ + SchDlHqProcCb *hqP, SchPdcchAllocInfo *pdcchAllocInfo) { + uint8_t ret = RFAILED; uint16_t pucchSlot = 0; SchUlSlotInfo *schUlSlotInfo = NULLP; pucchSlot = pucchTime.slot; schUlSlotInfo = cell->schUlSlotInfo[pucchSlot]; - memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo)); - schUlSlotInfo->pucchPres = true; + ret = fillPucchResourceInfo(cell, ueId, &schUlSlotInfo->schPucchInfo[ueId - 1],\ + 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 */ + schUlSlotInfo->schPucchInfo[ueId - 1].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; } @@ -816,9 +856,9 @@ 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 ueId=0, ssIdx = 0, cRSetIdx = 0;; uint8_t cwCount = 0, rbgCount = 0, pdcchStartSymbol = 0; PdcchCfg *pdcch = NULLP; PdschCfg *pdsch = NULLP; @@ -840,8 +880,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]; - searchSpace = ueCb.ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.searchSpcToAddModList[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 */ @@ -881,25 +938,31 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c 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; + 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.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; + 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; @@ -959,7 +1022,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)); @@ -1748,7 +1811,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; } @@ -1797,7 +1860,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; @@ -1843,7 +1906,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 { @@ -1874,7 +1937,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 { @@ -1892,12 +1955,8 @@ 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) { @@ -2017,7 +2076,7 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId } /* Calculating time frame to send DCI for SR */ - ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); + ADD_DELTA_TO_TIME(currTime, dciTime, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(dciTime.slot, cell->slotFrmtBitMap) == DL_SLOT) #endif @@ -2050,7 +2109,8 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId if(schGetSlotSymbFrmt(puschTime.slot, cell->slotFrmtBitMap) == DL_SLOT) continue; #endif - if(cell->schUlSlotInfo[puschTime.slot]->puschUe != 0) + if((cell->schUlSlotInfo[puschTime.slot]->schPuschInfo[ueId - 1] != NULLP) + && cell->schUlSlotInfo[puschTime.slot]->schPuschInfo[ueId - 1]->crnti == ueCb->crnti) { continue; } @@ -2070,7 +2130,7 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId } else { - DU_LOG("\nDEBUG --> SCH : schProcessSrOrBsrReq(): K2 value is not found"); + /* K2 value not found*/ return false; } return true; @@ -2200,7 +2260,7 @@ uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb) currTime = cell->slotInfo; /* Calculating time frame to send DCI for MSG3 Retx*/ - ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); + ADD_DELTA_TO_TIME(currTime, dciTime, gConfigInfo.gPhyDeltaDl + SCHED_DELTA, cell->numSlots); #ifdef NR_TDD /* Consider this slot for sending DCI, only if it is a DL slot */ if(schGetSlotSymbFrmt(dciSlot, raCb->cell->slotFrmtBitMap) == DL_SLOT) @@ -2210,7 +2270,7 @@ uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb) if(cell->schDlSlotInfo[dciSlot]->pdcchUe != 0) return false; - k2Found = schGetMsg3K2(cell, &raCb->msg3HqProc, dciTime.slot, &msg3Time, TRUE); + k2Found = schGetMsg3K2(cell, raCb->ueId, &raCb->msg3HqProc, dciTime.slot, &msg3Time, TRUE); if (!k2Found) { @@ -2223,9 +2283,10 @@ uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb) return RFAILED; } cell->schDlSlotInfo[msg3Time.slot]->ulGrant = dciInfo; - SCH_ALLOC(cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo, sizeof(SchPuschInfo)); + SCH_ALLOC(cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo[raCb->ueId - 1], sizeof(SchPuschInfo)); + cell->schUlSlotInfo[msg3Time.slot]->puschPres = true; memset(dciInfo,0,sizeof(DciInfo)); - schFillUlDciForMsg3Retx(raCb, cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo, dciInfo); + schFillUlDciForMsg3Retx(raCb, cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo[raCb->ueId - 1], dciInfo); } raCb->retxMsg3HqProc = NULLP; return ROK; @@ -2249,7 +2310,7 @@ uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb) * -# true * -# false **/ -bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, SlotTimingInfo *msg3Time, bool isRetx) +bool schGetMsg3K2(SchCellCb *cell, uint8_t ueId, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, SlotTimingInfo *msg3Time, bool isRetx) { bool k2Found = false; uint8_t k2TblIdx = 0; @@ -2261,6 +2322,7 @@ bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, S #ifdef NR_TDD uint8_t totalCfgSlot = 0; #endif + uint16_t crnti = 0; SchK2TimingInfoTbl *msg3K2InfoTbl=NULLP; SlotTimingInfo currTime, msg3TempTime; currTime = cell->slotInfo; @@ -2283,7 +2345,8 @@ bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, S msg3MinSchTime = minMsg3SchTime[cell->numerology]; msg3Delta = puschDeltaTable[puschMu]; } - + + GET_UE_ID(crnti, ueId); for(k2TblIdx = 0; k2TblIdx < numK2; k2TblIdx++) { k2Index = msg3K2InfoTbl->k2TimingInfo[dlTime].k2Indexes[k2TblIdx]; @@ -2306,9 +2369,10 @@ bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, S if(schGetSlotSymbFrmt(msg3TempTime.slot % totalCfgSlot, cell->slotFrmtBitMap) == DL_SLOT) continue; #endif - /* If PUSCH is already scheduled on this slot, another PUSCH - * pdu cannot be scheduled here */ - if(cell->schUlSlotInfo[msg3TempTime.slot]->puschUe != 0) + /* If PUSCH is already scheduled on this slot for this UE, another PUSCH + * pdu cannot be scheduled here for same UE*/ + if((cell->schUlSlotInfo[msg3TempTime.slot]->schPuschInfo[ueId - 1] != NULLP) + && cell->schUlSlotInfo[msg3TempTime.slot]->schPuschInfo[ueId - 1]->crnti == crnti) continue; k2Found = true; break; @@ -2393,7 +2457,207 @@ uint8_t fillUeCoresetAndSsInfo(SchUeCb *ue) 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 **********************************************************************/