Fix in DL PRB allocation [Issue-ID: ODUHIGH-380]
[o-du/l2.git] / src / 5gnrsch / sch_common.c
index b36d054..8929c33 100644 (file)
@@ -47,6 +47,7 @@ SchCb schCb[SCH_MAX_INST];
 uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8];
 uint16_t numRbForPrachTable[MAX_RACH_NUM_RB_IDX][5];
 uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4];
+uint8_t puschDeltaTable[MAX_MU_PUSCH];
 
 SchMacUlSchInfoFunc schMacUlSchInfoOpts[] =
 {
@@ -60,70 +61,128 @@ SchMacUlSchInfoFunc schMacUlSchInfoOpts[] =
  *
  * @details
  *
- *     Function : schBroadcastAlloc
+ *     Function : schBroadcastSsbAlloc
  *     
- *     This function handles common scheduling for DL
+ *     This function handles common scheduling for SSB
  *     
  *  @param[in]  SchCellCb *cell, cell cb
  *  @param[in]  DlBrdcstAlloc *dlBrdcstAlloc, DL brdcst allocation
  *  @return  void
  **/
-uint8_t schBroadcastAlloc(SchCellCb *cell, DlBrdcstAlloc *dlBrdcstAlloc,
-      uint16_t slot)
+uint8_t schBroadcastSsbAlloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc)
 {
    /* schedule SSB */
-   uint8_t ssbStartPrb, ssbStartSymb, idx;
+   uint8_t ssbStartSymb, idx;
+   uint16_t ssbStartPrb;
    SchDlSlotInfo *schDlSlotInfo;
    SsbInfo ssbInfo;
 
-   schDlSlotInfo = cell->schDlSlotInfo[slot];
+   if(cell == NULL)
+   {
+      DU_LOG("\nERROR  -->  SCH: schBroadcastSsbAlloc() : Cell is NULL");
+      return RFAILED;
+   }
 
-   if(dlBrdcstAlloc->ssbTrans)
+   if(dlBrdcstAlloc == NULL)
    {
-      ssbStartPrb = cell->cellCfg.ssbSchCfg.ssbOffsetPointA; //+Kssb
-      ssbStartSymb = cell->ssbStartSymbArr[dlBrdcstAlloc->ssbIdxSupported-1]; /*since we are
-                                                                                supporting only 1 ssb beam */
+      DU_LOG("\nERROR  -->  SCH: schBroadcastSsbAlloc() : dlBrdcstAlloc is NULL");
+      return RFAILED;
+   }
 
-      /* Assign interface structure */
-      for(idx=0; idx<dlBrdcstAlloc->ssbIdxSupported; idx++)
-      {
-         ssbInfo.ssbIdx              = idx;
-         ssbInfo.fdAlloc.startPrb    = ssbStartPrb;
-         ssbInfo.fdAlloc.numPrb      = SCH_SSB_NUM_PRB;
-         ssbInfo.tdAlloc.startSymb   = ssbStartSymb;
-         ssbInfo.tdAlloc.numSymb     = SCH_SSB_NUM_SYMB;
-         dlBrdcstAlloc->ssbInfo[idx] = ssbInfo;
-         schDlSlotInfo->ssbInfo[idx] = ssbInfo;
-      }
+   schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot];
+   ssbStartPrb = cell->cellCfg.ssbSchCfg.ssbOffsetPointA; //+Kssb
+   ssbStartSymb = cell->ssbStartSymbArr[dlBrdcstAlloc->ssbIdxSupported-1]; /*since we are supporting only 1 ssb beam */
 
-      schDlSlotInfo->ssbPres = true;
-      schDlSlotInfo->ssbIdxSupported = dlBrdcstAlloc->ssbIdxSupported;
-      for(idx=ssbStartSymb; idx<ssbStartSymb+SCH_SSB_NUM_SYMB; idx++)
-      {
-         schDlSlotInfo->assignedPrb[idx] = ssbStartPrb + SCH_SSB_NUM_PRB + 1; /* +1 for kSsb */
-      }
+   /* Assign interface structure */
+   for(idx=0; idx<dlBrdcstAlloc->ssbIdxSupported; idx++)
+   {
+      ssbInfo.ssbIdx              = idx;
+      ssbInfo.fdAlloc.startPrb    = ssbStartPrb;
+      ssbInfo.fdAlloc.numPrb      = SCH_SSB_NUM_PRB;
+      ssbInfo.tdAlloc.startSymb   = ssbStartSymb;
+      ssbInfo.tdAlloc.numSymb     = SCH_SSB_NUM_SYMB;
+      dlBrdcstAlloc->ssbInfo[idx] = ssbInfo;
+      schDlSlotInfo->ssbInfo[idx] = ssbInfo;
    }
 
