[Epic-ID: ODUHIGH-488][Task-ID: ODUHIGH-492] WG8 Alignment [DL Broadcast Allocation]
[o-du/l2.git] / src / 5gnrsch / sch_common.c
index dff28ca..8e7b588 100644 (file)
@@ -121,8 +121,8 @@ uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcst
 {
    uint8_t dmrsStartSymbol, startSymbol, numSymbol ;
    DmrsInfo dmrs;
-   FreqDomainAlloc freqAlloc;
-   TimeDomainAlloc timeAlloc;
+   PdschFreqAlloc freqAlloc;
+   PdschTimeAlloc timeAlloc;
    SchDlSlotInfo *schDlSlotInfo = NULLP;
 
    if(cell == NULL)
@@ -136,10 +136,11 @@ uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcst
       DU_LOG("\nERROR  -->  SCH: schBroadcastSsbAlloc() : dlBrdcstAlloc is NULL");
       return RFAILED;
    }
-
-   dmrs = cell->cellCfg.sib1SchCfg.sib1PdschCfg.dmrs;
-   freqAlloc = cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc;
-   timeAlloc = cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschTimeAlloc.timeAlloc;
+   
+   dlBrdcstAlloc->crnti = SI_RNTI;
+   dmrs = cell->cellCfg.sib1SchCfg.sib1PdcchCfg.dci.pdschCfg->dmrs;
+   freqAlloc = cell->cellCfg.sib1SchCfg.sib1PdcchCfg.dci.pdschCfg->pdschFreqAlloc;
+   timeAlloc = cell->cellCfg.sib1SchCfg.sib1PdcchCfg.dci.pdschCfg->pdschTimeAlloc;
    schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot];
 
    /* Find total symbols used including DMRS */
@@ -167,8 +168,6 @@ uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcst
 
    memcpy(&dlBrdcstAlloc->sib1Alloc.bwp, &cell->cellCfg.sib1SchCfg.bwp, sizeof(BwpCfg)); 
    memcpy(&dlBrdcstAlloc->sib1Alloc.sib1PdcchCfg, &cell->cellCfg.sib1SchCfg.sib1PdcchCfg, sizeof(PdcchCfg)); 
-   memcpy(&dlBrdcstAlloc->sib1Alloc.sib1PdschCfg, &cell->cellCfg.sib1SchCfg.sib1PdschCfg, sizeof(PdschCfg)); 
-   dlBrdcstAlloc->sib1Alloc.sib1PdcchCfg.dci.pdschCfg = &dlBrdcstAlloc->sib1Alloc.sib1PdschCfg;
    schDlSlotInfo->sib1Pres = true;
    return ROK;
 }
