Merge "Fix in DL PRB allocation [Issue-ID: ODUHIGH-380]"
[o-du/l2.git] / src / 5gnrsch / sch_common.c
index f3c52fc..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)
    {
-      /* PDSCH is always above SSB */
-      pdsch->pdschFreqAlloc.freqAlloc.startPrb = offsetPointA + SCH_SSB_NUM_PRB + 1;
+      startSymbol = pdsch->pdschTimeAlloc.timeAlloc.startSymb;
+      numSymbol = pdsch->pdschTimeAlloc.timeAlloc.numSymb;
    }
-   if(sib1Present)
+   /* If DMRS symbol is found, mark DMRS and PDSCH symbols as occupied */
+   else
    {
-      /* Must not overlap with SIB1 */
-      sib1PdschFreqAlloc = &cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc;
-      pdsch->pdschFreqAlloc.freqAlloc.startPrb = sib1PdschFreqAlloc->startPrb + sib1PdschFreqAlloc->numPrb + 1; 
+      startSymbol = dmrsStartSymbol;
+      numSymbol = pdsch->dmrs.nrOfDmrsSymbols + pdsch->pdschTimeAlloc.timeAlloc.numSymb;
    }
-   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;
+
+   /* Allocate the number of PRBs required for RAR PDSCH */
+   if((allocatePrbDl(cell, slotTime, startSymbol, numSymbol,\
+      &pdsch->pdschFreqAlloc.freqAlloc.startPrb, pdsch->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
+   {
+      DU_LOG("\nERROR  --> SCH : Resource allocation failed for MSG4");
+      return RFAILED;
+   }
+
    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;
@@ -863,10 +972,15 @@ uint8_t schDlRsrcAllocDlMsg(DlMsgAlloc *dlMsgAlloc, SchCellCb *cell, uint16_t cr
 void BuildK0K1TableForFdd(SchCellCb *cell, SchK0K1TimingInfoTbl *k0K1InfoTbl, bool pdschCfgCmnPres,SchPdschCfgCmn pdschCmnCfg,\
 SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
 {
-   uint8_t k0TmpVal = 0, k1TmpVal =0, cfgIdx=0;
+   
+   uint8_t k1TmpVal =0, cfgIdx=0;
    uint8_t slotIdx=0, k0Index=0, k1Index=0, numK0=0, numK1=0, numTimeDomAlloc=0;
-   SchPdschCfgCmnTimeDomRsrcAlloc cmnTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
-   SchPdschTimeDomRsrcAlloc dedTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
+   
+   /* TODO Commented these below lines for resolving warnings. Presently these variable are not 
+    * required but this will require for harq processing */
+   // uint8_t k0TmpVal = 0; 
+   // SchPdschCfgCmnTimeDomRsrcAlloc cmnTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
+   // SchPdschTimeDomRsrcAlloc dedTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
 
    /* Initialization the structure and storing the total slot values. */
    memset(k0K1InfoTbl, 0, sizeof(SchK0K1TimingInfoTbl));
@@ -878,7 +992,8 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
       numTimeDomAlloc = pdschCmnCfg.numTimeDomAlloc;
       for(cfgIdx = 0; cfgIdx<numTimeDomAlloc; cfgIdx++)
       {
-         cmnTimeDomRsrcAllocList[cfgIdx] = pdschCmnCfg.timeDomRsrcAllocList[cfgIdx];
+         /*TODO uncomment this line during harq processing */
+         //cmnTimeDomRsrcAllocList[cfgIdx] = pdschCmnCfg.timeDomRsrcAllocList[cfgIdx];
       }
    }
    else
@@ -886,7 +1001,8 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
       numTimeDomAlloc = pdschDedCfg.numTimeDomRsrcAlloc;
       for(cfgIdx = 0; cfgIdx<numTimeDomAlloc; cfgIdx++)
       {
-         dedTimeDomRsrcAllocList[cfgIdx] = pdschDedCfg.timeDomRsrcAllociList[cfgIdx];
+         /*TODO uncomment this line during harq processing */
+         //dedTimeDomRsrcAllocList[cfgIdx] = pdschDedCfg.timeDomRsrcAllociList[cfgIdx];
       }
    }
    
@@ -899,6 +1015,8 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
        * As per 38.331 PDSCH-TimeDomainResourceAllocation field descriptions. */
       for(k0Index = 0; ((k0Index < numTimeDomAlloc) && (k0Index < MAX_NUM_K0_IDX));  k0Index++)
       {
+         /* TODO These if 0 we will remove during harq processing */
+#if 0
          if(pdschCfgCmnPres == true)
          {
             k0TmpVal = cmnTimeDomRsrcAllocList[k0Index].k0;
@@ -914,7 +1032,7 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
                k0TmpVal = DEFAULT_K0_VALUE;
             }
          }
-         
+#endif         
          /* Checking all the Ul Alloc values. If value is less than MIN_NUM_K1_IDX
           * then skip else continue storing the values. */
          numK1 = 0;
@@ -1083,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)
                         {
@@ -1117,6 +1235,206 @@ SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
 #endif
    }
 }
+
+/*******************************************************************
+*
+* @brief Fills K2 information table for FDD
+*
+* @details
+*
+*    Function : BuildK2InfoTableForFdd 
+*
+*    Functionality:
+*       Fills K2 information table for FDD
+*
+* @params[in] SchCellCb *cell,SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[],
+* uint16_t puschSymTblSize,SchK2TimingInfoTbl *k2InfoTbl
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+void BuildK2InfoTableForFdd(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\
+SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl)
+{
+   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++)
+   {
+      /* Storing K2 values. */
+      for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); 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++;
+         }
+      }
+   }
+}
+
+/*******************************************************************
+ *
+ * @brief Fills K2 information table
+ *
+ * @details
+ *
+ *    Function : BuildK2InfoTable 
+ *
+ *    Functionality:
+ *       Fills K2 information table
+ *
+ * @params[in] SchCellCb *cell,SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[],
+ * uint16_t puschSymTblSize, SchK2TimingInfoTbl *k2InfoTbl
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+void BuildK2InfoTable(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\
+SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl)
+{
+
+#ifdef NR_TDD
+   bool dlSymbolPresent = false;
+   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, msg3K2InfoTbl, k2InfoTbl);
+   }
+   else
+   {
+#ifdef NR_TDD
+
+      /* 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 < cell->numSlots; slotIdx++)
+      {
+         currentSlot = schGetSlotSymbFrmt(slotIdx % totalCfgSlot, cell->slotFrmtBitMap);
+         
+         /* If current slot is UL then skip because PDCCH is sent only in DL slots */
+         if(currentSlot != UL_SLOT)
+         {
+            for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); k2Index++)
+            {
+               /* 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 */
+               k2Val = timeDomRsrcAllocList[k2Index].k2;
+               if(!k2Val)
+               {
+                  switch(cell->cellCfg.ssbSchCfg.scsCommon)
+                  {
+                     case SCS_15KHZ:
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS15;
+                        break;
+                     case SCS_30KHZ:
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS30;
+                        break;
+                     case SCS_60KHZ:
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS60;
+                        break;
+                     case SCS_120KHZ:
+                        k2Val = DEFAULT_K2_VALUE_FOR_SCS120;
+                        break;
+                  }
+               }
+               
+               /* 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 + k2Val) % totalCfgSlot;
+               slotCfg = schGetSlotSymbFrmt(k2TmpVal, 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[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++;
+                  }
+               }
+
+               if(msg3K2InfoTbl)
+               {
+                   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++;
+                     }
+                  }
+               }
+            }
+         }
+      }
+#endif
+   }
+}
+
 /**********************************************************************
   End of file
  **********************************************************************/