-   /* SIB1 allocation */
-   if(dlBrdcstAlloc->sib1Trans)
+   if((allocatePrbDl(cell, slotTime, ssbStartSymb, SCH_SSB_NUM_SYMB, &ssbInfo.fdAlloc.startPrb, ssbInfo.fdAlloc.numPrb)) != ROK)
    {
-      uint16_t tbSize         = 0;
-      uint8_t numPdschSymbols = 12; /* considering pdsch region from 2 to 13 */
-      uint8_t mcs             = 4;  /* MCS fixed to 4 */
-      uint8_t numSib1Prb      = 0;
-      schDlSlotInfo->sib1Pres = true;
-
-      tbSize = schCalcTbSize(cell->cellCfg.sib1SchCfg.sib1PduLen); /* send this value to the func in bytes when considering sib1 size */
-      numSib1Prb = schCalcNumPrb(tbSize,mcs,numPdschSymbols);
-      for(idx=0; idx<SCH_SYMBOL_PER_SLOT; idx++)
-      {
-         schDlSlotInfo->assignedPrb[idx] = ssbStartPrb + SCH_SSB_NUM_PRB + 1 + numSib1Prb; /* 10 PRBs for sib1 */
-      }
-      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;
+       DU_LOG("\nERROR  -->  SCH: PRB allocation failed for SSB in SFN:SLOT [%d : %d]", slotTime.sfn, slotTime.slot);
+       return RFAILED;
+   }
+
+
+   schDlSlotInfo->ssbPres = true;
+   schDlSlotInfo->ssbIdxSupported = dlBrdcstAlloc->ssbIdxSupported;
+   return ROK;
+}
+
+/**
+ * @brief common resource allocation for SIB1
+ *
+ * @details
+ *
+ *     Function : schBroadcastSib1Alloc
+ *     
+ *     This function handles common scheduling for SIB1
+ *     
+ *  @param[in]  SchCellCb *cell, cell cb
+ *  @param[in]  DlBrdcstAlloc *dlBrdcstAlloc, DL brdcst allocation
+ *  @return  void
+ **/
+uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc)
+{
+   uint8_t dmrsStartSymbol, startSymbol, numSymbol ;
+   DmrsInfo dmrs;
+   FreqDomainAlloc freqAlloc;
+   TimeDomainAlloc timeAlloc;
+   SchDlSlotInfo *schDlSlotInfo = NULLP;
+
+   if(cell == NULL)
+   {
+      DU_LOG("\nERROR  -->  SCH: schBroadcastSsbAlloc() : Cell is NULL");
+      return RFAILED;
+   }
+
+   if(dlBrdcstAlloc == NULL)
+   {
+      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;
+   schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot];
+
+   /* Find total symbols used including DMRS */
+   /* If there are no DRMS symbols, findDmrsStartSymbol() returns MAX_SYMB_PER_SLOT,
+    * in that case only PDSCH symbols are marked as occupied */
+   dmrsStartSymbol = findDmrsStartSymbol(dmrs.dlDmrsSymbPos);   
+   if(dmrsStartSymbol == MAX_SYMB_PER_SLOT)
+   {
+      startSymbol = timeAlloc.startSymb;
+      numSymbol = timeAlloc.numSymb;
    }
+   /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
+   else
+   {
+      startSymbol = dmrsStartSymbol;
+      numSymbol = dmrs.nrOfDmrsSymbols + timeAlloc.numSymb;
+   }
+
+   /* Allocate PRB */
+   if((allocatePrbDl(cell, slotTime, startSymbol, numSymbol, &freqAlloc.startPrb, freqAlloc.numPrb)) != ROK)
+   {
+       DU_LOG("\nERROR  -->  SCH: PRB allocation failed for SIB1 in SFN:Slot [%d : %d]", slotTime.sfn, slotTime.slot);
+       return RFAILED;
+   }
+
+   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;
 }
 
@@ -239,7 +298,7 @@ void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotTimingInfo
             dataType |= SCH_DATATYPE_PRACH;
             /* Considering first slot in the frame for PRACH */
             idx = 0;