@@ -217,7 +216,7 @@ void fillPucchFormat0(SchPucchInfo *ulSchedPucch, SchPucchResrcInfo *resrcInfo)
 {
    if(resrcInfo->SchPucchFormat.format0)
    {
-      ulSchedPucch->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
+      ulSchedPucch->fdAlloc.resAlloc.type1.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
       ulSchedPucch->pucchFormat  = PUCCH_FORMAT_0;
       ulSchedPucch->initialCyclicShift =  resrcInfo->SchPucchFormat.format0->initialCyclicShift;
       ulSchedPucch->tdAlloc.numSymb = resrcInfo->SchPucchFormat.format0->numSymbols;
@@ -242,7 +241,7 @@ void fillPucchFormat1(SchPucchInfo *ulSchedPucch, SchPucchResrcInfo *resrcInfo)
 {
    if(resrcInfo->SchPucchFormat.format1)
    {
-      ulSchedPucch->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
+      ulSchedPucch->fdAlloc.resAlloc.type1.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
       ulSchedPucch->pucchFormat  = PUCCH_FORMAT_1;
       ulSchedPucch->initialCyclicShift =  resrcInfo->SchPucchFormat.format1->initialCyclicShift;
       ulSchedPucch->tdAlloc.numSymb = resrcInfo->SchPucchFormat.format1->numSymbols;
@@ -274,23 +273,24 @@ uint8_t fillUlSchedPucchFormat(uint8_t pucchFormat, SchPucchInfo *ulSchedPucch,\
    {
       case PUCCH_FORMAT_0:
          {
-           if(resrcInfo)
+            if(resrcInfo)
                fillPucchFormat0(ulSchedPucch, resrcInfo);
             return ret;
-        }
+         }
       case PUCCH_FORMAT_1:
          {
-           if(resrcInfo)
-           {
+            if(resrcInfo)
+            {
                fillPucchFormat1(ulSchedPucch, resrcInfo);
-           }
-           if(formatCfg)
-           {
-               memcpy(&ulSchedPucch->cmnFormatCfg, formatCfg, sizeof(SchPucchFormatCfg));
-           }
-           return ret;
-        }/* To Add support for more Pucch Format */
-      
+            }
+            if(formatCfg)
+            {
+               ulSchedPucch->addDmrs = formatCfg->addDmrs;
+               ulSchedPucch->pi2BPSK = formatCfg->pi2BPSK;
+            }
+            return ret;
+         }/* To Add support for more Pucch Format */
+
       default:
          DU_LOG("\nERROR  --> SCH : Invalid PUCCH format[%d] in fillUlSchedPucchFormatCfg()", pucchFormat);
         ret = RFAILED;
@@ -334,7 +334,7 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\
             {
                ulSchedPucch->intraFreqHop = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].intraFreqHop;
                ulSchedPucch->secondPrbHop = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].secondPrbHop;
-               ulSchedPucch->fdAlloc.startPrb = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].startPrb;
+               ulSchedPucch->fdAlloc.resAlloc.type1.startPrb = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].startPrb;
                ulSchedPucch->pucchFormat = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].pucchFormat;
                ret = fillUlSchedPucchFormat(ulSchedPucch->pucchFormat, ulSchedPucch,\
                      &pucchDedCfg->resrc->resrcToAddModList[resrcIdx], NULLP);
@@ -357,7 +357,6 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\
 
    if(pucchDedCfg->format1)
    {
-      memset(&ulSchedPucch->cmnFormatCfg, 0, sizeof(SchPucchFormatCfg));
       ret = fillUlSchedPucchFormat(ulSchedPucch->pucchFormat, ulSchedPucch, NULLP, pucchDedCfg->format1);
       if(ret == RFAILED)
          return ret;
@@ -375,14 +374,12 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\
       {
          srPeriodicity = pucchDedCfg->schedReq->schedAddModList[schedReqIdx].periodicity;
          srOffset      = pucchDedCfg->schedReq->schedAddModList[schedReqIdx].offset;
-        break;
+         break;
       }
       if(((numSlots * slotInfo->sfn + slotInfo->slot - srOffset) % srPeriodicity) == 0)
       {
          ulSchedPucch->srFlag  = true;
-         ulSchedPucch->uciFlag = true;
       }
-      ulSchedPucch->harqFlag  = true;//check how to enable?
    }
    return ret;
 }
@@ -400,9 +397,9 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\
  *  @return  ROK/RFAILED
  **/
 
-uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst, SlotTimingInfo slotInfo)
+uint16_t fillPucchResourceInfo(uint8_t ueId, SchPucchInfo *schPucchInfo, Inst inst, SlotTimingInfo slotInfo)
 {
-   uint8_t ret = ROK, ueId = 0, ueIdx = 0, pucchIdx = 0;
+   uint8_t ret = ROK,  ueIdx = 0, pucchIdx = 0;
    SchCellCb  *cell = schCb[inst].cells[inst];
    SchPucchCfgCmn *pucchCfg = NULLP;
    SchBwpParams *ulBwp = NULLP;
@@ -411,10 +408,9 @@ uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst, SlotTiming
 #endif
    uint16_t startPrb;
 
-   GET_UE_ID(schPucchInfo->rnti, ueId);
    ueIdx = ueId -1;
 #ifdef NR_DRX 
-   ueCb = schGetUeCb(cell, schPucchInfo->rnti);
+   ueCb = &(cell->ueCb[ueIdx]); 
    if(ueCb->ueDrxInfoPres)
    {
       if(!ueCb->drxUeCb.drxUlUeActiveStatus)
@@ -445,15 +441,14 @@ uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst, SlotTiming
             &startPrb, PUCCH_NUM_PRB_FORMAT_0_1_4);
       if (ret == ROK)
       {
-         schPucchInfo->fdAlloc.startPrb = ulBwp->freqAlloc.startPrb + pucchResourceSet[pucchIdx][3];
-         schPucchInfo->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
+         schPucchInfo->fdAlloc.resAlloc.type1.startPrb = ulBwp->freqAlloc.startPrb + pucchResourceSet[pucchIdx][3];
+         schPucchInfo->fdAlloc.resAlloc.type1.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
          schPucchInfo->tdAlloc.startSymb = pucchResourceSet[pucchIdx][1];
          schPucchInfo->tdAlloc.numSymb = pucchResourceSet[pucchIdx][2];
          schPucchInfo->pucchFormat = pucchResourceSet[pucchIdx][0];
 
          /* set SR and UCI flag to false */
          schPucchInfo->srFlag  = true;
-         schPucchInfo->uciFlag = true;
       }
    }
    return ROK;
@@ -497,7 +492,7 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
    schUlSlotInfo = cell->schUlSlotInfo[ulTimingInfo.slot]; 
    if(schUlSlotInfo->schPuschInfo)
    {
-      ulSchedInfo.crnti = schUlSlotInfo->schPuschInfo->crnti;
+      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);
@@ -516,7 +511,8 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
 
    if(schUlSlotInfo->pucchPres)
    {
-      ret = fillPucchResourceInfo(&schUlSlotInfo->schPucchInfo, schInst, ulTimingInfo);
+      GET_CRNTI(ulSchedInfo.crnti, schUlSlotInfo->pucchUe);
+      ret = fillPucchResourceInfo(schUlSlotInfo->pucchUe, &schUlSlotInfo->schPucchInfo, schInst, ulTimingInfo);
       if (ret == ROK)
       {
          ulSchedInfo.dataType |= SCH_DATATYPE_UCI;
@@ -642,7 +638,7 @@ uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueI
    pdcch->dci.beamPdcchInfo.digBfInterfaces = 0;
    pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0;
    pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0;
-   pdcch->dci.txPdcchPower.powerValue = 0;
+   pdcch->dci.txPdcchPower.beta_pdcch_1_0 = 0;
    pdcch->dci.txPdcchPower.powerControlOffsetSS = 0;
    pdcch->dci.pdschCfg = pdsch;
 
@@ -685,12 +681,12 @@ uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueI
    pdsch->dmrs.nrOfDmrsSymbols  = NUM_DMRS_SYMBOLS;
    pdsch->dmrs.dmrsAddPos       = DMRS_ADDITIONAL_POS;
 
-   pdsch->pdschTimeAlloc.timeAlloc.startSymb = pdschStartSymbol; 
-   pdsch->pdschTimeAlloc.timeAlloc.numSymb = pdschNumSymbols;
+   pdsch->pdschTimeAlloc.startSymb = pdschStartSymbol; 
+   pdsch->pdschTimeAlloc.numSymb = pdschNumSymbols;
 
    pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
-   pdsch->pdschFreqAlloc.freqAlloc.startPrb = MAX_NUM_RB;
-   pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, mcs, pdschNumSymbols);
+   pdsch->pdschFreqAlloc.startPrb = MAX_NUM_RB;
+   pdsch->pdschFreqAlloc.numPrb = schCalcNumPrb(tbSize, mcs, pdschNumSymbols);
    pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
 
    /* Find total symbols occupied including DMRS */
@@ -699,19 +695,19 @@ uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueI
     * in that case only PDSCH symbols are marked as occupied */
    if(dmrsStartSymbol == MAX_SYMB_PER_SLOT)
    {
-      startSymbol = pdsch->pdschTimeAlloc.timeAlloc.startSymb;
-      numSymbol = pdsch->pdschTimeAlloc.timeAlloc.numSymb;
+      startSymbol = pdsch->pdschTimeAlloc.startSymb;
+      numSymbol = pdsch->pdschTimeAlloc.numSymb;
    }
    /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
    else
    {
       startSymbol = dmrsStartSymbol;
-      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.timeAlloc.numSymb;
+      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.numSymb;
    }
 
    /* Allocate the number of PRBs required for RAR PDSCH */
    if((allocatePrbDl(cell, msg4Time, startSymbol, numSymbol,\
-      &pdsch->pdschFreqAlloc.freqAlloc.startPrb, pdsch->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
+      &pdsch->pdschFreqAlloc.startPrb, pdsch->pdschFreqAlloc.numPrb)) != ROK)
    {
       DU_LOG("\nERROR  --> SCH : Resource allocation failed for MSG4");
       return RFAILED;
@@ -758,12 +754,10 @@ uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16
    memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo));
 
    schUlSlotInfo->pucchPres = true;