-            schUlSlotInfo->assignedPrb[idx] = freqStart+numPrachRb;
+            //schUlSlotInfo->assignedPrb[idx] = freqStart+numPrachRb;
          }
          ulSchedInfo->dataType = dataType;
          /* prach info */
@@ -557,37 +616,45 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t schDlRsrcAllocMsg4(DlMsgAlloc *msg4Alloc, SchCellCb *cell, uint16_t slot, bool ssbPresent, bool sib1Present)
+uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo slotTime, DlMsgAlloc *msg4Alloc)
 {
    uint8_t coreset0Idx = 0;
-   uint8_t numRbs = 0;
    uint8_t firstSymbol = 0;
    uint8_t numSymbols = 0;
-   uint8_t offset = 0;
-   uint8_t offsetPointA;
-   uint8_t FreqDomainResource[6] = {0};
-   uint16_t tbSize = 0;
-   uint8_t numPdschSymbols = 11;            /* considering pdsch region from 3 to 13 */
    uint8_t mcs = 4;                         /* MCS fixed to 4 */
-   SchBwpDlCfg *initialBwp;
-   FreqDomainAlloc *sib1PdschFreqAlloc = NULL;
+   uint8_t dmrsStartSymbol = 0, startSymbol = 0, numSymbol = 0;
+   uint16_t tbSize = 0;
+   uint16_t numRbs;
+   SchBwpDlCfg *initialBwp = NULLP;
+   PdcchCfg *pdcch = NULLP;
+   PdschCfg *pdsch = NULLP;
+   BwpCfg *bwp = NULLP;
 
-   PdcchCfg *pdcch = &msg4Alloc->dlMsgPdcchCfg;
-   PdschCfg *pdsch = &msg4Alloc->dlMsgPdschCfg;
-   BwpCfg *bwp = &msg4Alloc->bwp;
+   if(cell == NULL)
+   {
+      DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() : Cell is NULL");
+      return RFAILED;
+   }
+
+   if(msg4Alloc == NULL)
+   {
+      DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() :  msg4Alloc is NULL");
+      return RFAILED;
+   }
 
+   pdcch = &msg4Alloc->dlMsgPdcchCfg;
+   pdsch = &msg4Alloc->dlMsgPdschCfg;
+   bwp = &msg4Alloc->bwp;
    initialBwp   = &cell->cellCfg.schInitialDlBwp;
-   offsetPointA = cell->cellCfg.ssbSchCfg.ssbOffsetPointA;
    coreset0Idx  = initialBwp->pdcchCommon.commonSearchSpace.coresetId;
 
    /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */
-   numRbs        = coresetIdxTable[coreset0Idx][1];
-   numSymbols    = coresetIdxTable[coreset0Idx][2];
-   offset        = coresetIdxTable[coreset0Idx][3];
+   numRbs     = coresetIdxTable[coreset0Idx][1];
+   numSymbols = coresetIdxTable[coreset0Idx][2];
 
    /* calculate time domain parameters */
    uint16_t mask = 0x2000;
-   for(firstSymbol=0; firstSymbol<14;firstSymbol++)
+   for(firstSymbol=0; firstSymbol<MAX_SYMB_PER_SLOT; firstSymbol++)
    {
       if(initialBwp->pdcchCommon.commonSearchSpace.monitoringSymbol & mask)
         break;
@@ -595,9 +662,6 @@ uint8_t schDlRsrcAllocMsg4(DlMsgAlloc *msg4Alloc, SchCellCb *cell, uint16_t slot
         mask = mask>>1;
    }
 
-   /* calculate the PRBs */
-   freqDomRscAllocType0(((offsetPointA-offset)/6), (numRbs/6), FreqDomainResource);
-
    /* fill BWP */
    bwp->freqAlloc.numPrb   = initialBwp->bwp.freqAlloc.numPrb;
    bwp->freqAlloc.startPrb = initialBwp->bwp.freqAlloc.startPrb;
@@ -607,7 +671,9 @@ uint8_t schDlRsrcAllocMsg4(DlMsgAlloc *msg4Alloc, SchCellCb *cell, uint16_t slot
    /* fill the PDCCH PDU */
    pdcch->coresetCfg.startSymbolIndex = firstSymbol;
    pdcch->coresetCfg.durationSymbols = numSymbols;
-   memcpy(pdcch->coresetCfg.freqDomainResource,FreqDomainResource,6);
+   memcpy(pdcch->coresetCfg.freqDomainResource, \
+      cell->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
+
    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 */
@@ -616,7 +682,7 @@ uint8_t schDlRsrcAllocMsg4(DlMsgAlloc *msg4Alloc, SchCellCb *cell, uint16_t slot
    pdcch->coresetCfg.shiftIndex = cell->cellCfg.phyCellId;
    pdcch->coresetCfg.precoderGranularity = 0; /* sameAsRegBundle */
    pdcch->numDlDci = 1;
-   pdcch->dci.rnti = cell->schDlSlotInfo[slot]->dlMsgInfo->crnti;
+   pdcch->dci.rnti = cell->schDlSlotInfo[slotTime.slot]->dlMsgInfo->crnti;
    pdcch->dci.scramblingId = cell->cellCfg.phyCellId;
    pdcch->dci.scramblingRnti = 0;
    pdcch->dci.cceIndex = 4; /* considering SIB1 is sent at cce 0-1-2-3 */
@@ -632,7 +698,7 @@ uint8_t schDlRsrcAllocMsg4(DlMsgAlloc *msg4Alloc, SchCellCb *cell, uint16_t slot
    /* fill the PDSCH PDU */
    uint8_t cwCount = 0;
    pdsch->pduBitmap = 0; /* PTRS and CBG params are excluded */
-   pdsch->rnti = cell->schDlSlotInfo[slot]->dlMsgInfo->crnti;
+   pdsch->rnti = cell->schDlSlotInfo[slotTime.slot]->dlMsgInfo->crnti;
    pdsch->pduIndex = 0;
    pdsch->numCodewords = 1;
    for(cwCount = 0; cwCount < pdsch->numCodewords; cwCount++)
@@ -658,24 +724,39 @@ uint8_t schDlRsrcAllocMsg4(DlMsgAlloc *msg4Alloc, SchCellCb *cell, uint16_t slot
    pdsch->dmrs.mappingType      = DMRS_MAP_TYPE_A; /* Setting to Type-A */
    pdsch->dmrs.nrOfDmrsSymbols  = NUM_DMRS_SYMBOLS;
    pdsch->dmrs.dmrsAddPos       = DMRS_ADDITIONAL_POS;
+
+   pdsch->pdschTimeAlloc.timeAlloc.startSymb = 3; /* spec-38.214, Table 5.1.2.1-1 */
+   pdsch->pdschTimeAlloc.timeAlloc.numSymb = NUM_PDSCH_SYMBOL;
+
    pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
-   /* The RB numbering starts from coreset0 */ 
-   pdsch->pdschFreqAlloc.freqAlloc.startPrb = PDSCH_START_RB;
-   if(ssbPresent)
+   pdsch->pdschFreqAlloc.freqAlloc.startPrb = MAX_NUM_RB;
+   pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, mcs, NUM_PDSCH_SYMBOL);
+   pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
+
+   /* Find total symbols occupied including DMRS */
+   dmrsStartSymbol = findDmrsStartSymbol(pdsch->dmrs.dlDmrsSymbPos);
+   /* If there are no DRMS symbols, findDmrsStartSymbol() returns MAX_SYMB_PER_SLOT,
+    * 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;
+   }
+   /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
+   else
    {
-      /* PDSCH is always above SSB */
-      pdsch->pdschFreqAlloc.freqAlloc.startPrb = offsetPointA + SCH_SSB_NUM_PRB + 1;
+      startSymbol = dmrsStartSymbol;
+      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.timeAlloc.numSymb;
    }
-   if(sib1Present)
+
+   /* Allocate the number of PRBs required for RAR PDSCH */
+   if((allocatePrbDl(cell, slotTime, startSymbol, numSymbol,\
+      &pdsch->pdschFreqAlloc.freqAlloc.startPrb, pdsch->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
    {
-      /* Must not overlap with SIB1 */
-      sib1PdschFreqAlloc = &cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc;
-      pdsch->pdschFreqAlloc.freqAlloc.startPrb = sib1PdschFreqAlloc->startPrb + sib1PdschFreqAlloc->numPrb + 1; 
+      DU_LOG("\nERROR  --> SCH : Resource allocation failed for MSG4");
+      return RFAILED;
    }
-   pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, mcs, numPdschSymbols);
-   pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
-   pdsch->pdschTimeAlloc.timeAlloc.startSymb = 3; /* spec-38.214, Table 5.1.2.1-1 */
-   pdsch->pdschTimeAlloc.timeAlloc.numSymb = numPdschSymbols;
+
    pdsch->beamPdschInfo.numPrgs = 1;
    pdsch->beamPdschInfo.prgSize = 1;
    pdsch->beamPdschInfo.digBfInterfaces = 0;
@@ -737,8 +818,8 @@ uint16_t schAllocPucchResource(SchCellCb *cell, uint16_t crnti, uint16_t slot)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t schDlRsrcAllocDlMsg(DlMsgAlloc *dlMsgAlloc, SchCellCb *cell, uint16_t crnti,
-      uint32_t *accumalatedSize, uint16_t slot)
+uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti,
+      uint32_t *accumalatedSize, DlMsgAlloc *dlMsgAlloc)
 {
    uint8_t ueIdx;
    uint16_t tbSize = 0;
@@ -748,6 +829,7 @@ uint8_t schDlRsrcAllocDlMsg(DlMsgAlloc *dlMsgAlloc, SchCellCb *cell, uint16_t cr
    SchUeCb ueCb;
    SchControlRsrcSet coreset1;
    SchPdschConfig pdschCfg;
+   uint8_t dmrsStartSymbol, startSymbol, numSymbol;
 
    pdcch = &dlMsgAlloc->dlMsgPdcchCfg;
    pdsch = &dlMsgAlloc->dlMsgPdschCfg;
@@ -822,13 +904,40 @@ uint8_t schDlRsrcAllocDlMsg(DlMsgAlloc *dlMsgAlloc, SchCellCb *cell, uint16_t cr
    pdsch->dmrs.mappingType      = DMRS_MAP_TYPE_A; /* Setting to Type-A */
    pdsch->dmrs.nrOfDmrsSymbols  = NUM_DMRS_SYMBOLS;
    pdsch->dmrs.dmrsAddPos       = pdschCfg.dmrsDlCfgForPdschMapTypeA.addPos;
+
+   pdsch->pdschTimeAlloc.timeAlloc.startSymb = pdschCfg.timeDomRsrcAllociList[0].startSymbol;
+   pdsch->pdschTimeAlloc.timeAlloc.numSymb = pdschCfg.timeDomRsrcAllociList[0].symbolLength;
+
+   pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
    pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
-   pdsch->pdschFreqAlloc.freqAlloc.startPrb = PDSCH_START_RB;
+   pdsch->pdschFreqAlloc.freqAlloc.startPrb = MAX_NUM_RB;
    pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, ueCb.ueCfg.dlModInfo.mcsIndex, \
                   pdschCfg.timeDomRsrcAllociList[0].symbolLength);
-   pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
-   pdsch->pdschTimeAlloc.timeAlloc.startSymb = pdschCfg.timeDomRsrcAllociList[0].startSymbol;
-   pdsch->pdschTimeAlloc.timeAlloc.numSymb = pdschCfg.timeDomRsrcAllociList[0].symbolLength;
+
+   /* Find total symbols occupied including DMRS */
+   dmrsStartSymbol = findDmrsStartSymbol(pdsch->dmrs.dlDmrsSymbPos);
+   /* If there are no DRMS symbols, findDmrsStartSymbol() returns MAX_SYMB_PER_SLOT,
+    * 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;
+   }
+   /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
+   else
+   {
+      startSymbol = dmrsStartSymbol;
+      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.timeAlloc.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)
+   {
+      DU_LOG("\nERROR  --> SCH : allocatePrbDl() failed for DL MSG");
+      return RFAILED;
+   }
+
    pdsch->beamPdschInfo.numPrgs = 1;
    pdsch->beamPdschInfo.prgSize = 1;
    pdsch->beamPdschInfo.digBfInterfaces = 0;
@@ -1092,7 +1201,7 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
                   }   
                   if(slotCfg == FLEXI_SLOT)
                   {
-                     for(checkSymbol = 0; checkSymbol<SCH_SYMBOL_PER_SLOT;checkSymbol++)
+                     for(checkSymbol = 0; checkSymbol< MAX_SYMB_PER_SLOT;checkSymbol++)
                      {
                         if(cell->cellCfg.tddCfg.slotCfg[tmpSlot][checkSymbol] == UL_SLOT)
                         {
@@ -1145,13 +1254,15 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
 *
 * ****************************************************************/
 void BuildK2InfoTableForFdd(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\
-SchK2TimingInfoTbl *k2InfoTbl)
+SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl)
 {
-   uint16_t slotIdx=0, k2Index=0, k2TmpVal=0;
+   uint16_t slotIdx=0, k2Index=0, k2TmpIdx=0, msg3K2TmpIdx=0;
 
    /* Initialization the structure and storing the total slot values. */
    memset(k2InfoTbl, 0, sizeof(SchK2TimingInfoTbl));
    k2InfoTbl->tblSize = cell->numSlots;
+   if(msg3K2InfoTbl)
+      msg3K2InfoTbl->tblSize = cell->numSlots;
    
    /* Checking all possible indexes for K2. */
    for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++)
@@ -1159,9 +1270,17 @@ SchK2TimingInfoTbl *k2InfoTbl)
       /* Storing K2 values. */
       for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); k2Index++)
       {
-         k2TmpVal= k2InfoTbl->k2TimingInfo[slotIdx].numK2;
-         k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[k2TmpVal] = k2Index;
+         k2TmpIdx= k2InfoTbl->k2TimingInfo[slotIdx].numK2;
+         k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[k2TmpIdx] = k2Index;
          k2InfoTbl->k2TimingInfo[slotIdx].numK2++;
+
+         /* Updating K2 values for MSG3 */
+         if(msg3K2InfoTbl)
+         {
+            msg3K2TmpIdx = msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2;
+            msg3K2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[msg3K2TmpIdx] = k2Index;
+            msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2++;
+         }
       }
    }
 }
@@ -1184,19 +1303,19 @@ SchK2TimingInfoTbl *k2InfoTbl)
  *
  * ****************************************************************/
 void BuildK2InfoTable(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\
-SchK2TimingInfoTbl *k2InfoTbl)
+SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl)
 {
 
 #ifdef NR_TDD
    bool dlSymbolPresent = false;
-   uint8_t slotIdx=0, k2Index=0, k2TmpVal=0, numK2 =0, currentSymbol =0;
+   uint8_t slotIdx=0, k2Index=0, k2Val=0, k2TmpVal=0, msg3K2TmpVal=0, msg3Delta=0, numK2 =0, currentSymbol =0;
    uint8_t startSymbol =0, endSymbol =0, checkSymbol=0, totalCfgSlot=0, slotCfg=0;
    SlotConfig currentSlot;
 #endif
 
    if(cell->cellCfg.dupMode == DUPLEX_MODE_FDD)
    {
-      BuildK2InfoTableForFdd(cell, timeDomRsrcAllocList, puschSymTblSize, k2InfoTbl);
+      BuildK2InfoTableForFdd(cell, timeDomRsrcAllocList, puschSymTblSize, msg3K2InfoTbl, k2InfoTbl);
    }
    else
    {
@@ -1205,10 +1324,12 @@ SchK2TimingInfoTbl *k2InfoTbl)
       /* Initialization the structure and storing the total slot values. */
       memset(k2InfoTbl, 0, sizeof(SchK2TimingInfoTbl));
       k2InfoTbl->tblSize = cell->numSlots;
+      if(msg3K2InfoTbl)
+         msg3K2InfoTbl->tblSize = cell->numSlots;
       totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod);
 
       /* Checking all possible indexes for K2. */
-      for(slotIdx = 0; slotIdx < k2InfoTbl->tblSize; slotIdx++)
+      for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++)
       {
          currentSlot = schGetSlotSymbFrmt(slotIdx % totalCfgSlot, cell->slotFrmtBitMap);
          
@@ -1220,22 +1341,22 @@ SchK2TimingInfoTbl *k2InfoTbl)
                /* Storing k2, startSymbol, endSymbol information for further processing.
                 * If k2 is absent then fill the default values given in spec 38.331
                 * PUSCH-TimeDomainResourceAllocationList field descriptions */
-               k2TmpVal = timeDomRsrcAllocList[k2Index].k2;
-               if(!k2TmpVal)
+               k2Val = timeDomRsrcAllocList[k2Index].k2;
+               if(!k2Val)
                {
                   switch(cell->cellCfg.ssbSchCfg.scsCommon)
                   {
                      case SCS_15KHZ:
-                        k2TmpVal = DEFAULT_K2_VALUE_FOR_SCS15;
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS15;
                         break;
                      case SCS_30KHZ:
-                        k2TmpVal = DEFAULT_K2_VALUE_FOR_SCS30;
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS30;
                         break;
                      case SCS_60KHZ:
-                        k2TmpVal = DEFAULT_K2_VALUE_FOR_SCS60;
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS60;
                         break;
                      case SCS_120KHZ:
-                        k2TmpVal = DEFAULT_K2_VALUE_FOR_SCS120;
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS120;
                         break;
                   }
                }