-   schUlSlotInfo->schPucchInfo.rnti = crnti;
    if(ueCb != NULLP)
    {
       /* set HARQ flag to true */
-      schUlSlotInfo->schPucchInfo.harqFlag = true;
-      schUlSlotInfo->schPucchInfo.numHarqBits = 1; /* 1 bit for HARQ */
+      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);
    }
@@ -842,7 +836,7 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c
    pdcch->dci.beamPdcchInfo.digBfInterfaces = 0;
    pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0;
    pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0;
-   pdcch->dci.txPdcchPower.powerValue = 0;
+   pdcch->dci.txPdcchPower.beta_pdcch_1_0 = 0;
    pdcch->dci.txPdcchPower.powerControlOffsetSS = 0;
 
    /* fill the PDSCH PDU */
@@ -880,13 +874,13 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c
    pdsch->dmrs.nrOfDmrsSymbols  = NUM_DMRS_SYMBOLS;
    pdsch->dmrs.dmrsAddPos       = pdschCfg.dmrsDlCfgForPdschMapTypeA.addPos;
 
-   pdsch->pdschTimeAlloc.timeAlloc.startSymb = pdschStartSymbol; 
-   pdsch->pdschTimeAlloc.timeAlloc.numSymb = pdschNumSymbols;
+   pdsch->pdschTimeAlloc.startSymb = pdschStartSymbol; 
+   pdsch->pdschTimeAlloc.numSymb = pdschNumSymbols;
 
    pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
    pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
-   pdsch->pdschFreqAlloc.freqAlloc.startPrb = startPRB; /*Start PRB will be already known*/
-   pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, ueCb.ueCfg.dlModInfo.mcsIndex, pdschNumSymbols);
+   pdsch->pdschFreqAlloc.startPrb = startPRB; /*Start PRB will be already known*/
+   pdsch->pdschFreqAlloc.numPrb = schCalcNumPrb(tbSize, ueCb.ueCfg.dlModInfo.mcsIndex, pdschNumSymbols);
 
    /* Find total symbols occupied including DMRS */
    dmrsStartSymbol = findDmrsStartSymbol(pdsch->dmrs.dlDmrsSymbPos);