@@ -1243,33 +1364,69 @@ SchK2TimingInfoTbl *k2InfoTbl)
                /* Current slot + k2 should be either UL or FLEXI slot.
                 * If slot is FLEXI then check all the symbols of that slot,
                 * it should not contain any DL or FLEXI slot */
-               k2TmpVal = (slotIdx + k2TmpVal) % totalCfgSlot;
+               k2TmpVal = (slotIdx + k2Val) % totalCfgSlot;
                slotCfg = schGetSlotSymbFrmt(k2TmpVal, cell->slotFrmtBitMap);
-               if(slotCfg == DL_SLOT)
-               {
-                  continue;
-               }
-               if(slotCfg == FLEXI_SLOT)
+               if(slotCfg != DL_SLOT)
                {
-                  startSymbol =  timeDomRsrcAllocList[k2Index].startSymbol;
-                  endSymbol   =  startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength;
-                  dlSymbolPresent = false;
-                  for(checkSymbol= startSymbol; checkSymbol<endSymbol; checkSymbol++)
+                  if(slotCfg == FLEXI_SLOT)
                   {
-                     currentSymbol = cell->cellCfg.tddCfg.slotCfg[k2TmpVal][checkSymbol];
-                     if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT)
+                     startSymbol =  timeDomRsrcAllocList[k2Index].startSymbol;
+                     endSymbol   =  startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength;
+                     dlSymbolPresent = false;
+                     for(checkSymbol= startSymbol; checkSymbol<endSymbol; checkSymbol++)
                      {
-                        dlSymbolPresent = true;
-                        break;
+                        currentSymbol = cell->cellCfg.tddCfg.slotCfg[k2TmpVal][checkSymbol];
+                        if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT)
+                        {
+                           dlSymbolPresent = true;
+                           break;
+                        }
                      }
                   }
+                  /* Store all the values if all condition satisfies. */
+                  if(dlSymbolPresent != true || slotCfg == UL_SLOT)
+                  {
+                     numK2 = k2InfoTbl->k2TimingInfo[slotIdx].numK2;
+                     k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index;
+                     k2InfoTbl->k2TimingInfo[slotIdx].numK2++;
+                  }
                }
-               /* Store all the values if all condition satisfies. */
-               if(dlSymbolPresent != true || slotCfg == UL_SLOT)
+
+               if(msg3K2InfoTbl)
                {
-                  numK2 = k2InfoTbl->k2TimingInfo[slotIdx].numK2;
-                  k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index;
-                  k2InfoTbl->k2TimingInfo[slotIdx].numK2++;
+                   msg3Delta = puschDeltaTable[cell->cellCfg.numerology];
+
+                  /* Check for K2 for MSG3 */
+                  /* Current slot + k2 should be either UL or FLEXI slot.
+                   * If slot is FLEXI then check all the symbols of that slot,
+                   * it should not contain any DL or FLEXI slot */
+                  msg3K2TmpVal = (slotIdx + k2Val + msg3Delta) % totalCfgSlot;
+                  slotCfg = schGetSlotSymbFrmt(msg3K2TmpVal, cell->slotFrmtBitMap);
+                  if(slotCfg != DL_SLOT)
+                  {
+                     if(slotCfg == FLEXI_SLOT)
+                     {
+                        startSymbol =  timeDomRsrcAllocList[k2Index].startSymbol;
+                        endSymbol   =  startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength;
+                        dlSymbolPresent = false;
+                        for(checkSymbol= startSymbol; checkSymbol<endSymbol; checkSymbol++)
+                        {
+                           currentSymbol = cell->cellCfg.tddCfg.slotCfg[msg3K2TmpVal][checkSymbol];
+                           if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT)
+                           {
+                              dlSymbolPresent = true;
+                              break;
+                           }
+                        }
+                     }
+                     /* Store all the values if all condition satisfies. */
+                     if(dlSymbolPresent != true || slotCfg == UL_SLOT)
+                     {
+                        numK2 = msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2;
+                        msg3K2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index;
+                        msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2++;
+                     }
+                  }
                }
             }
          }