@@ -894,19 +888,19 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c
     * in that case only PDSCH symbols are marked as occupied */
    if(dmrsStartSymbol == MAX_SYMB_PER_SLOT)
    {
-      startSymbol = pdsch->pdschTimeAlloc.timeAlloc.startSymb;
-      numSymbol = pdsch->pdschTimeAlloc.timeAlloc.numSymb;
+      startSymbol = pdsch->pdschTimeAlloc.startSymb;
+      numSymbol = pdsch->pdschTimeAlloc.numSymb;
    }
    /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
    else
    {
       startSymbol = dmrsStartSymbol;
-      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.timeAlloc.numSymb;
+      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.numSymb;
    }
 
    /* Allocate the number of PRBs required for DL PDSCH */
    if((allocatePrbDl(cell, slotTime, startSymbol, numSymbol,\
-      &pdsch->pdschFreqAlloc.freqAlloc.startPrb, pdsch->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
+      &pdsch->pdschFreqAlloc.startPrb, pdsch->pdschFreqAlloc.numPrb)) != ROK)
    {
       DU_LOG("\nERROR  --> SCH : allocatePrbDl() failed for DL MSG");
       return RFAILED;
@@ -2095,13 +2089,13 @@ uint8_t schFillPagePdschCfg(SchCellCb *cell, PdschCfg *pagePdschCfg, SlotTimingI
 
    pagePdschCfg->pdschFreqAlloc.resourceAllocType   = 1; /* RAT type-1 RIV format */
    /* the RB numbering starts from coreset0, and PDSCH is always above SSB */
-   pagePdschCfg->pdschFreqAlloc.freqAlloc.startPrb  = startPrb;
-   pagePdschCfg->pdschFreqAlloc.freqAlloc.numPrb    = schCalcNumPrb(tbSize, mcs, NUM_PDSCH_SYMBOL);
+   pagePdschCfg->pdschFreqAlloc.startPrb  = startPrb;
+   pagePdschCfg->pdschFreqAlloc.numPrb    = schCalcNumPrb(tbSize, mcs, NUM_PDSCH_SYMBOL);
    pagePdschCfg->pdschFreqAlloc.vrbPrbMapping       = 0; /* non-interleaved */
    pagePdschCfg->pdschTimeAlloc.rowIndex            = 1;
    /* This is Intel's requirement. PDSCH should start after PDSCH DRMS symbol */
-   pagePdschCfg->pdschTimeAlloc.timeAlloc.startSymb = 3; /* spec-38.214, Table 5.1.2.1-1 */
-   pagePdschCfg->pdschTimeAlloc.timeAlloc.numSymb   = NUM_PDSCH_SYMBOL;
+   pagePdschCfg->pdschTimeAlloc.startSymb = 3; /* spec-38.214, Table 5.1.2.1-1 */
+   pagePdschCfg->pdschTimeAlloc.numSymb   = NUM_PDSCH_SYMBOL;
 
    /* Find total symbols occupied including DMRS */
    dmrsStartSymbol = findDmrsStartSymbol(pagePdschCfg->dmrs.dlDmrsSymbPos);
@@ -2109,19 +2103,19 @@ uint8_t schFillPagePdschCfg(SchCellCb *cell, PdschCfg *pagePdschCfg, SlotTimingI
     * in that case only PDSCH symbols are marked as occupied */
    if(dmrsStartSymbol == MAX_SYMB_PER_SLOT)
    {
-      startSymbol = pagePdschCfg->pdschTimeAlloc.timeAlloc.startSymb;
-      numSymbol = pagePdschCfg->pdschTimeAlloc.timeAlloc.numSymb;
+      startSymbol = pagePdschCfg->pdschTimeAlloc.startSymb;
+      numSymbol = pagePdschCfg->pdschTimeAlloc.numSymb;
    }
    /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
    else
    {
       startSymbol = dmrsStartSymbol;
-      numSymbol = pagePdschCfg->dmrs.nrOfDmrsSymbols + pagePdschCfg->pdschTimeAlloc.timeAlloc.numSymb;
+      numSymbol = pagePdschCfg->dmrs.nrOfDmrsSymbols + pagePdschCfg->pdschTimeAlloc.numSymb;
    }
 
    /* Allocate the number of PRBs required for DL PDSCH */
    if((allocatePrbDl(cell, slotTime, startSymbol, numSymbol,\
-               &pagePdschCfg->pdschFreqAlloc.freqAlloc.startPrb, pagePdschCfg->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
+               &pagePdschCfg->pdschFreqAlloc.startPrb, pagePdschCfg->pdschFreqAlloc.numPrb)) != ROK)
    {
       DU_LOG("\nERROR  --> SCH : allocatePrbDl() failed for DL MSG");
       return RFAILED;
@@ -2138,6 +2132,155 @@ uint8_t schFillPagePdschCfg(SchCellCb *cell, PdschCfg *pagePdschCfg, SlotTimingI
    return ROK;
 }
 
+/**
+ * @brief Handles retransmission for MSG3
+ *
+ * @details
+ *
+ *     Function : schMsg3RetxSchedulingForUe
+ *      
+ *      This function handles retransmission for MSG3
+ *           
+ *  @param[in]  SchRaCb *raCb, RA cb pointer
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb)
+{
+   bool      k2Found = false;
+   uint16_t             dciSlot = 0;
+   SlotTimingInfo       dciTime, msg3Time;
+   SchCellCb            *cell = NULLP;
+   SlotTimingInfo       currTime;
+   DciInfo  *dciInfo = NULLP;
+   cell = raCb->cell;
+   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);
+#ifdef NR_TDD
+   /* Consider this slot for sending DCI, only if it is a DL slot */
+   if(schGetSlotSymbFrmt(dciSlot, raCb->cell->slotFrmtBitMap) == DL_SLOT)
+#endif
+   {
+      /* If PDCCH is already scheduled on this slot, cannot schedule PDSCH for another UE here. */
+      if(cell->schDlSlotInfo[dciSlot]->pdcchUe != 0)
+         return false;
+
+      k2Found = schGetMsg3K2(cell, &raCb->msg3HqProc, dciTime.slot, &msg3Time, TRUE);
+
+      if (!k2Found)
+      {
+         return RFAILED;
+      }
+      SCH_ALLOC(dciInfo, sizeof(DciInfo));
+      if(!dciInfo)
+      {
+         DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciInfo alloc");
+         return RFAILED;
+      }
+      cell->schDlSlotInfo[msg3Time.slot]->ulGrant = dciInfo;
+      SCH_ALLOC(cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo, sizeof(SchPuschInfo));
+      memset(dciInfo,0,sizeof(DciInfo));
+      schFillUlDciForMsg3Retx(raCb, cell->schUlSlotInfo[msg3Time.slot]->schPuschInfo, dciInfo);
+   }   
+   raCb->retxMsg3HqProc = NULLP;
+   return ROK;
+}
+
+/**
+ * @brief Get K2 value for MSG3
+ *
+ * @details
+ *
+ *     Function : schGetMsg3K2
+ *      
+ *      This function gets K2 for MSG3
+ *           
+ *  @param[in]  SchCellCb *cell, Cell cb struc pointer
+ *  @param[in]  SchUlHqProcCb* msg3HqProc, msg3 harq proc pointer
+ *  @param[in]  uint16_t dlTime, DL time of scheduling
+ *  @param[in]  SlotTimingInfo *msg3Time, MSG3 timing info
+ *  @param[in]  bool isRetx, indicates MSG3 retransmission
+ *  @return  
+ *      -# true
+ *      -# false
+ **/
+bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, SlotTimingInfo *msg3Time, bool isRetx)
+{
+   bool      k2Found = false;
+   uint8_t   k2TblIdx = 0;
+   uint8_t   k2Index = 0;
+   uint8_t   k2 = 0;
+   uint8_t   numK2 = 0;
+   uint8_t   puschMu = 0;
+   uint8_t   msg3Delta = 0, msg3MinSchTime = 0;
+#ifdef NR_TDD
+   uint8_t   totalCfgSlot = 0;
+#endif
+   SchK2TimingInfoTbl   *msg3K2InfoTbl=NULLP;
+   SlotTimingInfo       currTime, msg3TempTime;
+   currTime = cell->slotInfo;
+   puschMu = cell->cellCfg.numerology;
+
+   if (isRetx)
+   {
+      if(!msg3HqProc)
+         return false;
+
+      numK2 = cell->cellCfg.schInitialUlBwp.k2InfoTbl.k2TimingInfo[dlTime].numK2;
+      msg3K2InfoTbl = &cell->cellCfg.schInitialUlBwp.msg3K2InfoTbl;
+      msg3MinSchTime = 0;
+      msg3Delta = 0;
+   }
+   else
+   {
+      numK2 = cell->cellCfg.schInitialUlBwp.msg3K2InfoTbl.k2TimingInfo[dlTime].numK2;
+      msg3K2InfoTbl = &cell->cellCfg.schInitialUlBwp.k2InfoTbl;
+      msg3MinSchTime = minMsg3SchTime[cell->cellCfg.numerology];
+      msg3Delta = puschDeltaTable[puschMu];
+   }
+
+   for(k2TblIdx = 0; k2TblIdx < numK2; k2TblIdx++)
+   {
+      k2Index = msg3K2InfoTbl->k2TimingInfo[dlTime].k2Indexes[k2TblIdx];
+
+      k2 = cell->cellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[k2Index].k2;
+      if (isRetx)
+      {
+         if ((msg3HqProc->strtSymbl != cell->cellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[k2Index].startSymbol) ||
+            (msg3HqProc->numSymbl != cell->cellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[k2Index].symbolLength))
+         {
+            continue;
+         }
+      }
+      /* Delta is added to the slot allocation for msg3 based on 38.214 section 6.1.2.1 */
+      k2 = k2 + msg3Delta;
+      if(k2 >= msg3MinSchTime)
+      {
+         ADD_DELTA_TO_TIME(currTime, msg3TempTime, k2, cell->numSlots);
+#ifdef NR_TDD
+         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)
+            continue;
+         k2Found = true;
+         break;
+      }
+   }
+   if (k2Found == true)
+   {
+      msg3Time->slot = msg3TempTime.slot;
+      msg3Time->sfn = msg3TempTime.sfn;
+      msg3Time->slot = msg3TempTime.slot;
+   }
+   return k2Found;
+}
+
 /**********************************************************************
   End of file
  **********************************************************************/