[Epic-ID: ODUHIGH-402][Task-ID: ODUHIGH-418] Harq feature changes 34/8134/10
authorbarveankit <anbarve@radisys.com>
Sat, 30 Apr 2022 18:27:16 +0000 (23:57 +0530)
committerbarveankit <anbarve@radisys.com>
Thu, 9 Jun 2022 12:48:25 +0000 (18:18 +0530)
Signed-off-by: barveankit <anbarve@radisys.com>
Change-Id: I38674060ab7dcb876cd9b0d39723a6d887215d77
Signed-off-by: barveankit <anbarve@radisys.com>
26 files changed:
src/5gnrmac/mac.h
src/5gnrmac/mac_demux.c
src/5gnrmac/mac_harq_dl.c [new file with mode: 0644]
src/5gnrmac/mac_harq_dl.h [new file with mode: 0644]
src/5gnrmac/mac_msg_hdl.c
src/5gnrmac/mac_rach.c
src/5gnrmac/mac_slot_ind.c
src/5gnrmac/mac_ue_mgr.c
src/5gnrsch/sch.c
src/5gnrsch/sch.h
src/5gnrsch/sch_common.c
src/5gnrsch/sch_crc.c [new file with mode: 0644]
src/5gnrsch/sch_harq_dl.c [new file with mode: 0644]
src/5gnrsch/sch_harq_ul.c [new file with mode: 0644]
src/5gnrsch/sch_rach.c
src/5gnrsch/sch_rr.c [new file with mode: 0644]
src/5gnrsch/sch_slot_ind.c
src/5gnrsch/sch_ue_mgr.c
src/5gnrsch/sch_utils.c
src/5gnrsch/sch_utils.h
src/cm/cm_llist.c
src/cm/cm_llist.x
src/cm/common_def.h
src/cm/mac_sch_interface.c
src/cm/mac_sch_interface.h
src/phy_stub/phy_stub_msg_hdl.c

index fb78f80..6115c67 100644 (file)
@@ -90,6 +90,21 @@ typedef enum
    MAC_LC_STATE_ACTIVE
 }MacLcState;
 
+typedef struct dlTbInfo
+{
+   SlotTimingInfo  txTime;  
+   uint16_t        tbSize;
+   uint8_t         *tb;
+}DlTbInfo;
+
+/* DL HARQ Process Info */
+typedef struct dlHarqProcCb
+{
+   uint8_t     procId;                 /* HARQ Process Id */
+   uint8_t     numTb;                  /* Number of TB */
+   DlTbInfo    tbInfo[MAX_NUM_TB_PER_UE];  /* TB information */
+}DlHarqProcCb;
+
 typedef struct macDlSlot
 {
    DlSchedInfo dlInfo;
@@ -108,8 +123,7 @@ typedef struct macCbInfo
    uint8_t     msg3Pdu[6];  /* used as CRI value during muxing */
    uint8_t     *msg4Pdu;    /* storing DL-CCCH Ind Pdu */
    uint16_t    msg4PduLen;  /* storing DL-CCCH Ind Pdu Len */
-   uint8_t     *msg4TxPdu;  /* muxed Pdu used for re-transmission */
-   uint16_t    msg4TbSize;  /* size required for msg4TxPdu */
+   DlHarqProcCb msg4HqInfo; /* HARQ process info for msg 4 */
 }MacRaCbInfo;
 
 typedef struct macCe
@@ -138,12 +152,6 @@ typedef struct macDlData
    MacDlInfo  pduInfo[MAX_MAC_DL_PDU];
 }MacDlData;
 
-/* HARQ Process Info */
-typedef struct dlHarqProcCb
-{
-   uint8_t   procId;    /* HARQ Process Id */
-}DlHarqProcCb;
-
 /* DL HARQ entity */
 typedef struct dlHarqEnt
 {
index d244d57..1989a3b 100644 (file)
@@ -143,16 +143,6 @@ uint8_t unpackRxData(uint16_t cellId, SlotTimingInfo slotInfo, RxDataIndPdu *rxD
                pduLen -= length;
                rxPduIdx = rxPduIdx + length;
 
-               /* Delete RA cb once RRC setup complete received */
-               if(macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti == rxDataIndPdu->rnti)
-               {
-                  MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, \
-                        macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
-                  MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \
-                        macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize - TX_PAYLOAD_HDR_LEN);
-                  memset(&macCb.macCell[cellIdx]->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo));
-               }
-
                /* Send UL Data to RLC */
                ret = macProcUlData(cellId, rxDataIndPdu->rnti, slotInfo, lcId, length, pdu);
 
diff --git a/src/5gnrmac/mac_harq_dl.c b/src/5gnrmac/mac_harq_dl.c
new file mode 100644 (file)
index 0000000..8b3499f
--- /dev/null
@@ -0,0 +1,245 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+/* header include files (.h) */
+#include "common_def.h"
+#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "lwr_mac_upr_inf.h"
+#include "mac.h"
+#include "mac_utils.h"
+#include "mac_harq_dl.h"
+
+/**
+ * @brief Add HARQ process to UE's DL HARQ Entity
+ *
+ * @details
+ *
+ *     Function : addDlHqProcInUe
+ *
+ *      This functions adds HARQ process to UE's DL HARQ entity
+ *
+ *  @param[in]  Time of transmission on this HARQ process
+ *  @param[in]  UE Cb
+ *  @param[in]  DL Scheduling Information
+ *  @return
+ *      -# Void
+ **/
+void addDlHqProcInUe(SlotTimingInfo dlMsgTime, MacUeCb *ueCb, DlMsgSchInfo schedInfo)
+{
+   uint8_t       hqProcId = 0, tbIdx = 0, cwIdx = 0;
+   DlHarqEnt     *dlHqEnt = NULLP;
+   DlHarqProcCb  *hqProcCb = NULLP;
+
+   dlHqEnt = &ueCb->dlInfo.dlHarqEnt;  
+   hqProcId = schedInfo.dlMsgInfo.harqProcNum;
+   hqProcCb = &dlHqEnt->harqProcCb[hqProcId];
+
+   /* Check if harqProcId is already present in UE's DL HARQ Entity */
+   if(hqProcCb->procId == schedInfo.dlMsgInfo.harqProcNum)
+   {
+      /* Expected Behaviour:
+       * If a HARQ proc is already present in DL HARQ entity, it means this HARQ proc 
+       * is not free and SCH must not schedule on this process.
+       *
+       * Corner Case (occured if this line is hit):
+       * HARQ proc is present in DL HARQ entity but SCH has scheduled a new data transmission on it.
+       *
+       * Action:
+       * Free the process and schedule new data on it
+       */
+      for(tbIdx = 0; tbIdx < hqProcCb->numTb; tbIdx++)
+      {
+         MAC_FREE(hqProcCb->tbInfo[tbIdx].tb, hqProcCb->tbInfo[tbIdx].tbSize);
+      }
+      memset(hqProcCb, 0, sizeof(DlHarqProcCb));
+   }
+
+   /* Fill HARQ Proc Cb */
+   hqProcCb->procId = hqProcId;
+   for(cwIdx = 0; cwIdx < schedInfo.dlMsgPdschCfg.numCodewords; cwIdx++)
+   {
+      memcpy(&hqProcCb->tbInfo[hqProcCb->numTb].txTime, &dlMsgTime, sizeof(SlotTimingInfo));
+      hqProcCb->tbInfo[hqProcCb->numTb].tbSize = schedInfo.dlMsgPdschCfg.codeword[cwIdx].tbSize;
+      hqProcCb->numTb++;
+   }
+   return;
+}
+
+/**
+ * @brief Adds multiplexes TB to DL HARQ Process Info
+ *
+ * @details
+ *
+ *     Function : updateNewTbInDlHqProcCb
+ *     
+ *      This function adds multiplxed TB to DL HARQ process.
+ *      It will be used in case retransmission is required.
+ *           
+ *  @param[in]  Time on which TB will be transmitted
+ *  @param[in]  UE CB
+ *  @param[in]  Transport Block
+ *  @return  
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+uint8_t updateNewTbInDlHqProcCb(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint32_t tbSize, uint8_t *txPdu)
+{
+   uint8_t hqProcIdx = 0, tbIdx = 0;
+   DlHarqEnt  *dlHqEnt = NULLP;
+   DlTbInfo   *tbInfo = NULLP;
+
+   dlHqEnt = &ueCb->dlInfo.dlHarqEnt;
+
+   /* Search HARQ Proc Cb in DL HARQ Ent */
+   for(hqProcIdx = 0; hqProcIdx < MAX_NUM_HARQ_PROC; hqProcIdx++)
+   {
+      /* Search TB Info in a HARQ Proc Cb */
+      for(tbIdx =0; tbIdx < dlHqEnt->harqProcCb[hqProcIdx].numTb; tbIdx++)
+      {
+         /* Store MAC PDU if a harqProcCb->tbInfo is found with 
+          * a. same SFN/Slot on which incoming RLC DL Data is to be scheduled
+          * b. same TB size as MAC PDU size
+          */
+         if((dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx].txTime.sfn == slotInfo.sfn) &&
+               (dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx].txTime.slot == slotInfo.slot) &&
+               (dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx].tbSize == tbSize))
+         {
+            tbInfo = &dlHqEnt->harqProcCb[hqProcIdx].tbInfo[tbIdx];
+            MAC_ALLOC(tbInfo->tb, tbSize);
+            if(!tbInfo->tb)
+            {
+               DU_LOG("\nERROR  -->  MAC : Failed to allocate memory for TB in updateTbInDlHqProcCb");
+               return RFAILED;
+            }
+            memcpy(tbInfo->tb, txPdu, tbSize);
+
+            return ROK;
+         }
+      }
+   }
+   return RFAILED;
+}
+
+/**
+ * @brief Returns a transmission block from HARQ process Cb
+ *
+ * @details
+ *
+ *     Function : fetchTbfromDlHarqProc
+ *      
+ *      Returns a transmission block from HARQ process Cb
+ *           
+ *  @param[in]  Time of retransmission
+ *  @param[in]  UE CB
+ *  @param[in]  HARQ process Id
+ *  @param[in]  TB size
+ *  @return  
+ *      -# Pointer to TB
+ *      -# NULL
+ **/
+uint8_t* fetchTbfromDlHarqProc(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint8_t hqProcId, uint32_t tbSize)
+{
+   uint8_t    tbIdx = 0;
+   DlHarqEnt  *dlHqEnt = NULLP;
+   DlHarqProcCb  *hqProcCb = NULLP;
+
+   dlHqEnt = &ueCb->dlInfo.dlHarqEnt;
+   hqProcCb = &dlHqEnt->harqProcCb[hqProcId];
+
+   /* Search HARQ Proc Cb in DL HARQ Ent */
+   if(hqProcCb->procId == hqProcId)
+   {
+      /* Search TB Info in a HARQ Proc Cb */
+      for(tbIdx =0; tbIdx < hqProcCb->numTb; tbIdx++)
+      {
+         if(hqProcCb->tbInfo[tbIdx].tbSize == tbSize)
+         {
+            /* Update transmission time in TB Info */
+            memset(&hqProcCb->tbInfo[tbIdx].txTime, 0, sizeof(SlotTimingInfo));
+            memcpy(&hqProcCb->tbInfo[tbIdx].txTime, &slotInfo, sizeof(SlotTimingInfo));
+
+            return hqProcCb->tbInfo[tbIdx].tb;
+         }
+      }
+   }
+   return NULLP;
+}
+/**
+ * @brief Release Dl Harq process
+ *
+ * @details
+ *
+ *     Function : fetchTbfromDlHarqProc
+ *      
+ *      Release Dl Harq process
+ *           
+ *  @param[in]  Pst *pst, the post structure
+ *  @param[in]  SchRlsHqInfo *hqIndo, release hq info structure
+  *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+uint8_t MacSchReleaseDlHarqProc(Pst *pst, SchRlsHqInfo *hqInfo)
+{
+   uint8_t   hqProcId, tbIdx = 0;
+   uint16_t  cellIdx = 0, hqInfoIdx = 0, ueId = 0;
+   MacCellCb *cellCb = NULLP;
+   MacUeCb   *ueCb = NULLP;
+   DlHarqEnt     *dlHqEnt = NULLP;
+   DlHarqProcCb  *hqProcCb = NULLP;
+
+   GET_CELL_IDX(hqInfo->cellId, cellIdx);
+   cellCb = macCb.macCell[cellIdx];
+
+   for(hqInfoIdx = 0; hqInfoIdx < hqInfo->numUes; hqInfoIdx++)
+   {
+      GET_UE_ID(hqInfo->ueHqInfo[hqInfoIdx].crnti, ueId)
+      ueCb = &cellCb->ueCb[ueId -1];
+      dlHqEnt = &ueCb->dlInfo.dlHarqEnt;
+      hqProcId = hqInfo->ueHqInfo[hqInfoIdx].hqProcId;
+
+      /* First check if the HARQ process to be released belong to msg 4 */
+      if ((ueCb->raCb) && (ueCb->raCb->msg4HqInfo.procId == hqProcId))
+      {
+            deleteMacRaCb(cellIdx, ueCb);
+      }
+      else
+      {
+         /* Search harqProcId in UE's DL HARQ Entity */
+         hqProcCb = &dlHqEnt->harqProcCb[hqProcId];
+         if(hqProcCb->procId == hqProcId)
+         {
+            /* Free HARQ process */
+            for(tbIdx = 0; tbIdx < hqProcCb->numTb; tbIdx++)
+            {
+               MAC_FREE(hqProcCb->tbInfo[tbIdx].tb, hqProcCb->tbInfo[tbIdx].tbSize);
+            }
+            memset(hqProcCb, 0, sizeof(DlHarqProcCb));
+            hqProcCb->procId =  MAX_NUM_HARQ_PROC;
+         }
+      }
+   }
+   
+   MAC_FREE(hqInfo->ueHqInfo, (sizeof(SchUeHqInfo) * hqInfo->numUes)); 
+   MAC_FREE(hqInfo, sizeof(SchRlsHqInfo));
+   return ROK;
+}
+
+/**********************************************************************
+  End of file
+ **********************************************************************/
diff --git a/src/5gnrmac/mac_harq_dl.h b/src/5gnrmac/mac_harq_dl.h
new file mode 100644 (file)
index 0000000..721d8ef
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+
+void addDlHqProcInUe(SlotTimingInfo dlMsgTime, MacUeCb *ueCb, DlMsgSchInfo schedInfo);
+uint8_t updateNewTbInDlHqProcCb(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint32_t tbSize, uint8_t *txPdu);
+uint8_t* fetchTbfromDlHarqProc(SlotTimingInfo slotInfo, MacUeCb *ueCb, uint8_t hqProcId, uint32_t tbSize);
+
+/**********************************************************************
+  End of file
+ **********************************************************************/
+
index 16ade71..f167513 100644 (file)
@@ -32,6 +32,7 @@
 #include "lwr_mac_upr_inf.h"
 #include "mac.h"
 #include "mac_utils.h"
+#include "mac_harq_dl.h"
 
 /* This file contains message handling functionality for MAC */
 
@@ -69,6 +70,14 @@ MacSchSrUciIndFunc macSchSrUciIndOpts[]=
    packMacSchSrUciInd
 };
 
+/* Function pointer for sending HARQ Uci ind from MAC to SCH */
+MacSchHarqUciIndFunc macSchHarqUciIndOpts[]=
+{
+   packMacSchHarqUciInd,
+   MacSchHarqUciInd,
+   packMacSchHarqUciInd
+};
+
 /* Function pointer for sending Slice cfg  ind from MAC to SCH */
 MacSchSliceCfgReqFunc macSchSliceCfgReqOpts[]=
 {
@@ -194,7 +203,7 @@ uint8_t fapiMacRxDataInd(Pst *pst, RxDataInd *rxDataInd)
 
    for(pduIdx = 0; pduIdx < rxDataInd->numPdus; pduIdx++)
    {
-     
+
       GET_CELL_IDX(rxDataInd->cellId, cellIdx);
       GET_UE_ID(rxDataInd->pdus[pduIdx].rnti, ueId);
       
@@ -287,6 +296,10 @@ uint8_t MacProcRlcDlData(Pst* pstInfo, RlcData *dlData)
 
       currDlSlot->dlInfo.dlMsgAlloc[ueId-1]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPduLen = txPduLen;
       currDlSlot->dlInfo.dlMsgAlloc[ueId-1]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPdu = txPdu;
+      /* Add muxed TB to DL HARQ Proc CB. This will be used if retranmission of
+       * TB is requested in future. */
+      updateNewTbInDlHqProcCb(dlData->slotInfo, &macCb.macCell[cellIdx]->ueCb[ueId -1], \
+         currDlSlot->dlInfo.dlMsgAlloc[ueId-1]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[0].tbSize, txPdu);
    }
 
    for(lcIdx = 0; lcIdx < dlData->numLc; lcIdx++)
@@ -726,6 +739,51 @@ uint8_t macProcLongBsr(uint16_t cellId, uint16_t crnti,uint8_t numLcg,\
    return(*macSchBsrOpts[pst.selector])(&pst, &bsrInd);
 }
 
+/*******************************************************************
+ *
+ * @brief Builds and send HARQ UCI Indication to SCH
+ *
+ * @details
+ *
+ *    Function : buildAndSendHarqInd
+ *
+ *    Functionality:
+ *       Builds and send HARQ UCI Indication to SCH
+ *
+ * @params[in] harqInfo Pointer
+ *             crnti value
+ *             cell Index value
+ *             slot Ind Pointer
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t buildAndSendHarqInd(HarqInfoF0F1 *harqInfo, uint8_t crnti, uint16_t cellIdx, SlotTimingInfo *slotInd)
+{
+   uint16_t harqCounter=0;
+   Pst pst;
+   HarqUciIndInfo   harqUciInd;
+   memset(&pst, 0, sizeof(Pst));
+   memset(&harqUciInd, 0, sizeof(HarqUciIndInfo));
+
+   harqUciInd.cellId       = macCb.macCell[cellIdx]->cellId;
+   harqUciInd.crnti        = crnti;
+   harqUciInd.slotInd.sfn  = slotInd->sfn;
+   harqUciInd.slotInd.slot = slotInd->slot;
+   harqUciInd.numHarq = harqInfo->numHarq;
+   memset(harqUciInd.harqPayload, 0, MAX_SR_BITS_IN_BYTES);
+   for(harqCounter = 0; harqCounter < harqInfo->numHarq; harqCounter++)
+   {
+      harqUciInd.harqPayload[harqCounter] = harqInfo->harqValue[harqCounter];
+   }
+   
+   /* Fill Pst */
+   FILL_PST_MAC_TO_SCH(pst, EVENT_UCI_IND_TO_SCH);
+
+   return(*macSchHarqUciIndOpts[pst.selector])(&pst, &harqUciInd);
+}
+
+
 /*******************************************************************
  *
  * @brief Builds and send SR UCI Indication to SCH
@@ -785,7 +843,7 @@ uint8_t buildAndSendSrInd(UciInd *macUciInd, uint8_t crnti)
 uint8_t FapiMacUciInd(Pst *pst, UciInd *macUciInd)
 {
    uint8_t     pduIdx = 0, ret = ROK;
-   uint16_t    nPdus = 0, crnti = 0;
+   uint16_t    nPdus = 0, crnti = 0, cellIdx = 0;
 
    if(macUciInd)
    {
@@ -797,12 +855,19 @@ uint8_t FapiMacUciInd(Pst *pst, UciInd *macUciInd)
             case UCI_IND_PUSCH:
                break;
             case UCI_IND_PUCCH_F0F1:
+            {
+               {
+                  DU_LOG("\nDEBUG  -->  MAC : Received HARQ UCI Indication\n");
+                  GET_CELL_IDX(macUciInd->cellId, cellIdx);
+                  buildAndSendHarqInd(&macUciInd->pdus[pduIdx].uci.uciPucchF0F1.harqInfo, macUciInd->pdus[pduIdx].uci.uciPucchF0F1.crnti, cellIdx, &macUciInd->slotInd);
+               }
                if(macUciInd->pdus[pduIdx].uci.uciPucchF0F1.srInfo.srIndPres)
                {
                   DU_LOG("\nDEBUG  -->  MAC : Received SR UCI indication");
                   crnti = macUciInd->pdus[pduIdx].uci.uciPucchF0F1.crnti; 
                   ret = buildAndSendSrInd(macUciInd, crnti);
                }
+            }
                break;
             case UCI_IND_PUCCH_F2F3F4:
                break;
index 0100631..cc59d5c 100644 (file)
@@ -146,8 +146,13 @@ uint8_t createMacRaCb(MacCellCb *cellCb, RachIndInfo *rachIndInfo)
       GET_CRNTI(crnti, ueIdx+1);
 
       /* Store in raCb */
+      memset(&cellCb->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo));
       cellCb->macRaCb[ueIdx].cellId = rachIndInfo->cellId;
       cellCb->macRaCb[ueIdx].crnti  = crnti;
+
+     /* Initialize MSG4 HARQ PROC CB */
+     cellCb->macRaCb[ueIdx].msg4HqInfo.procId = MAX_NUM_HARQ_PROC;
+
    }
 
    /* Store in Rach Indication message to be sent to SCH */
index 321e350..fc32cc1 100644 (file)
@@ -28,6 +28,7 @@
 #include "lwr_mac.h"
 #include "lwr_mac_fsm.h"
 #include "mac_utils.h"
+#include "mac_harq_dl.h"
 
 /* function pointers for packing slot ind from mac to sch */
 MacSchSlotIndFunc macSchSlotIndOpts[] =
@@ -54,10 +55,14 @@ MacSchSlotIndFunc macSchSlotIndOpts[] =
  **/
 uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo)
 {
-   uint8_t   schInfoIdx = 0;
+   uint8_t   schInfoIdx = 0, cwIdx = 0;
    uint8_t   ueId = 0, ueIdx = 0;
    uint16_t  cellIdx = 0;
-   MacDlSlot *currDlSlot = NULLP;
+   uint8_t   *retxTb = NULLP, *txPdu = NULLP;
+   uint16_t  txPduLen = 0;
+   MacDlSlot      *currDlSlot = NULLP;
+   DlMsgSchInfo   schedInfo;
+   DlHarqProcCb   *hqProcCb = NULLP;
 
 #ifdef CALL_FLOW_DEBUG_LOG
    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_SCH_INFO\n");
@@ -100,16 +105,78 @@ uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo)
                {
                   GET_UE_ID(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.crnti, ueId);
                   ueIdx = ueId -1;
-                  macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize = \
-                     dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[0].tbSize;
+                  schedInfo = dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx];
+                  hqProcCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4HqInfo;
+
+                  if(!dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].isRetx)
+                  {
+                     /* First transmission of MSG4 */
+                     hqProcCb->procId = schedInfo.dlMsgInfo.harqProcNum;
+                     for(cwIdx = 0; cwIdx < schedInfo.dlMsgPdschCfg.numCodewords; cwIdx++)
+                     {
+                        memcpy(&hqProcCb->tbInfo[hqProcCb->numTb].txTime, &dlSchedInfo->schSlotValue.dlMsgTime, \
+                              sizeof(SlotTimingInfo));
+                        hqProcCb->tbInfo[hqProcCb->numTb].tbSize = schedInfo.dlMsgPdschCfg.codeword[cwIdx].tbSize;
+                        hqProcCb->numTb++;
+                     }
+                  }
+                  else
+                  {
+                     /* MSG4 retransmission */
+                     if(hqProcCb->procId == schedInfo.dlMsgInfo.harqProcNum)
+                     {
+                        memcpy(&hqProcCb->tbInfo[0].txTime, &dlSchedInfo->schSlotValue.dlMsgTime, \
+                                                     sizeof(SlotTimingInfo));
+                     }
+                  }
                }
                else
                {
                   memcpy(&currDlSlot->dlInfo.schSlotValue, &dlSchedInfo->schSlotValue, sizeof(SchSlotValue));
-                  /* Send LC schedule result to RLC */
-                  if((dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) ||
-                        (dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH))
-                     sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime, ueIdx, schInfoIdx);
+                  
+                  if(!dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].isRetx)
+                  {
+                     /* If new data transmission is scheduled, send schedule results to RLC */
+                     if((dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) ||
+                           (dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH))
+                     {
+                        sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime, ueIdx, schInfoIdx);
+
+                        /* Add HARQ Proc to DL HARQ Proc Entity in UE */
+                        addDlHqProcInUe(currDlSlot->dlInfo.schSlotValue.dlMsgTime, &macCb.macCell[cellIdx]->ueCb[ueIdx], \
+                           dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx]);
+                     }
+                  }
+                  else
+                  {
+                     /* For retransmission, fetch PDU to be retransmitted from DL HARQ entity and schedule on corresponding slot */
+                     
+                     /* As of now this loop will run only once for one TB. 
+                      * TODO : update handling of fetched TB appropriately when support for two TB is added 
+                      */
+                     for(cwIdx = 0; \
+                           cwIdx < dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.numCodewords;\
+                           cwIdx++)
+                     {
+                        /* Fetch TB to be retransmitted */
+                        txPduLen = dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[cwIdx].tbSize;
+                        retxTb = fetchTbfromDlHarqProc(currDlSlot->dlInfo.schSlotValue.dlMsgTime, \
+                              &macCb.macCell[cellIdx]->ueCb[ueIdx], \
+                              dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.harqProcNum, txPduLen);
+
+                        /* Store PDU in corresponding DL slot */
+                        MAC_ALLOC(txPdu, txPduLen);
+                        if(!txPdu)
+                        {
+                           DU_LOG("\nERROR  -->  MAC : Memory allocation failed in MacProcRlcDlData");
+                           return RFAILED;
+                        }   
+                        memcpy(txPdu, retxTb,  txPduLen);
+
+                        currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPduLen = txPduLen;
+                        currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPdu = txPdu;
+                     }
+                  }
                }
             }
          }
@@ -117,8 +184,7 @@ uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo)
 
       if(dlSchedInfo->ulGrant != NULLP)
       {
-         currDlSlot = &macCb.macCell[cellIdx]->\
-                      dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot];
+         currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot];
          currDlSlot->dlInfo.ulGrant = dlSchedInfo->ulGrant;
       }
    }
@@ -189,6 +255,7 @@ void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo)
    uint16_t  msg4TxPduLen;
    MacDlData msg4DlData;
    MacCeInfo  macCeData;
+   DlHarqProcCb *hqProcCb;
 
    GET_CELL_IDX(cellId, cellIdx);
 
@@ -204,23 +271,25 @@ void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo)
       return;
    }
 
+   hqProcCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4HqInfo;
+   msg4TxPduLen = hqProcCb->tbInfo[0].tbSize - TX_PAYLOAD_HDR_LEN;
+
    if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu != NULLP)
    {
       MAC_ALLOC(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
       if(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu != NULLP)
       {
-         msg4TxPduLen = macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize - TX_PAYLOAD_HDR_LEN;
-
          fillMsg4DlData(&msg4DlData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen, \
             macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu);
          fillMacCe(&macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg3Pdu);
+
          /* Forming Mux Pdu */
-         macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu = NULLP;
-         MAC_ALLOC(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen);
-         if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu != NULLP)
+         hqProcCb->tbInfo[0].tb = NULLP;
+         MAC_ALLOC(hqProcCb->tbInfo[0].tb, msg4TxPduLen);
+         if(hqProcCb->tbInfo[0].tb != NULLP)
          {
-            memset(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, 0, msg4TxPduLen);
-            macMuxPdu(&msg4DlData, &macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen);
+            memset(hqProcCb->tbInfo[0].tb, 0, msg4TxPduLen);
+            macMuxPdu(&msg4DlData, &macCeData, hqProcCb->tbInfo[0].tb, msg4TxPduLen);
          }
          else
          {
@@ -228,18 +297,22 @@ void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo)
          }
          /* Free memory allocated */
          MAC_FREE(msg4DlData.pduInfo[msg4DlData.numPdu-1].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
+         MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
+         macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu = NULLP;
+         macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen = 0;
          msg4DlData.numPdu--;
+
       }
    }
 
    /* storing msg4 Pdu in macDlSlot */
-   if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu)
+   if(hqProcCb->tbInfo[0].tb)
    {
       msg4SchInfo->dlMsgInfo.dlMsgPduLen = msg4TxPduLen;
       MAC_ALLOC(msg4SchInfo->dlMsgInfo.dlMsgPdu, msg4SchInfo->dlMsgInfo.dlMsgPduLen);
       if(msg4SchInfo->dlMsgInfo.dlMsgPdu != NULLP)
       {
-         memcpy(msg4SchInfo->dlMsgInfo.dlMsgPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \
+         memcpy(msg4SchInfo->dlMsgInfo.dlMsgPdu, hqProcCb->tbInfo[0].tb, \
                msg4SchInfo->dlMsgInfo.dlMsgPduLen);
       }
    }
index 4206acd..06953b4 100644 (file)
@@ -2008,6 +2008,7 @@ uint8_t fillMacUeCb(MacUeCb *ueCb, MacUeCfg *ueCfg, uint8_t cellIdx)
       DU_LOG("\nERROR  -->  MAC: Failed while filing MAC LC List at fillMacUeCb()");
    }
    ueCb->transmissionAction = ueCfg->transmissionAction;
+
    return ret;
 }
 
@@ -2059,27 +2060,21 @@ uint8_t updateMacRaCb(uint16_t cellIdx, MacUeCb *ueCb)
 
 void deleteMacRaCb(uint16_t cellIdx, MacUeCb *ueCb)
 {
-   uint8_t ueIdx;
+   uint8_t tbIdx;
+   MacRaCbInfo *raCb = ueCb->raCb;
+   DlHarqProcCb *hqProcCb;
 
-   for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+   if(raCb && (raCb->crnti == ueCb->crnti))
    {
-      if(macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti == ueCb->crnti)
+      hqProcCb = &raCb->msg4HqInfo;
+      MAC_FREE(raCb->msg4Pdu, raCb->msg4PduLen);
+      for(tbIdx = 0; tbIdx < raCb->msg4HqInfo.numTb; tbIdx++)
       {
-         if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu)
-        {
-          MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, \
-                    macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
-         }
-        if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu)
-        {
-            MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \
-                      macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize);
-         }
-        memset(&macCb.macCell[cellIdx]->macRaCb[ueIdx], 0, sizeof(MacRaCbInfo));
-         break;
+         MAC_FREE(raCb->msg4HqInfo.tbInfo[tbIdx].tb, \
+               raCb->msg4HqInfo.tbInfo[tbIdx].tbSize);
       }
+      memset(raCb, 0, sizeof(MacRaCbInfo));
    }
-                 
 }
 
 /*******************************************************************
@@ -2099,7 +2094,8 @@ void deleteMacRaCb(uint16_t cellIdx, MacUeCb *ueCb)
  * ****************************************************************/
 uint8_t createUeCb(uint8_t cellIdx, MacUeCb *ueCb, MacUeCfg *ueCfg)
 {
-   uint8_t ret =ROK;
+   uint8_t ret = ROK;
+   uint8_t hqProcIdx = 0;
 
    if((ueCb->ueId == ueCfg->ueId) && (ueCb->crnti == ueCfg->crnti)\
       &&(ueCb->state == UE_STATE_ACTIVE))
@@ -2118,6 +2114,12 @@ uint8_t createUeCb(uint8_t cellIdx, MacUeCb *ueCb, MacUeCfg *ueCfg)
       }
       else
       {
+         /* Initialize all DL HARQ PROC ID to MAX NUM OF HARQ PROC */
+         for(hqProcIdx = 0; hqProcIdx <  MAX_NUM_HARQ_PROC; hqProcIdx++)
+         {
+            ueCb->dlInfo.dlHarqEnt.harqProcCb[hqProcIdx].procId = MAX_NUM_HARQ_PROC;
+         }
+
          /* If UE has not requested for RACH yet, it means UE context is created for a
           * UE in handover */
          if(macCb.macCell[cellIdx]->macRaCb[ueCb->ueId-1].crnti == ueCb->crnti)
@@ -2166,7 +2168,6 @@ uint8_t modifyUeCb(uint8_t cellIdx, MacUeCb *ueCb, MacUeCfg *ueCfg)
       }
       else
       {
-         deleteMacRaCb(cellIdx, ueCb);
          return ROK;
       }
    }
index c3be113..3e485c4 100644 (file)
@@ -335,22 +335,12 @@ uint8_t MacSchRachInd(Pst *pst, RachIndInfo *rachInd)
  * ****************************************************************/
 uint8_t MacSchCrcInd(Pst *pst, CrcIndInfo *crcInd)
 {
+   Inst  inst = pst->dstInst-SCH_INST_START;
 #ifdef CALL_FLOW_DEBUG_LOG
    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_CRC_IND_TO_SCH\n");
 #endif
 
-   switch(crcInd->crcInd[0])
-   {
-      case CRC_FAILED:
-        DU_LOG("\nDEBUG  -->  SCH : Received CRC indication. CRC Status [FAILURE]");
-        break;
-      case CRC_PASSED:
-        DU_LOG("\nDEBUG  -->  SCH : Received CRC indication. CRC Status [PASS]");
-        break;
-      default:
-        DU_LOG("\nDEBUG  -->  SCH : Invalid CRC state %d", crcInd->crcInd[0]);
-        return RFAILED;
-   }
+   schProcessCrcInd(crcInd, inst);
    return ROK;
 }
 
@@ -909,6 +899,11 @@ uint8_t SchHdlCellCfgReq(Pst *pst, SchCellCfg *schCellCfg)
    cellCb->actvUeBitMap = 0;
    cellCb->boIndBitMap = 0;
 
+   cellCb->cellCfg.schHqCfg.maxDlDataHqTx = SCH_MAX_NUM_DL_HQ_TX;
+   cellCb->cellCfg.schHqCfg.maxMsg4HqTx = SCH_MAX_NUM_MSG4_TX;
+   cellCb->cellCfg.schHqCfg.maxUlDataHqTx = SCH_MAX_NUM_UL_HQ_TX;
+   cellCb->cellCfg.schRachCfg.maxMsg3Tx = SCH_MAX_NUM_MSG3_TX;
+
    /* Fill and send Cell config confirm */
    memset(&rspPst, 0, sizeof(Pst));
    FILL_PST_SCH_TO_MAC(rspPst, pst->dstInst);
@@ -945,13 +940,11 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo)
    bool isLcIdValid = false;
    SchUeCb *ueCb = NULLP;
    SchCellCb *cell = NULLP;
-   Inst  inst = pst->dstInst-SCH_INST_START;
-   CmLListCp *lcLL = NULLP;
+   Inst  inst = pst->dstInst-SCH_INST_START;   
 
 #ifdef CALL_FLOW_DEBUG_LOG
    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_DL_RLC_BO_INFO_TO_SCH\n");
-#endif
-
+#endif   
    DU_LOG("\nDEBUG  -->  SCH : Received RLC BO Status indication LCId [%d] BO [%d]", dlBoInfo->lcId, dlBoInfo->dataVolume);
    cell = schCb[inst].cells[inst];
 
@@ -982,28 +975,20 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo)
     *Thus clearing out the LC from the Lc priority list*/
    if(dlBoInfo->dataVolume == 0)
    {
-      /*Check the LC is Dedicated or default and accordingly LCList will
-       * be used*/
-      if(ueCb->dlInfo.dlLcCtxt[lcId].isDedicated)
-      {
-         lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
-      }
-      else
-      {
-         lcLL = &(ueCb->dlLcPrbEst.defLcList);
-      }
-      handleLcLList(lcLL, lcId, DELETE);
+      /* TODO : Check the LC is Dedicated or default and accordingly LCList
+       * will be used*/
       return ROK;
    }
 
    if(lcId == SRB0_LCID)
    {
       cell->raCb[ueId -1].msg4recvd = true;
-      cell->raCb[ueId -1].dlMsgPduLen = dlBoInfo->dataVolume;
-      
+      cell->raCb[ueId -1].dlMsgPduLen = dlBoInfo->dataVolume;      
    }
    else
    {
+      /* TODO : These part of changes will be corrected during DL scheduling as
+       * per K0 - K1 -K2 */
       SET_ONE_BIT(ueId, cell->boIndBitMap);
       if(ueCb->dlInfo.dlLcCtxt[lcId].lcId == lcId)
       {
@@ -1015,7 +1000,6 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo)
          return RFAILED;
       }
    }
-   
    /* Adding UE Id to list of pending UEs to be scheduled */
    addUeToBeScheduled(cell, ueId);
    return ROK;
@@ -1132,14 +1116,55 @@ uint8_t MacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd)
    }
    if(uciInd->numSrBits)
    {
-      ueCb->srRcvd = true;
-      
+      ueCb->srRcvd = true;      
       /* Adding UE Id to list of pending UEs to be scheduled */
       addUeToBeScheduled(cellCb, ueCb->ueId);
    }
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Processes HARQ UCI indication from MAC 
+ *
+ * @details
+ *
+ *    Function : MacSchHarqUciInd
+ *
+ *    Functionality:
+ *      Processes HARQ UCI indication from MAC
+ *
+ * @params[in] Post structure
+ *             UCI Indication
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t MacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd)
+{
+   Inst  inst = pst->dstInst-SCH_INST_START;
+   SchUeCb   *ueCb;
+   SchCellCb *cellCb = schCb[inst].cells[inst];
+
+#ifdef CALL_FLOW_DEBUG_LOG
+   DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_UCI_IND_TO_SCH\n");
+#endif
+
+   DU_LOG("\nDEBUG  -->  SCH : Received HARQ");
+
+   ueCb = schGetUeCb(cellCb, uciInd->crnti);
+
+   if(ueCb->state == SCH_UE_STATE_INACTIVE)
+   {
+      DU_LOG("\nERROR  -->  SCH : Crnti %d is inactive", uciInd->crnti);
+      return ROK;
+   }
+
+   schUpdateHarqFdbk(ueCb, uciInd->numHarq, uciInd->harqPayload, &uciInd->slotInd);
+
+   return ROK;
+}
+
 /*******************************************************************
  *
  * @brief Allocates requested PRBs for DL
index 3793761..4281ef8 100644 (file)
 #define PRB_BITMAP_IDX_LEN 64
 #define PRB_BITMAP_MAX_IDX ((MAX_NUM_RB + PRB_BITMAP_IDX_LEN-1) / PRB_BITMAP_IDX_LEN)
 
+#define SCH_MAX_NUM_UL_HQ_PROC 16
+#define SCH_MAX_NUM_DL_HQ_PROC 16
+#define SCH_MAX_NUM_MSG3_TX 2
+#define SCH_MAX_NUM_DL_HQ_TX 3
+#define SCH_MAX_NUM_UL_HQ_TX 3
+#define SCH_MAX_NUM_MSG4_TX 2
+#define HQ_ACK 0
+#define HQ_NACK 1
+#define HQ_DTX 2
+
+typedef struct schDlHqProcCb SchDlHqProcCb;
+typedef struct schUlHqEnt SchUlHqEnt;
+typedef struct schRaReq SchRaReq;
+typedef struct schDlHqEnt SchDlHqEnt;
 typedef struct schCellCb SchCellCb;
 typedef struct schUeCb SchUeCb;
 
@@ -78,6 +92,14 @@ typedef enum
    SCH_UE_HANDIN_IN_PROGRESS
 }SchUeState;
 
+typedef enum
+{
+   SCH_RA_STATE_MSG2_HANDLE,
+   SCH_RA_STATE_MSG3_PENDING,
+   SCH_RA_STATE_MSG4_PENDING,
+   SCH_RA_STATE_MSG4_DONE
+}SchRaState;
+
 typedef enum
 {
    SCH_LC_STATE_INACTIVE,
@@ -91,6 +113,124 @@ typedef enum
    WINDOW_EXPIRED
 }RaRspWindowStatus;
 
+typedef enum
+{
+   HQ_TB_ACKED=0,
+   HQ_TB_NACKED,
+   HQ_TB_WAITING
+}SchHqTbState;
+
+/*Following structures to keep record and estimations of PRB allocated for each
+ * LC taking into consideration the RRM policies*/
+typedef struct lcInfo
+{
+   uint8_t  lcId;     /*LCID for which BO are getting recorded*/
+   uint32_t reqBO;    /*Size of the BO requested/to be allocated for this LC*/
+   uint32_t allocBO;  /*TBS/BO Size which is actually allocated*/
+   uint8_t  allocPRB; /*PRB count which is allocated based on RRM policy/FreePRB*/
+}LcInfo;
+
+typedef struct schLcPrbEstimate
+{
+   /* TODO: For Multiple RRMPolicies, Make DedicatedLcInfo as array/Double Pointer 
+    * and have separate DedLCInfo for each RRMPolcyMemberList*/
+   /* Dedicated LC List will be allocated, if any available*/
+   CmLListCp dedLcList;        /*Contain LCInfo per RRMPolicy*/
+   CmLListCp defLcList; /*Linklist of LC assoc with Default S-NSSAI(s)*/
+   /* SharedPRB number can be used by any LC.
+    * Need to calculate in every Slot based on PRB availability*/
+   uint16_t sharedNumPrb;
+}SchLcPrbEstimate;
+typedef struct schUlHqTbCb
+{
+   uint32_t               tbSzReq;
+   uint32_t               tbSzAllc;
+   uint8_t                ndi;
+   uint8_t                rv;
+   uint8_t                rvIdx;
+   uint8_t                qamOrder;
+   SchMcsTable            mcsTable;
+   uint8_t                iMcs;
+   uint8_t                iMcsInDci;
+   uint8_t                numLyrs;
+   uint8_t                txCntr;
+   SchHqTbState           state;
+   uint8_t                cntrRetxAllocFail;
+   uint8_t                statsBitmap;
+}SchUlHqTbCb;
+
+typedef struct schDlHqTbCb
+{
+   uint8_t                tbIdx;
+   Bool                   isEnabled;
+   uint32_t               tbSzReq;
+   uint8_t                txCntr;
+   uint8_t                ndi;
+   uint8_t                rv;
+   uint8_t                rvIdx;
+   uint8_t                iMcs;
+   uint8_t                iMcsInDci;
+   uint8_t                numLyrs;
+   SchHqTbState           state;
+   uint8_t                isAckNackDtx;
+   uint8_t                cntrRetxAllocFail;
+   //InfUeTbInfo          tbCompInfo;
+   uint8_t                statsBitmap;
+}SchDlHqTbCb;
+
+typedef struct schUlHqProcCb
+{
+   uint8_t           procId;       /*!< HARQ Process ID */
+   SchUlHqEnt        *hqEnt;
+   uint8_t           maxHqTxPerHqP;
+   SchUlHqTbCb       tbInfo;
+   CmLList           ulHqEntLnk;
+   CmLList           ulSlotLnk;
+   uint8_t           strtSymbl;
+   uint8_t           numSymbl;
+   SchLcPrbEstimate  ulLcPrbEst; /*UL PRB Alloc Estimate among different LC*/
+   CmLList           ulHqProcLink;
+   uint8_t           puschResType; /* Resource allocation type */
+   uint16_t          puschStartPrb;
+   uint16_t          puschNumPrb;
+   uint8_t           dmrsMappingType;
+   uint8_t           nrOfDmrsSymbols;
+   uint8_t           dmrsAddPos;
+}SchUlHqProcCb;
+
+struct schDlHqProcCb
+{
+   uint8_t           procId;       /*!< HARQ Process ID */
+   SchDlHqEnt        *hqEnt;
+   uint8_t           maxHqTxPerHqP;
+   CmLList           dlHqEntLnk;
+   CmLList           ulSlotLnk;
+   SchDlHqTbCb       tbInfo[2];
+   uint8_t           k1;
+   SchLcPrbEstimate  dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/
+   CmLList           dlHqProcLink;
+};
+struct schUlHqEnt
+{
+   SchCellCb      *cell;     /*!< Contains the pointer to cell*/
+   SchUeCb        *ue;       /*!< Contains the pointer to ue*/
+   CmLListCp      free;      /*!< List of free HARQ processes */
+   CmLListCp      inUse;     /*!< List of in-use HARQ processes */
+   uint8_t        maxHqTx;   /*!< Maximum number of harq re-transmissions */
+   uint8_t        numHqPrcs; /*!< Number of HARQ Processes */
+   SchUlHqProcCb  procs[SCH_MAX_NUM_UL_HQ_PROC]; /*!< Uplink harq process info */
+};
+struct schDlHqEnt
+{
+   SchCellCb      *cell;     /*!< Contains the pointer to cell */
+   SchUeCb        *ue;       /*!< Contains the pointer to UE */
+   CmLListCp      free;      /*!< List of free HARQ processes */
+   CmLListCp      inUse;     /*!< List of in-use HARQ processes */
+   uint8_t        maxHqTx;   /*!< Maximum number of harq transmissions */
+   uint8_t        numHqPrcs; /*!< Number of HARQ Processes */
+   SchDlHqProcCb  procs[SCH_MAX_NUM_DL_HQ_PROC];/*!< Downlink harq processes */
+};
+
 /**
  * @brief
  * Structure holding LTE MAC's General Configuration information.
@@ -144,9 +284,15 @@ typedef struct schDlSlotInfo
 
 typedef struct schRaCb
 {
+   uint8_t   ueId;
    bool      msg4recvd;
    uint16_t  tcrnti;
    uint16_t  dlMsgPduLen;
+   SchUlHqProcCb msg3HqProc;
+   SchUlHqProcCb *retxMsg3HqProc;
+   SchRaState raState;
+   SchCellCb *cell;
+   SchRaReq  *raReq;
 }SchRaCb;
 
 /**
@@ -184,6 +330,7 @@ typedef struct schLcCtxt
    uint16_t   pduSessionId; /*Pdu Session Id*/
    Snssai  *snssai;      /*S-NSSAI assoc with LCID*/
    bool isDedicated;     /*Flag containing Dedicated S-NSSAI or not*/
+   uint16_t rsvdDedicatedPRB;
 }SchDlLcCtxt;
 
 typedef struct schDlCb
@@ -194,7 +341,7 @@ typedef struct schDlCb
 typedef struct schUlLcCtxt
 {
    SchLcState  lcState;
-   uint8_t lcId;       
+   uint8_t lcId;
    uint8_t priority;
    uint8_t lcGroup;
    uint8_t schReqId;
@@ -203,6 +350,7 @@ typedef struct schUlLcCtxt
    uint16_t   pduSessionId; /*Pdu Session Id*/
    Snssai  *snssai;      /*S-NSSAI assoc with LCID*/
    bool isDedicated;     /*Flag containing Dedicated S-NSSAI or not*/
+   uint16_t rsvdDedicatedPRB;
 }SchUlLcCtxt;
 
 typedef struct schUlCb
@@ -227,35 +375,15 @@ typedef struct schUeCfgCb
    SchDataTransmission dataTransmissionAction;
 }SchUeCfgCb;
 
-/*Following structures to keep record and estimations of PRB allocated for each
- * LC taking into consideration the RRM policies*/
-typedef struct lcInfo
+typedef struct schHqDlMap
 {
-   uint8_t  lcId;     /*LCID for which BO are getting recorded*/
-   uint32_t reqBO;    /*Size of the BO requested/to be allocated for this LC*/
-   uint32_t allocBO;  /*TBS/BO Size which is actually allocated*/
-   uint8_t  allocPRB; /*PRB count which is allocated based on RRM policy/FreePRB*/
-}LcInfo;
+   CmLListCp hqList;
+}SchHqDlMap;
 
-typedef struct dedicatedLCInfo
+typedef struct schHqUlMap
 {
-   CmLListCp dedLcList;            /*Linklist of LC assoc with RRMPolicyMemberList*/
-   uint16_t     rsvdDedicatedPRB; /*Number of PRB reserved for this Dedicated S-NSSAI*/
-}DedicatedLCInfo;
-
-typedef struct schLcPrbEstimate
-{
-   /* TODO: For Multiple RRMPolicies, Make DedicatedLcInfo as array/Double Pointer 
-    * and have separate DedLCInfo for each RRMPolcyMemberList*/
-   /* Dedicated LC List will be allocated, if any available*/
-   DedicatedLCInfo *dedLcInfo; /*Contain LCInfo per RRMPolicy*/
-
-   CmLListCp defLcList; /*Linklist of LC assoc with Default S-NSSAI(s)*/
-
-   /* SharedPRB number can be used by any LC.
-    * Need to calculate in every Slot based on PRB availability*/
-   uint16_t sharedNumPrb;  
-}SchLcPrbEstimate;
+   CmLListCp hqList;
+}SchHqUlMap;
 
 /**
  * @brief
@@ -274,8 +402,14 @@ typedef struct schUeCb
    BsrInfo    bsrInfo[MAX_NUM_LOGICAL_CHANNEL_GROUPS];
    SchUlCb    ulInfo;
    SchDlCb    dlInfo;
-   SchLcPrbEstimate dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/
-   SchLcPrbEstimate ulLcPrbEst; /*UL PRB Alloc Estimate among different LC*/
+   SchUlHqEnt ulHqEnt;
+   SchDlHqEnt dlHqEnt;
+   SchDlHqProcCb *msg4Proc;
+   SchDlHqProcCb *retxMsg4HqProc;
+   SchHqDlMap   **hqDlmap;
+   SchHqUlMap   **hqUlmap;
+   CmLListCp  ulRetxHqList;
+   CmLListCp  dlRetxHqList;
 }SchUeCb;
 
 /**
@@ -364,7 +498,7 @@ typedef struct schCb
    SchGenCb      genCfg;                /*!< General Config info */
    CmTqCp        tmrTqCp;               /*!< Timer Task Queue Cntrl Point */
    CmTqType      tmrTq[SCH_TQ_SIZE];    /*!< Timer Task Queue */
-   SchCellCb     *cells[MAX_NUM_CELL];  /* Array to store cellCb ptr */ 
+   SchCellCb     *cells[MAX_NUM_CELL];  /* Array to store cellCb ptr */
    SchSliceCfg   sliceCfg;
 }SchCb;
 
@@ -388,6 +522,7 @@ uint8_t addUeToBeScheduled(SchCellCb *cell, uint8_t ueId);
 /* Incoming message handler function declarations */
 uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst inst);
 uint8_t schProcessRachInd(RachIndInfo *rachInd, Inst schInst);
+uint8_t schProcessCrcInd(CrcIndInfo *crcInd, Inst schInst);
 
 /* DL scheduling related function declarations */
 PduTxOccsaion schCheckSsbOcc(SchCellCb *cell, SlotTimingInfo slotTime);
@@ -395,32 +530,32 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime);
 uint8_t schBroadcastSsbAlloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc);
 uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc);
 bool schProcessRaReq(Inst schInst, SchCellCb *cellCb, SlotTimingInfo currTime, uint8_t ueId);
-bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId);
+uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId,bool isRetxMsg4, SchDlHqProcCb **hqP);
 uint8_t schFillRar(SchCellCb *cell, SlotTimingInfo rarTime, uint16_t ueId, RarAlloc *rarAlloc, uint8_t k0Index);
 uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti,
-uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, uint8_t pdschNumSymbols);
+uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, uint8_t pdschNumSymbols,bool isRetx, SchDlHqProcCb* hqP);
 uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueId, DlMsgAlloc *msg4Alloc,\
-uint8_t pdschStartSymbol, uint8_t pdschNumSymbols);
+uint8_t pdschStartSymbol, uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP);
 uint8_t allocatePrbDl(SchCellCb *cell, SlotTimingInfo slotTime, uint8_t startSymbol, uint8_t symbolLength, \
    uint16_t *startPrb, uint16_t numPrb);
-void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti);
+void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti, bool isRetx, SchDlHqProcCb* hqP);
 bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg, uint8_t *pdschStartSymbol,\
-uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime,  SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime);
-
+uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime,  SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP);
+RaRspWindowStatus isInRaRspWindow(SchRaReq *raReq, SlotTimingInfo frameToCheck, uint16_t numSlotsPerSystemFrame);
 /* UL scheduling related function declarations */
 uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst);
 bool schCheckPrachOcc(SchCellCb *cell, SlotTimingInfo prachOccasionTimingInfo);
 uint8_t schCalcPrachNumRb(SchCellCb *cell);
 void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotTimingInfo prachOccasionTimingInfo);
-uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti);
-uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo);
-uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbsSize, \
-                           uint8_t startSymb, uint8_t symbLen, uint16_t startPrb);
+uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti,SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP);
+uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, bool isRetx, SchUlHqProcCb *hqP);
+uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize,
+                            uint8_t startSymb, uint8_t symbLen, uint16_t startPrb, bool isRetx, SchUlHqProcCb *hqP);
 uint8_t allocatePrbUl(SchCellCb *cell, SlotTimingInfo slotTime, uint8_t startSymbol, uint8_t symbolLength, \
    uint16_t *startPrb, uint16_t numPrb);
-bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId);
-bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
-                             uint16_t *startPrb, uint32_t *totTBS);
+bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetx, SchUlHqProcCb **hqP);
+uint8_t schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
+                             uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP);
 
 /*Generic Functions*/
 void updateGrantSizeForBoRpt(CmLListCp *lcLL, DlMsgAlloc *dlMsgAlloc, BsrInfo *bsrInfo, uint32_t *accumalatedBOSize);
@@ -436,7 +571,28 @@ void schCfgPdcchMonOccOfPO(SchCellCb *cell);
 void schIncrSlot(SlotTimingInfo *timingInfo, uint8_t incr, uint16_t numSlotsPerRF);
 uint8_t schFillPagePdschCfg(SchCellCb *cell, PdschCfg *pagePdschCfg, SlotTimingInfo slotTime, \
                              uint16_t tbSize, uint8_t mcs, uint16_t startPrb);
-
+/*DL HARQ Functions*/
+void schDlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb);
+void schMsg4FeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk);
+void schDlHqFeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk1, uint8_t fdbk2);
+uint8_t schDlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqProcCb **hqP);
+void schDlReleaseHqProcess(SchDlHqProcCb *hqP);
+
+/*UL HARQ Functions*/
+void schUlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb);
+uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb);
+void schUlHqProcessNack(SchUlHqProcCb *hqP);
+void schUlHqProcessAck(SchUlHqProcCb *hqP);
+uint8_t schUlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqProcCb **hqP);
+void schUlReleaseHqProcess(SchUlHqProcCb *hqP, Bool togNdi);
+
+/* UE Manager HARQ Fun*/
+void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload,SlotTimingInfo *slotInd);
+
+/* Round Robbin Scheduler funtions*/
+uint8_t schFillUlDciForMsg3Retx(SchRaCb *raCb, SchPuschInfo *puschInfo, DciInfo *dciInfo);
+bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, SlotTimingInfo *msg3Time, bool isRetx);
+void schMsg4Complete(SchUeCb *ueCb);
 /**********************************************************************
   End of file
  **********************************************************************/
index 23b648b..a16cda5 100644 (file)
@@ -389,6 +389,7 @@ uint8_t fillUlSchedPucchDedicatedCfg(SchCellCb *cell, SchPucchCfg *pucchDedCfg,\
          ulSchedPucch->srFlag  = true;
          ulSchedPucch->uciFlag = true;
       }
+      ulSchedPucch->harqFlag  = true;//check how to enable?
    }
    return ret;
 }
@@ -451,10 +452,6 @@ uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst, SlotTiming
          schPucchInfo->uciFlag = true;
       }
    }
-   /* set HARQ flag to true */
-   schPucchInfo->harqFlag = true;
-   schPucchInfo->numHarqBits = 1; /* 1 bit for HARQ */
-
    return ROK;
 }
 
@@ -535,13 +532,16 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
  *    Functionality:
  *       Fills pdcch and pdsch info for msg4
  *
- * @params[in] 
+ * @params[in] SchCellCb *cell, SlotTimingInfo msg4Time
+ * @params[in] uint8_t ueId, DlMsgAlloc *dlMsgAlloc
+ * @params[in] uint8_t pdschStartSymbol, uint8_t pdschNumSymbols
+ * @params[in] bool isRetx, SchDlHqProcCb *hqP
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
 uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo msg4Time, uint8_t ueId, DlMsgAlloc *dlMsgAlloc,\
-uint8_t pdschStartSymbol, uint8_t pdschNumSymbols)
+                           uint8_t pdschStartSymbol, uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP)
 {
    uint8_t coreset0Idx = 0;
    uint8_t firstSymbol = 0;
@@ -575,7 +575,7 @@ uint8_t pdschStartSymbol, uint8_t pdschNumSymbols)
    bwp = &msg4Alloc->bwp;
    coreset0Idx  = initialBwp->pdcchCommon.commonSearchSpace.coresetId;
 
-   fillDlMsgInfo(&msg4Alloc->dlMsgInfo, cell->raCb[ueId-1].tcrnti);
+   fillDlMsgInfo(&msg4Alloc->dlMsgInfo, cell->raCb[ueId-1].tcrnti, isRetx, hqP);
    msg4Alloc->dlMsgInfo.dlMsgPduLen = cell->raCb[ueId-1].dlMsgPduLen;
 
    /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */
@@ -638,8 +638,17 @@ uint8_t pdschStartSymbol, uint8_t pdschNumSymbols)
       pdsch->codeword[cwCount].qamModOrder = 2;
       pdsch->codeword[cwCount].mcsIndex = mcs; /* mcs configured to 4 */
       pdsch->codeword[cwCount].mcsTable = 0; /* notqam256 */
-      pdsch->codeword[cwCount].rvIndex = 0;
-      tbSize = schCalcTbSize(msg4Alloc->dlMsgInfo.dlMsgPduLen + TX_PAYLOAD_HDR_LEN); /* MSG4 size + FAPI header size*/
+      if(isRetx != TRUE)
+      {
+         tbSize = schCalcTbSize(msg4Alloc->dlMsgInfo.dlMsgPduLen + TX_PAYLOAD_HDR_LEN); /* MSG4 size + FAPI header size*/
+         hqP->tbInfo[cwCount].tbSzReq = tbSize;
+         pdsch->codeword[cwCount].rvIndex = 0;
+      }
+      else
+      {
+         pdsch->codeword[cwCount].rvIndex = (pdsch->codeword[cwCount].rvIndex +1) & 0x03;
+         tbSize = hqP->tbInfo[cwCount].tbSzReq;
+      }
       pdsch->codeword[cwCount].tbSize = tbSize;
    }
    pdsch->dataScramblingId = cell->cellCfg.phyCellId;
@@ -712,23 +721,32 @@ uint8_t pdschStartSymbol, uint8_t pdschNumSymbols)
  *       Scheduling for Pucch Resource
  *
  * @params[in] SchCellCb *cell, SlotTimingInfo pucchTime, crnti
+ * @params[in] SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP
  * @return ROK     - success
  *         RFAILED - failure
  *
  *******************************************************************/
 
-uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti)
+uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16_t crnti,
+                               SchUeCb *ueCb, bool isRetx, SchDlHqProcCb *hqP)
 {
    uint16_t pucchSlot = 0;
    SchUlSlotInfo  *schUlSlotInfo = NULLP;
-   
+
    pucchSlot = pucchTime.slot;
    schUlSlotInfo = cell->schUlSlotInfo[pucchSlot];
    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 */
+      ADD_DELTA_TO_TIME(pucchTime, pucchTime, 3); /* SLOT_DELAY=3 */
+      cmLListAdd2Tail(&(ueCb->hqDlmap[pucchTime.slot]->hqList), &hqP->ulSlotLnk);
+   }
    return ROK;
 }
 
@@ -743,13 +761,18 @@ uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16
  *    Functionality:
  *       Fills pdcch and pdsch info for dl msg
  *
- * @params[in]
+ * @params[in] SchCellCb *cell, SlotTimingInfo slotTime
+ * @params[in] uint16_t crnti, uint32_t tbSize
+ * @params[in] DlMsgAlloc *dlMsgAlloc, uint16_t startPRB
+ * @params[in] uint8_t pdschStartSymbol, uint8_t pdschNumSymbols
+ * @params[in] bool isRetx, SchDlHqProcCb *hqP
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
 uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti,
-                uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol, uint8_t pdschNumSymbols)
+                uint32_t tbSize, DlMsgAlloc *dlMsgAlloc, uint16_t startPRB, uint8_t pdschStartSymbol,
+                uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb *hqP)
 {
    uint8_t ueId=0;
    PdcchCfg *pdcch = NULLP;
@@ -816,7 +839,11 @@ uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t c
       pdsch->codeword[cwCount].mcsTable = ueCb.ueCfg.dlModInfo.mcsTable;
       pdsch->codeword[cwCount].rvIndex = 0;
 
-      tbSize +=TX_PAYLOAD_HDR_LEN;
+      if (isRetx != TRUE)
+      {
+         tbSize +=TX_PAYLOAD_HDR_LEN;
+         hqP->tbInfo[cwCount].tbSzReq = tbSize;
+      }
       pdsch->codeword[cwCount].tbSize = tbSize;
    }
    pdsch->dataScramblingId = cell->cellCfg.phyCellId;
@@ -1628,18 +1655,25 @@ void updateGrantSizeForBoRpt(CmLListCp *lcLL, DlMsgAlloc *dlMsgAlloc,\
 *       fill DL message information for MSG4 and Dedicated DL Msg
 *
 * @params[in] DlMsgInfo *dlMsgInfo,  uint8_t crnti
+* @params[in] bool isRetx, SchDlHqProcCb *hqP
 * @return void
 *
 *******************************************************************/
-void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti)
+void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti, bool isRetx, SchDlHqProcCb *hqP)
 {
+   hqP->tbInfo[0].isEnabled = TRUE;
+   hqP->tbInfo[0].state = HQ_TB_WAITING;
+   hqP->tbInfo[0].txCntr++;
+   hqP->tbInfo[1].isEnabled = TRUE;
+   hqP->tbInfo[1].state = HQ_TB_WAITING;
+   hqP->tbInfo[1].txCntr++;
    dlMsgInfo->crnti = crnti;
-   dlMsgInfo->ndi = 1;
-   dlMsgInfo->harqProcNum = 0;
+   dlMsgInfo->ndi = hqP->tbInfo[0].ndi; /*How to handle two tb case?TBD*/
+   dlMsgInfo->harqProcNum = hqP->procId;
    dlMsgInfo->dlAssignIdx = 0;
    dlMsgInfo->pucchTpc = 0;
    dlMsgInfo->pucchResInd = 0;
-   dlMsgInfo->harqFeedbackInd = 0;
+   dlMsgInfo->harqFeedbackInd = hqP->k1;
    dlMsgInfo->dciFormatId = 1;
 }
 
@@ -1654,13 +1688,17 @@ void fillDlMsgInfo(DlMsgInfo *dlMsgInfo, uint8_t crnti)
  *    Functionality:
  *       sch Process pending Msg4 Req
  *
- * @params[in] SchCellCb *cell,  SlotTimingInfo currTime 
+ * @params[in] SchCellCb *cell, cell cb struct pointer
+ * @params[in] SlotTimingInfo currTime, current timing info
+ * @params[in] uint8_t ueId, ue ID
+ * @params[in] bool isRetxMsg4, indicator to MSG4 retransmission
+ * @params[in] SchDlHqProcCb **msg4HqProc, address of MSG4 HARQ proc pointer
  * @return ROK     - success
  *         RFAILED - failure
  *
  *******************************************************************/
 
-bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
+uint8_t schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetxMsg4, SchDlHqProcCb **msg4HqProc)
 {
    uint8_t pdschStartSymbol = 0, pdschNumSymbols = 0;
    SlotTimingInfo pdcchTime, pdschTime, pucchTime;
@@ -1670,13 +1708,23 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
    if(cell == NULL)
    {
       DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() : Cell is NULL");
-      return false;
+      return RFAILED;
    }
-   
+
+   if (isRetxMsg4 == FALSE)
+   {
+      if (RFAILED == schDlGetAvlHqProcess(cell, &cell->ueCb[ueId - 1], msg4HqProc))
+      {
+         DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() : No process");
+         return RFAILED;
+      }
+   }
+
    if(findValidK0K1Value(cell, currTime, ueId, false, &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime,\
-            &pucchTime) != true )
+            &pucchTime, isRetxMsg4, *msg4HqProc) != true )
    {
-      return false;
+      DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() : k0 k1 not found");
+      return RFAILED;
    }
 
    if(cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] == NULL)
@@ -1685,7 +1733,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
       if(dciSlotAlloc == NULLP)
       {
          DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciSlotAlloc");
-         return false;
+         return RFAILED;
       }
       cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] = dciSlotAlloc;
       memset(dciSlotAlloc, 0, sizeof(DlMsgAlloc));
@@ -1695,7 +1743,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
       dciSlotAlloc = cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1];
 
    /* Fill PDCCH and PDSCH scheduling information for Msg4 */
-   if((schDlRsrcAllocMsg4(cell, pdschTime, ueId, dciSlotAlloc, pdschStartSymbol, pdschNumSymbols)) != ROK)
+   if((schDlRsrcAllocMsg4(cell, pdschTime, ueId, dciSlotAlloc, pdschStartSymbol, pdschNumSymbols, isRetxMsg4, *msg4HqProc)) != ROK)
    {
       DU_LOG("\nERROR  -->  SCH: Scheduling of Msg4 failed in slot [%d]", pdschTime.slot);
       if(dciSlotAlloc->numSchedInfo == 0)
@@ -1705,7 +1753,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
       }
       else
          memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
-      return false;
+      return RFAILED;
    }
 
    /* Check if both DCI and RAR are sent in the same slot.
@@ -1732,7 +1780,7 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
             }
             else
                memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
-            return false;
+            return RFAILED;
          }
          cell->schDlSlotInfo[pdschTime.slot]->dlMsgAlloc[ueId-1] = msg4SlotAlloc;
          memset(msg4SlotAlloc, 0, sizeof(DlMsgAlloc));
@@ -1757,13 +1805,17 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
    }
 
    /* PUCCH resource */
-   schAllocPucchResource(cell, pucchTime, cell->raCb[ueId-1].tcrnti);
+   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;
-   return true;
+   if(isRetxMsg4)
+   {
+      cell->ueCb[ueId-1].retxMsg4HqProc= NULLP;
+   }
+   return ROK;
 }
 
 /*******************************************************************
@@ -1783,18 +1835,20 @@ bool schProcessMsg4Req(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
  *         [out] startPrb(Pointer to startPRB which will be calculated while
  *         finding the best Free Block)
  *         [out] totTBS(Pointer to total TBS size)
+ *         [in] isRetx (to indicate retransmission)
+ *         [in] hqP (UL Harq process pointer)
  *
- * @return bool : true > Scheduling of UL grant is successful
- *                false > vice versa
+ * @return uint8_t : ROK > Scheduling of UL grant is successful
+ *                   RFAILED > vice versa
  *
  * ****************************************************************/
-bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
-                          uint16_t *startPrb, uint32_t *totTBS)
+uint8_t schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
+                          uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP)
 {
    uint16_t mcsIdx = 0;
    CmLListCp *lcLL = NULLP;
    uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
-
+   uint16_t rsvdDedicatedPRB;
    *startPrb = 0;
    *totTBS = 0;
 
@@ -1812,33 +1866,32 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,
       lcId = lcgIdx;
       if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
       {
-         lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList);
+         lcLL = &(hqP->ulLcPrbEst.dedLcList);
+         rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
       }
       else
       {
-         lcLL = &(ueCb->ulLcPrbEst.defLcList);
+         lcLL = &(hqP->ulLcPrbEst.defLcList);
       }
 
       /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
       if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
       {
-         DU_LOG("\nERROR  --> SCH: LcgId:%d updation failed",lcId);
-         return false; 
+         DU_LOG("\nERROR  --> SCH: LcgId:%d updation failed",lcId);         
+         return RFAILED;
       }
    }
 
-   if ((ueCb->ulLcPrbEst.defLcList.count == 0) && \
-         ((ueCb->ulLcPrbEst.dedLcInfo == NULL) || (ueCb->ulLcPrbEst.dedLcInfo->dedLcList.count == 0)))
+   if ((hqP->ulLcPrbEst.defLcList.count == 0) && (hqP->ulLcPrbEst.dedLcList.count == 0))
    {
-      if(ueCb->srRcvd)
+      if( (ueCb->srRcvd) || (isRetx) )
       {
          *startPrb = MAX_NUM_RB;
          *totTBS = schCalcTbSize(UL_GRANT_SIZE);
       }
-
       /*Returning true when NO Grant is there for UE as this is not scheduling
-       * error*/
-      return (true);
+       * error*/      
+      return ROK;
    }
 
    maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
@@ -1851,38 +1904,37 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,
    if(maxFreePRB != 0)
    {
       mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
-      if((ueCb->ulLcPrbEst.dedLcInfo == NULLP) 
-            || ((maxFreePRB <  ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB)))
-      { 
-         ueCb->ulLcPrbEst.sharedNumPrb = maxFreePRB;
+      if((hqP->ulLcPrbEst.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
+      {
+         hqP->ulLcPrbEst.sharedNumPrb = maxFreePRB;
          DU_LOG("\nDEBUG  -->  SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
-               ueCb->ulLcPrbEst.sharedNumPrb);
+               hqP->ulLcPrbEst.sharedNumPrb);
 
          /*PRB Alloc for Default LCs*/
-         prbAllocUsingRRMPolicy(&(ueCb->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen,\
-               &(ueCb->ulLcPrbEst.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
+         prbAllocUsingRRMPolicy(&(hqP->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen,\
+               &(hqP->ulLcPrbEst.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
       }
       else
       {
-         ueCb->ulLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB;
+         hqP->ulLcPrbEst.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
 
          /*PRB Alloc for Dedicated LCs*/
-         prbAllocUsingRRMPolicy(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, symbLen,\
-               &(ueCb->ulLcPrbEst.sharedNumPrb), &(ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB),\
+         prbAllocUsingRRMPolicy(&(hqP->ulLcPrbEst.dedLcList), TRUE, mcsIdx, symbLen,\
+               &(hqP->ulLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB),\
                NULLP,&(ueCb->srRcvd));
 
          /*PRB Alloc for Default LCs*/
-         prbAllocUsingRRMPolicy(&(ueCb->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen, \
-               &(ueCb->ulLcPrbEst.sharedNumPrb), &(ueCb->ulLcPrbEst.dedLcInfo->rsvdDedicatedPRB),\
+         prbAllocUsingRRMPolicy(&(hqP->ulLcPrbEst.defLcList), FALSE, mcsIdx, symbLen, \
+               &(hqP->ulLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB),\
                NULLP,&(ueCb->srRcvd));
       }
    }
    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
     * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ 
-   if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
-      updateGrantSizeForBoRpt(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), NULLP, ueCb->bsrInfo, totTBS);
+   if(hqP->ulLcPrbEst.dedLcList.count != 0)
+      updateGrantSizeForBoRpt(&(hqP->ulLcPrbEst.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
 
-   updateGrantSizeForBoRpt(&(ueCb->ulLcPrbEst.defLcList), NULLP, ueCb->bsrInfo, totTBS);
+   updateGrantSizeForBoRpt(&(hqP->ulLcPrbEst.defLcList), NULLP, ueCb->bsrInfo, totTBS);
 
    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
    if (*totTBS == 0)
@@ -1895,10 +1947,10 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,
       {
          /*Schedule the LC for next slot*/
          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
-      }
-      return (false);
-   }
-   return (true);
+      }      
+      return RFAILED;
+   }   
+   return ROK;
 }
 
 /*******************************************************************
@@ -1912,14 +1964,15 @@ bool schCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,
  *    Functionality:
  *       sch Process pending Sr or Bsr Req
  *
- * @params[in] SchCellCb *cell,  SlotTimingInfo currTime 
- * @return ROK     - success
- *         RFAILED - failure
+ * @params[in] SchCellCb *cell,  SlotTimingInfo currTime
+ * @params[in] uint8_t ueId, Bool isRetx, SchUlHqProcCb **hqP
+ * @return true  - success
+ *         false - failure
  *
  *******************************************************************/
-bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
+bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetx, SchUlHqProcCb **hqP)
 {
-   bool k2Found = FALSE, ret = FALSE;
+   bool k2Found = FALSE, ret = RFAILED;
    uint8_t startSymb = 0, symbLen = 0;
    uint8_t k2TblIdx = 0, k2Index = 0, k2Val = 0;
    uint16_t startPrb = 0;
@@ -1929,10 +1982,10 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId
    DciInfo  *dciInfo = NULLP;
    SchK2TimingInfoTbl *k2InfoTbl=NULLP;
    SlotTimingInfo dciTime, puschTime;
-
+   
    if(cell == NULLP)
    {
-      DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() : Cell is NULL");
+      DU_LOG("\nERROR  -->  SCH: schProcessSrOrBsrReq() : Cell is NULL");
       return false;
    }
 
@@ -1940,9 +1993,18 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId
 
    if(ueCb == NULLP)
    {
-      DU_LOG("\nERROR  -->  SCH: schDlRsrcAllocMsg4() : UE is NULL");
+      DU_LOG("\nERROR  -->  SCH: schProcessSrOrBsrReq() : UE is NULL");
       return false;
    }
+
+   if (isRetx == FALSE)
+   {
+      if (schUlGetAvlHqProcess(cell, ueCb, hqP) != ROK)
+      {
+         return RFAILED;
+      }
+   }
+
    /* Calculating time frame to send DCI for SR */
    ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA);
 #ifdef NR_TDD
@@ -1970,7 +2032,7 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId
             startSymb =  ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[k2Index].startSymbol;
             symbLen =  ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList[k2Index].symbolLength;
          }
-
+         /* Check for number of Symbol of PUSCH should be same as original in case of transmisson*/
          /* Calculating time frame to send PUSCH for SR */
          ADD_DELTA_TO_TIME(dciTime, puschTime, k2Val);
 #ifdef NR_TDD
@@ -1988,25 +2050,28 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId
 
    if(k2Found == true)
    {
-      ret = schCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq);
-      if(totDataReq > 0 && ret == TRUE)
+      ret = schCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP);
+
+      if(totDataReq > 0 && ret == ROK)
       {
          SCH_ALLOC(dciInfo, sizeof(DciInfo));
          if(!dciInfo)
          {
             DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciInfo alloc");
+            if(isRetx != TRUE)
+            {
+               if((*hqP)->ulLcPrbEst.dedLcList.count != 0)
+                  updateBsrAndLcList(&((*hqP)->ulLcPrbEst.dedLcList), ueCb->bsrInfo, RFAILED);
 
-            if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
-               updateBsrAndLcList(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), ueCb->bsrInfo, RFAILED);
-
-            updateBsrAndLcList(&(ueCb->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED);
+               updateBsrAndLcList(&((*hqP)->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED);
+            }
             return false;
          }
          cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
          memset(dciInfo,0,sizeof(DciInfo));
 
          /* Update PUSCH allocation */
-         if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb) == ROK)
+         if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
          {
             if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo)
             {
@@ -2014,24 +2079,22 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId
                if(puschInfo != NULLP)
                {
                   /* Fill DCI for UL grant */
-                  schFillUlDci(ueCb, puschInfo, dciInfo);
+                  schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
                   memcpy(&dciInfo->slotIndInfo, &dciTime, sizeof(SlotTimingInfo));
                   ueCb->srRcvd = false;
                   ueCb->bsrRcvd = false;
                   cell->schUlSlotInfo[puschTime.slot]->puschUe = ueId;
-                  if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
-                     updateBsrAndLcList(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), ueCb->bsrInfo, ROK);
-
-                  updateBsrAndLcList(&(ueCb->ulLcPrbEst.defLcList), ueCb->bsrInfo, ROK);
+                  if((*hqP)->ulLcPrbEst.dedLcList.count != 0)
+                     updateBsrAndLcList(&((*hqP)->ulLcPrbEst.dedLcList), ueCb->bsrInfo, ROK);
+                  updateBsrAndLcList(&((*hqP)->ulLcPrbEst.defLcList), ueCb->bsrInfo, ROK);
+                  cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);                  
                   return true;
                }
             }
          }
-
-         if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
-            updateBsrAndLcList(&(ueCb->ulLcPrbEst.dedLcInfo->dedLcList), ueCb->bsrInfo, RFAILED);
-
-         updateBsrAndLcList(&(ueCb->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED);
+         if((*hqP)->ulLcPrbEst.dedLcList.count != 0)
+            updateBsrAndLcList(&((*hqP)->ulLcPrbEst.dedLcList), ueCb->bsrInfo, RFAILED);
+         updateBsrAndLcList(&((*hqP)->ulLcPrbEst.defLcList), ueCb->bsrInfo, RFAILED);
       }
    }
    return (ret);
diff --git a/src/5gnrsch/sch_crc.c b/src/5gnrsch/sch_crc.c
new file mode 100644 (file)
index 0000000..4aa9f81
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+#include "common_def.h"
+#include "tfu.h"
+#include "lrg.h"
+#include "tfu.x"
+#include "lrg.x"
+#include "du_log.h"
+#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "sch.h"
+#include "sch_utils.h"
+
+/**
+ * @brief Process CRC indication
+ *
+ * @details
+ *
+ *     Function : schProcessCrcInd
+ *      
+ *      This function process CRC indication
+ *           
+ *  @param[in]  CrcIndInfo *crcInd, recvd crc indication
+ *  @param[in]  Inst schInst, scheduler inst
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+uint8_t schProcessCrcInd(CrcIndInfo *crcInd, Inst schInst)
+{
+   SchCellCb *cell = schCb[schInst].cells[schInst];
+   uint16_t count=0;
+   uint8_t  ueId=0;
+   SchUlHqProcCb *hqP = NULLP;
+
+   while(count  <crcInd->numCrcInd)
+   {
+      GET_UE_ID(crcInd->crnti, ueId);
+      if (cell->raCb[ueId-1].raState == SCH_RA_STATE_MSG3_PENDING)
+      {
+         if (crcInd->crcInd[count])
+         {
+            /* failure case*/
+            if (cell->raCb[ueId-1].msg3HqProc.tbInfo.txCntr < cell->cellCfg.schRachCfg.maxMsg3Tx)
+            {
+               addUeToBeScheduled(cell, ueId);
+               cell->raCb[ueId - 1].retxMsg3HqProc = &cell->raCb[ueId - 1].msg3HqProc;
+            }
+            else
+            {
+               /*Release all contexts of the UE RA*/
+            }
+         }
+         else
+         {
+            /* pass case*/
+            /*Dedicated preamble case need to be added*/
+            cell->raCb[ueId-1].raState = SCH_RA_STATE_MSG4_PENDING;
+            /*HARQ init part is in ADD UE CONFIG now, could be moved here*/
+         }         
+      }
+      else
+      {
+         if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.count == 0)
+         {
+            DU_LOG("\n ERROR no harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId);
+            continue;
+         }
+         if (cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first == 0)
+         {
+            DU_LOG("\n ERROR NULL harq stored in ul hq map at slot %d ue id %d\n",crcInd->timingInfo.slot, ueId);
+            continue;
+         }
+         hqP = (SchUlHqProcCb*) cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList.first->node;
+         if(hqP == NULLP)
+         {
+            continue;
+         }
+         else
+         {
+            if (crcInd->crcInd[count])
+            {             
+               /* failure case*/
+               schUlHqProcessNack(hqP);
+            }
+            else
+            {
+               /* pass case*/
+               schUlHqProcessAck(hqP);
+            }
+         }
+         cmLListDelFrm(&(cell->ueCb[ueId-1].hqUlmap[crcInd->timingInfo.slot]->hqList), &hqP->ulSlotLnk);
+      }
+      count++;
+   }
+   return ROK;
+}
+/**********************************************************************
+  End of file
+ **********************************************************************/
\ No newline at end of file
diff --git a/src/5gnrsch/sch_harq_dl.c b/src/5gnrsch/sch_harq_dl.c
new file mode 100644 (file)
index 0000000..c5cebed
--- /dev/null
@@ -0,0 +1,403 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+#include "common_def.h"
+#include "tfu.h"
+#include "lrg.h"
+#include "tfu.x"
+#include "lrg.x"
+#include "du_log.h"
+#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "sch.h"
+#include "sch_utils.h"
+#include "cm_llist.h"
+
+SchMacDlReleaseHarqFunc schMacDlReleaseHarqOpts[] =
+{
+   packSchMacDlReleaseHarq,
+   MacSchReleaseDlHarqProc,
+   packSchMacDlReleaseHarq
+};
+
+typedef struct schCellCb SchCellCb;
+typedef struct schUeCb SchUeCb;
+void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE);
+void schDlHqAddToFreeList(SchDlHqProcCb *hqP);
+
+/**
+ * @brief DL Harq entity intialization
+ *
+ * @details
+ *
+ *     Function : schDlHqEntInit
+ *      
+ *      This function intialize DL Harq entity
+ *           
+ *  @param[in]  SchCellCb *cellCb, cell cb pointer
+ *  @param[in]  SchUeCb *ueCb, ue cb pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb)
+{
+   ueCb->dlHqEnt.numHqPrcs = SCH_MAX_NUM_DL_HQ_PROC;
+   ueCb->dlHqEnt.maxHqTx  = cellCb->cellCfg.schHqCfg.maxDlDataHqTx;
+   ueCb->dlHqEnt.cell = cellCb;
+   ueCb->dlHqEnt.ue =ueCb;
+   schDlHqEntReset(cellCb, ueCb, &ueCb->dlHqEnt);
+}
+/**
+ * @brief DL Harq entity Reset
+ *
+ * @details
+ *
+ *     Function : schDlHqEntReset
+ *      
+ *      This function Reset DL Harq entity
+ *           
+ *  @param[in]  SchCellCb *cellCb, cell cb pointer
+ *  @param[in]  SchUeCb *ueCb, ue cb pointer
+ *  @param[in]  SchDlHqEnt *hqE, Dl Harq entity pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE)
+{
+   uint8_t count = 0;
+   SchDlHqProcCb *hqP = NULL;
+   cmLListInit(&hqE->free);
+   cmLListInit(&hqE->inUse);
+
+   for(count=0; count < hqE->numHqPrcs; count++)
+   {
+      hqP = &(hqE->procs[count]);
+      hqP->procId = count;
+      hqP->hqEnt = hqE;
+      hqP->maxHqTxPerHqP = hqE->maxHqTx;
+      hqP->dlHqEntLnk.node = (PTR)hqP;
+      hqP->dlHqProcLink.node = (PTR)hqP;
+      hqP->ulSlotLnk.node = (PTR)hqP;
+      schDlHqAddToFreeList(hqP);
+   }
+}
+/**
+ * @brief Add hq process to free list of DL Harq entity
+ *
+ * @details
+ *
+ *     Function : schDlHqAddToFreeList
+ *      
+ *      This function adds hq process to free list of DL Harq entity
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlHqAddToFreeList(SchDlHqProcCb *hqP)
+{   
+   cmLListAdd2Tail(&(hqP->hqEnt->free), &hqP->dlHqEntLnk);
+}
+/**
+ * @brief Delete hq process from free list of DL Harq entity
+ *
+ * @details
+ *
+ *     Function : schDlHqDeleteFromFreeList
+ *      
+ *      This function deletes hq process to free list of DL Harq entity
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlHqDeleteFromFreeList(SchDlHqProcCb *hqP)
+{
+   cmLListDelFrm(&(hqP->hqEnt->free), &hqP->dlHqEntLnk);
+}
+/**
+ * @brief Add hq process to in use list of DL Harq entity
+ *
+ * @details
+ *
+ *     Function : schDlHqAddToInUseList
+ *      
+ *      This function adds hq process to in use list of DL Harq entity
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlHqAddToInUseList(SchDlHqProcCb *hqP)
+{
+   cmLListAdd2Tail(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk);
+}
+/**
+ * @brief Delete hq process from in use list of DL Harq entity
+ *
+ * @details
+ *
+ *     Function : schDlHqDeleteFromInUseList
+ *      
+ *      This function deletes hq process to in use list of DL Harq entity
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlHqDeleteFromInUseList(SchDlHqProcCb *hqP)
+{   
+   cmLListDelFrm(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk);
+}
+/**
+ * @brief Get available Harq process from Harq entity
+ *
+ * @details
+ *
+ *     Function : schDlGetAvlHqProcess
+ *      
+ *      This function fetches hq process from free list and puts in in use list
+ *           
+ *  @param[in]  SchCellCb *cellCb, cell cb pointer
+ *  @param[in]  SchUeCb *ueCb, ue cb pointer
+ *  @param[in]  SchDlHqProcCb **hqP, Address of DL harq process pointer
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+uint8_t schDlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqProcCb **hqP)
+{
+   SchDlHqProcCb *tmp;
+   if (ueCb->dlHqEnt.free.count == 0)
+   {
+      return RFAILED;
+   }
+   tmp = (SchDlHqProcCb*)(cmLListFirst(&(ueCb->dlHqEnt.free))->node);
+   if (NULLP == tmp)
+   {
+      return RFAILED;
+   }
+   schDlHqDeleteFromFreeList(tmp);
+   schDlHqAddToInUseList(tmp);
+   *hqP = tmp;
+   (*hqP)->maxHqTxPerHqP = ueCb->dlHqEnt.maxHqTx;
+   return ROK;
+}
+/**
+ * @brief Release Harq process from the DL Harq entity
+ *
+ * @details
+ *
+ *     Function : schDlReleaseHqProcess
+ *      
+ *      This function releases Harq process from DL Harq entity
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schDlReleaseHqProcess(SchDlHqProcCb *hqP)
+{
+   cmLListDeleteLList(&hqP->dlLcPrbEst.dedLcList);
+   cmLListDeleteLList(&hqP->dlLcPrbEst.defLcList);
+   schDlHqDeleteFromInUseList(hqP);
+   schDlHqAddToFreeList(hqP);
+}
+
+/*******************************************************************
+ *
+ * @brief Handles sending DL HARQ process release to MAC 
+ *
+ * @details
+ *
+ *    Function : sendDlHarqProcReleaseToMac
+ *
+ *    Functionality:
+ *     Sends DL DL HARQ process release to MAC from SCH
+ *
+ * @params[in] 
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t sendDlHarqProcReleaseToMac(SchDlHqProcCb *hqP, Inst inst)
+{
+   Pst pst;
+   SchRlsHqInfo *rlsHqInfo;
+   memset(&pst, 0, sizeof(Pst));
+   FILL_PST_SCH_TO_MAC(pst, inst);
+   pst.event = EVENT_DL_REL_HQ_PROC;
+
+   SCH_ALLOC(rlsHqInfo, sizeof(SchRlsHqInfo));
+   rlsHqInfo->cellId = hqP->hqEnt->cell->cellId;
+   rlsHqInfo->numUes = 1;
+
+   SCH_ALLOC(rlsHqInfo->ueHqInfo, sizeof(SchUeHqInfo)*rlsHqInfo->numUes);
+   rlsHqInfo->ueHqInfo[0].crnti = hqP->hqEnt->ue->crnti;
+   rlsHqInfo->ueHqInfo[0].hqProcId = hqP->procId;   
+
+   return(*schMacDlReleaseHarqOpts[pst.selector])(&pst, rlsHqInfo);
+}
+/**
+ * @brief Release Harq process TB from the DL Harq process
+ *
+ * @details
+ *
+ *     Function : schDlReleaseHqPTb
+ *      
+ *      This function releases Harq process TB from DL Harq proces
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @param[in]  uint8_t tbIdx, TB index
+ *  @param[in]  bool togNdi, indication to toggle NDI bit
+ *  @return  
+ *      -# void
+ **/
+void schDlReleaseHqPTb(SchDlHqProcCb *hqP, uint8_t tbIdx, bool togNdi)
+{
+   if (TRUE == togNdi)
+   {
+      hqP->tbInfo[tbIdx].ndi ^= 1;
+   }
+
+   {
+      hqP->tbInfo[tbIdx].isAckNackDtx = HQ_ACK;
+      hqP->tbInfo[tbIdx].isEnabled = FALSE;
+      hqP->tbInfo[tbIdx].state = HQ_TB_ACKED;
+      hqP->tbInfo[tbIdx].txCntr = 0;
+      if (HQ_TB_ACKED == hqP->tbInfo[tbIdx^1].state)
+      {
+         schDlReleaseHqProcess(hqP);
+         sendDlHarqProcReleaseToMac(hqP, hqP->hqEnt->cell->instIdx);
+      }
+   }
+}
+/**
+ * @brief Handles failure of HARQ process TB
+ *
+ * @details
+ *
+ *     Function : schDlHqTbFail
+ *      
+ *      This function handles failure of HARQ process TB
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @param[in]  uint8_t tbIdx, TB index
+ *  @param[in]  bool isMaxRetx, indicates max retransmission
+ *  @return  
+ *      -# void
+ **/
+void schDlHqTbFail(SchDlHqProcCb *hqP, uint8_t tbIdx, bool isMaxRetx)
+{
+   if (isMaxRetx)
+   {
+      schDlReleaseHqPTb(hqP, tbIdx, TRUE);
+   }
+   else
+   {
+      hqP->tbInfo[tbIdx].state = HQ_TB_NACKED;
+      if (HQ_TB_WAITING == hqP->tbInfo[tbIdx^1].state)
+      {
+         cmLListAdd2Tail( &(hqP->hqEnt->ue->dlRetxHqList), &hqP->dlHqProcLink);
+      }
+   }
+}
+/**
+ * @brief Handles Harq feedback for MSG4
+ *
+ * @details
+ *
+ *     Function : schMsg4FeedbackUpdate
+ *      
+ *      This function handles Harq feedback for MSG4
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @param[in]  uint8_t fdbk, Received feedback
+ *  @return  
+ *      -# void
+ **/
+void schMsg4FeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk)
+{
+   hqP->tbInfo[0].isAckNackDtx = fdbk;
+   hqP->tbInfo[1].isAckNackDtx = HQ_TB_ACKED;
+   if (HQ_TB_ACKED == hqP->tbInfo[0].isAckNackDtx)
+   {
+      schDlReleaseHqPTb(hqP, 0, TRUE);
+      schDlReleaseHqPTb(hqP, 1, TRUE);
+      schMsg4Complete(hqP->hqEnt->ue);
+   }
+   else
+   {
+      if( hqP->tbInfo[0].txCntr >= hqP->hqEnt->cell->cellCfg.schHqCfg.maxMsg4HqTx)
+      {
+         schDlReleaseHqProcess(hqP);
+         hqP->hqEnt->ue->msg4Proc = NULLP;
+         hqP->hqEnt->ue->retxMsg4HqProc = NULLP;
+         /* Delete UE and RA context */
+      }
+      addUeToBeScheduled(hqP->hqEnt->cell,hqP->hqEnt->ue->ueId);
+      hqP->hqEnt->ue->retxMsg4HqProc = hqP;
+   }
+}
+/**
+ * @brief Handles Harq feedback for DL Data
+ *
+ * @details
+ *
+ *     Function : schDlHqFeedbackUpdate
+ *      
+ *      This function handles Harq feedback for DL data
+ *           
+ *  @param[in]  SchDlHqProcCb *hqP, DL harq process pointer
+ *  @param[in]  uint8_t fdbk1, Received feedback for TB -0
+ *  @param[in]  uint8_t fdbk2, Received feedback for TB -1
+ *  @return  
+ *      -# void
+ **/
+void schDlHqFeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk1, uint8_t fdbk2)
+{
+   uint8_t tbIdx;
+   for (tbIdx = 0; tbIdx <2; tbIdx++)
+   {
+      if (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state)
+      {
+         hqP->tbInfo[tbIdx].isAckNackDtx = (0 == tbIdx)?fdbk1:fdbk2;
+      }
+      if (TRUE == hqP->tbInfo[tbIdx].isEnabled)
+      {
+         if (HQ_TB_ACKED == hqP->tbInfo[tbIdx].isAckNackDtx)
+         {
+            schDlReleaseHqPTb(hqP, tbIdx, TRUE);
+         }
+         else
+         {
+            if(hqP->tbInfo[tbIdx].txCntr >= hqP->maxHqTxPerHqP)
+            {
+               schDlHqTbFail(hqP, tbIdx, TRUE);
+            }
+            else
+            {
+               schDlHqTbFail(hqP, tbIdx, FALSE);
+               addUeToBeScheduled(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
+            }
+         }
+      }
+   }
+}
+/**********************************************************************
+  End of file
+ **********************************************************************/
diff --git a/src/5gnrsch/sch_harq_ul.c b/src/5gnrsch/sch_harq_ul.c
new file mode 100644 (file)
index 0000000..fdd5ffa
--- /dev/null
@@ -0,0 +1,266 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+#include "common_def.h"
+#include "tfu.h"
+#include "lrg.h"
+#include "tfu.x"
+#include "lrg.x"
+#include "du_log.h"
+#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "sch.h"
+#include "sch_utils.h"
+typedef struct schCellCb SchCellCb;
+typedef struct schUeCb SchUeCb;
+void schUlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqEnt *hqE);
+void schUlHqAddToFreeList(SchUlHqProcCb *hqP);
+/**
+ * @brief UL Harq entity intialization
+ *
+ * @details
+ *
+ *     Function : schUlHqEntInit
+ *      
+ *      This function intialize UL Harq entity
+ *           
+ *  @param[in]  SchCellCb *cellCb, cell cb pointer
+ *  @param[in]  SchUeCb *ueCb, ue cb pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb)
+{
+   ueCb->ulHqEnt.numHqPrcs = SCH_MAX_NUM_UL_HQ_PROC;
+   ueCb->ulHqEnt.maxHqTx  = cellCb->cellCfg.schHqCfg.maxUlDataHqTx;
+   ueCb->ulHqEnt.cell = cellCb;
+   ueCb->ulHqEnt.ue =ueCb;
+   schUlHqEntReset(cellCb, ueCb, &ueCb->ulHqEnt);
+}
+/**
+ * @brief UL Harq entity Reset
+ *
+ * @details
+ *
+ *     Function : schUlHqEntReset
+ *      
+ *      This function Reset UL Harq entity
+ *           
+ *  @param[in]  SchCellCb *cellCb, cell cb pointer
+ *  @param[in]  SchUeCb *ueCb, ue cb pointer
+ *  @param[in]  SchUlHqEnt *hqE, Ul Harq entity pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqEnt *hqE)
+{
+   uint8_t count = 0;
+   SchUlHqProcCb *hqP = NULL;
+   cmLListInit(&hqE->free);
+   cmLListInit(&hqE->inUse);
+   for(count=0; count < hqE->numHqPrcs; count++)
+   {
+      hqP = &(hqE->procs[count]);
+      hqP->procId = count;
+      hqP->hqEnt = hqE;
+      hqP->maxHqTxPerHqP = hqE->maxHqTx;
+      hqP->ulHqEntLnk.node = (PTR)hqP;
+      hqP->ulHqProcLink.node = (PTR)hqP;
+      hqP->ulSlotLnk.node = (PTR)hqP;
+      schUlHqAddToFreeList(hqP);
+   }
+}
+/**
+ * @brief Add hq process to free list of UL Harq entity
+ *
+ * @details
+ *
+ *     Function : schUlHqAddToFreeList
+ *      
+ *      This function adds hq process to free list of UL Harq entity
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqAddToFreeList(SchUlHqProcCb *hqP)
+{
+   cmLListAdd2Tail(&(hqP->hqEnt->free), &hqP->ulHqEntLnk);
+}
+/**
+ * @brief Delete hq process from free list of UL Harq entity
+ *
+ * @details
+ *
+ *     Function : schUlHqDeleteFromFreeList
+ *      
+ *      This function deletes hq process to free list of UL Harq entity
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqDeleteFromFreeList(SchUlHqProcCb *hqP)
+{
+   if(hqP->hqEnt->free.count == 0)
+   {
+      DU_LOG("\n ERROR schUlHqDeleteFromInUseList no proc in in free\n");
+   }
+   cmLListDelFrm(&(hqP->hqEnt->free), &hqP->ulHqEntLnk);
+}
+/**
+ * @brief Add hq process to in use list of UL Harq entity
+ *
+ * @details
+ *
+ *     Function : schUlHqAddToInUseList
+ *      
+ *      This function adds hq process to in use list of UL Harq entity
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqAddToInUseList(SchUlHqProcCb *hqP)
+{
+   cmLListAdd2Tail(&(hqP->hqEnt->inUse), &hqP->ulHqEntLnk);
+}
+/**
+ * @brief Delete hq process from in use list of UL Harq entity
+ *
+ * @details
+ *
+ *     Function : schUlHqDeleteFromInUseList
+ *      
+ *      This function deletes hq process to in use list of UL Harq entity
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqDeleteFromInUseList(SchUlHqProcCb *hqP)
+{
+   if(hqP->hqEnt->inUse.count == 0)
+   {
+      DU_LOG("\n ERROR schUlHqDeleteFromInUseList no proc in in use\n");
+   }
+   cmLListDelFrm(&(hqP->hqEnt->inUse), &hqP->ulHqEntLnk);
+}
+/**
+ * @brief Get available Harq process from Harq entity
+ *
+ * @details
+ *
+ *     Function : schUlGetAvlHqProcess
+ *      
+ *      This function fetches hq process from free list and puts in in use list
+ *           
+ *  @param[in]  SchCellCb *cellCb, cell cb pointer
+ *  @param[in]  SchUeCb *ueCb, ue cb pointer
+ *  @param[in]  SchUlHqProcCb **hqP, Address of UL harq process pointer
+ *  @return  
+ *      -# ROK
+ *      -# RFAILED
+ **/
+uint8_t schUlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchUlHqProcCb **hqP)
+{
+   SchUlHqProcCb                  *tmp;
+   if (ueCb->ulHqEnt.free.count == 0)
+   {
+      return RFAILED;
+   }
+   tmp = (SchUlHqProcCb*)(cmLListFirst(&(ueCb->ulHqEnt.free))->node);
+   if (NULLP == tmp)
+   {
+      return RFAILED;
+   }
+   schUlHqDeleteFromFreeList(tmp);
+   schUlHqAddToInUseList(tmp);
+   *hqP = tmp;
+   (*hqP)->maxHqTxPerHqP = ueCb->ulHqEnt.maxHqTx;
+   return ROK;
+}
+/**
+ * @brief Release Harq process from the UL Harq entity
+ *
+ * @details
+ *
+ *     Function : schUlReleaseHqProcess
+ *      
+ *      This function releases Harq process from UL Harq entity
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @param[in]  Bool togNdi, indication to togle NDI bit
+ *  @return  
+ *      -# void
+ **/
+void schUlReleaseHqProcess(SchUlHqProcCb *hqP, Bool togNdi)
+{
+   if (togNdi == TRUE)
+   {
+      hqP->tbInfo.ndi ^= 1;
+   }
+   cmLListDeleteLList(&hqP->ulLcPrbEst.dedLcList);
+   cmLListDeleteLList(&hqP->ulLcPrbEst.defLcList);
+   schUlHqDeleteFromInUseList(hqP);
+   schUlHqAddToFreeList(hqP);
+}
+/**
+ * @brief Handles NACK for UL Harq process
+ *
+ * @details
+ *
+ *     Function : schUlHqProcessNack
+ *      
+ *      This function handle NACK for  UL Harq process
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqProcessNack(SchUlHqProcCb *hqP)
+{
+   if (hqP->tbInfo.txCntr < hqP->maxHqTxPerHqP)
+   {
+      cmLListAdd2Tail(&(hqP->hqEnt->ue->ulRetxHqList), &hqP->ulHqProcLink);
+      addUeToBeScheduled(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
+   }
+   else
+   {
+      schUlReleaseHqProcess(hqP, TRUE);
+   }
+}
+/**
+ * @brief Handles ACK for UL Harq process
+ *
+ * @details
+ *
+ *     Function : schUlHqProcessAck
+ *      
+ *      This function handles ACK for UL Harq process
+ *           
+ *  @param[in]  SchUlHqProcCb *hqP, UL harq process pointer
+ *  @return  
+ *      -# void
+ **/
+void schUlHqProcessAck(SchUlHqProcCb *hqP)
+{
+   schUlReleaseHqProcess(hqP, TRUE);
+}
+/**********************************************************************
+  End of file
+ **********************************************************************/
\ No newline at end of file
index 2f3f4f9..162ed15 100644 (file)
@@ -388,6 +388,7 @@ void createSchRaCb(SchRaReq *raReq, Inst schInst)
          schCb[schInst].cells[schInst]->numActvUe++;
          SET_ONE_BIT(raReq->ueCb->ueId, schCb[schInst].cells[schInst]->actvUeBitMap);
          raReq->ueCb->state = SCH_UE_STATE_ACTIVE;
+         schCb[schInst].cells[schInst]->raCb[ueId -1].raState = SCH_RA_STATE_MSG4_DONE;
       }
    }
    else
@@ -396,7 +397,9 @@ void createSchRaCb(SchRaReq *raReq, Inst schInst)
       GET_UE_ID(raReq->rachInd->crnti, ueId);
       schCb[schInst].cells[schInst]->raCb[ueId -1].tcrnti = raReq->rachInd->crnti;
       schCb[schInst].cells[schInst]->raCb[ueId -1].msg4recvd = FALSE;
+      schCb[schInst].cells[schInst]->raCb[ueId -1].raState = SCH_RA_STATE_MSG3_PENDING;
    }
+   schCb[schInst].cells[schInst]->raCb[ueId -1].cell = schCb[schInst].cells[schInst];
 }
 
 /**
@@ -414,7 +417,7 @@ void createSchRaCb(SchRaReq *raReq, Inst schInst)
  *  @param[out]  msg3NumRb
  *  @return  void
  **/
-SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, SlotTimingInfo msg3SlotTime)
+SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, SlotTimingInfo msg3SlotTime, SchUlHqProcCb* msg3HqProc, bool isRetx)
 {
    SchCellCb      *cell          = NULLP;
    SchUlSlotInfo  *schUlSlotInfo = NULLP;
@@ -456,7 +459,7 @@ SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, S
    tbSize = tbSize / 8 ; /*bits to byte conversion*/
 
    schUlSlotInfo->schPuschInfo->crnti             = crnti;
-   schUlSlotInfo->schPuschInfo->harqProcId        = SCH_HARQ_PROC_ID;
+   schUlSlotInfo->schPuschInfo->harqProcId        = msg3HqProc->procId;
    schUlSlotInfo->schPuschInfo->resAllocType      = SCH_ALLOC_TYPE_1;
    schUlSlotInfo->schPuschInfo->fdAlloc.startPrb  = startRb;
    schUlSlotInfo->schPuschInfo->fdAlloc.numPrb    = numRb;
@@ -471,7 +474,23 @@ SchPuschInfo* schAllocMsg3Pusch(Inst schInst, uint16_t crnti, uint8_t k2Index, S
    schUlSlotInfo->schPuschInfo->dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
    schUlSlotInfo->schPuschInfo->nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
    schUlSlotInfo->schPuschInfo->dmrsAddPos        = DMRS_ADDITIONAL_POS;
-
+   if(!isRetx)
+   {
+      msg3HqProc->strtSymbl = startSymb;
+      msg3HqProc->numSymbl = symbLen;
+      msg3HqProc->puschResType = schUlSlotInfo->schPuschInfo->resAllocType;
+      msg3HqProc->puschStartPrb = schUlSlotInfo->schPuschInfo->fdAlloc.startPrb;
+      msg3HqProc->puschNumPrb = schUlSlotInfo->schPuschInfo->fdAlloc.numPrb;
+      msg3HqProc->tbInfo.qamOrder = schUlSlotInfo->schPuschInfo->tbInfo.qamOrder;
+      msg3HqProc->tbInfo.iMcs = schUlSlotInfo->schPuschInfo->tbInfo.mcs;
+      msg3HqProc->tbInfo.mcsTable = schUlSlotInfo->schPuschInfo->tbInfo.mcsTable;
+      msg3HqProc->tbInfo.ndi = schUlSlotInfo->schPuschInfo->tbInfo.ndi;
+      msg3HqProc->tbInfo.rv = schUlSlotInfo->schPuschInfo->tbInfo.rv;
+      msg3HqProc->tbInfo.tbSzReq = schUlSlotInfo->schPuschInfo->tbInfo.tbSize;
+      msg3HqProc->dmrsMappingType = schUlSlotInfo->schPuschInfo->dmrsMappingType;
+      msg3HqProc->nrOfDmrsSymbols = schUlSlotInfo->schPuschInfo->nrOfDmrsSymbols;
+      msg3HqProc->dmrsAddPos = schUlSlotInfo->schPuschInfo->dmrsAddPos;
+   }
    return schUlSlotInfo->schPuschInfo;
 }
 
@@ -539,7 +558,7 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin
    SchK0K1TimingInfoTbl *k0K1InfoTbl=NULLP;    
    SchK2TimingInfoTbl   *msg3K2InfoTbl=NULLP;
    RaRspWindowStatus    windowStatus=0;
-
+   
 #ifdef NR_TDD
    totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod);
 #endif
@@ -683,12 +702,12 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin
       if(cell->raReq[ueId-1]->isCFRA)
       {
          /* Allocate resources for PUCCH */
-         schAllocPucchResource(cell, pucchTime, cell->raReq[ueId-1]->rachInd->crnti);
+         schAllocPucchResource(cell, pucchTime, cell->raReq[ueId-1]->rachInd->crnti,NULLP, FALSE, NULLP);
       }
       else
       {
          /* Allocate resources for msg3 */
-         msg3PuschInfo = schAllocMsg3Pusch(schInst, cell->raReq[ueId-1]->rachInd->crnti, k2Index, msg3Time);
+         msg3PuschInfo = schAllocMsg3Pusch(schInst, cell->raReq[ueId-1]->rachInd->crnti, k2Index, msg3Time, &(cell->raCb[ueId-1].msg3HqProc), FALSE);
          if(msg3PuschInfo)
          {
             dciSlotAlloc->rarInfo.ulGrant.bwpSize = cell->cellCfg.schInitialUlBwp.bwp.freqAlloc.numPrb;
@@ -1055,7 +1074,23 @@ uint8_t MacSchRachRsrcRel(Pst *pst, SchRachRsrcRel *schRachRsrcRel)
    SCH_FREE(schRachRsrcRel, sizeof(SchRachRsrcRel));
    return ret;
 }
-
+ /* @brief process MSG4 completion
+ *
+ * @details
+ *
+ *     Function : schMsg4Complete
+ *     
+ *     This function updates ra state and msg4 Hqrq 
+ *     proc upon MSG4 completion     
+ *  @param[in]  SchUeCb *ueCb, UE cb pointer
+ *  @return     VOID
+ */
+void schMsg4Complete(SchUeCb *ueCb)
+{
+   DU_LOG("\nINFO --> SCH: State change for ueId[%2d] to SCH_RA_STATE_MSG4_DONE\n",ueCb->ueId);
+   ueCb->cellCb->raCb[ueCb->ueId-1].raState = SCH_RA_STATE_MSG4_DONE;
+   ueCb->msg4Proc = ueCb->retxMsg4HqProc = NULLP;
+}
 /**********************************************************************
          End of file
 **********************************************************************/
diff --git a/src/5gnrsch/sch_rr.c b/src/5gnrsch/sch_rr.c
new file mode 100644 (file)
index 0000000..a6c52e2
--- /dev/null
@@ -0,0 +1,180 @@
+/*******************************************************************************
+################################################################################
+#   Copyright (c) [2017-2019] [Radisys]                                        #
+#                                                                              #
+#   Licensed under the Apache License, Version 2.0 (the "License");            #
+#   you may not use this file except in compliance with the License.           #
+#   You may obtain a copy of the License at                                    #
+#                                                                              #
+#       http://www.apache.org/licenses/LICENSE-2.0                             #
+#                                                                              #
+#   Unless required by applicable law or agreed to in writing, software        #
+#   distributed under the License is distributed on an "AS IS" BASIS,          #
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
+#   See the License for the specific language governing permissions and        #
+#   limitations under the License.                                             #
+################################################################################
+ *******************************************************************************/
+#include "common_def.h"
+#include "tfu.h"
+#include "lrg.h"
+#include "tfu.x"
+#include "lrg.x"
+#include "du_log.h"
+#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "sch.h"
+#include "sch_utils.h"
+/**
+ * @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;
+#ifdef NR_TDD
+   uint8_t   totalCfgSlot = 0;
+#endif
+   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);
+#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);
+#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
+ **********************************************************************/
\ No newline at end of file
index dcebee1..7c08cf3 100644 (file)
@@ -234,12 +234,18 @@ PduTxOccsaion schCheckSib1Occ(SchCellCb *cell, SlotTimingInfo slotTime)
  *    Functionality:
  *       find correct combination of k0-k1 value
  *
- * @params[in]
+ * @params[in] SchCellCb *cell, SlotTimingInfo currTime
+ * @params[in] uint8_t ueId, bool dedMsg
+ * @params[in] uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen
+ * @params[in] SlotTimingInfo *pdcchTime, SlotTimingInfo *pdschTime
+ * @params[in] SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP
  * @return ROK     - success
  *         RFAILED - failure
  *
  *******************************************************************/
-bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg, uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime,  SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime)
+bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg,
+                        uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime,
+                        SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP)
 {
    uint8_t numK0 = 0, k0TblIdx = 0, k0Val = 0, k0Index =0 ;
    uint8_t k1TblIdx = 0, k1Index = 0, k1Val = 0, numK1 = 0;
@@ -331,6 +337,10 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId,
          return true;
       }
    }
+   /*
+    * Number of symbols in case of retransmisson should be same as it was in
+    * original transmisson. Symbol availablity checks need to be added.
+    */
    return false;
 }
 
@@ -345,12 +355,13 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId,
  *    Functionality:
  
  *
- * @params[in] 
+ * @params[in] SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId
+ * @params[in] bool isRetx, SchDlHqProcCb **hqP
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
-bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId)
+bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool isRetx, SchDlHqProcCb **hqP)
 {
    uint8_t lcIdx = 0;
    uint8_t pdschNumSymbols = 0, pdschStartSymbol = 0;
@@ -361,24 +372,32 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t
    CmLListCp *lcLL = NULLP;
    DlMsgAlloc *dciSlotAlloc, *dlMsgAlloc;
    SlotTimingInfo pdcchTime, pdschTime, pucchTime;
+   uint16_t rsvdDedicatedPRB = 0;
 
    /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size
     * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated.
     * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead
     * else if only Default list is present then first node in this List will add this overhead len*/
    bool isTxPayloadLenAdded = FALSE;
-
    GET_CRNTI(crnti,ueId);
    ueCb = &cell->ueCb[ueId-1];
 
+   if (isRetx == FALSE)
+   {
+      if(schDlGetAvlHqProcess(cell, ueCb, hqP) != ROK)
+      {
+         return false;
+      }
+   }
+
    if(findValidK0K1Value(cell, currTime, ueId, ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1TblPrsnt,\
-            &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, &pucchTime) != true )
+            &pdschStartSymbol, &pdschNumSymbols, &pdcchTime, &pdschTime, &pucchTime, isRetx, *hqP) != true )
    {
       /* If a valid combination of slots to scheduled PDCCH, PDSCH and PUCCH is
        * not found, do not perform resource allocation. Return from here. */
       return false;
    }
-
+   
    /* allocate PDCCH and PDSCH resources for the ue */
    if(cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId-1] == NULL)
    {
@@ -398,66 +417,69 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t
       dciSlotAlloc = cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1];
    }
    /* Dl ded Msg info is copied, this was earlier filled in macSchDlRlcBoInfo */
-   fillDlMsgInfo(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].dlMsgInfo, dciSlotAlloc->crnti);
+   fillDlMsgInfo(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].dlMsgInfo, dciSlotAlloc->crnti, isRetx, *hqP);
+   dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].isRetx = isRetx;
 
-   /*Re-Initalization per UE*/
-   /* scheduled LC data fill */
-   dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].numLc = 0;
-   isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
-   accumalatedSize = 0;
 
-   for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+   if (isRetx == FALSE)
    {
-      if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
-      {
-         /*Check the LC is Dedicated or default and accordingly LCList will
-          * be used*/
-         if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
-         {
-            lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
-         }
-         else
-         {
-            lcLL = &(ueCb->dlLcPrbEst.defLcList);
-         }
+      /*Re-Initalization per UE*/
+      /* scheduled LC data fill */
+      dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].numLc = 0;
+      isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
+      accumalatedSize = 0;
 
-         /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
-         if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
-                  (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
+      for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
+      {
+         if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
          {
-            DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
-            /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
-            if(dciSlotAlloc->numSchedInfo == 0)
+            /*Check the LC is Dedicated or default and accordingly LCList will
+            * be used*/
+            if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
             {
-               SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
-               cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
+               lcLL = &((*hqP)->dlLcPrbEst.dedLcList);
+               rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
             }
             else
-               memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
-            return false;
-         }
-      }
-      ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
-   }//End of for loop
+            {
+               lcLL = &((*hqP)->dlLcPrbEst.defLcList);
+            }
 
+            /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
+            if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
+                     (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
+            {
+               DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
+               /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+               if(dciSlotAlloc->numSchedInfo == 0)
+               {
+                  SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+                  cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
+               }
+               else
+                  memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+               return false;
+            }
+         }
+         ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
+      }//End of for loop
+      if (((*hqP)->dlLcPrbEst.defLcList.count == 0) && ( ((*hqP)->dlLcPrbEst.dedLcList.count == 0)))
+      {
+         DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
+         UNSET_ONE_BIT(ueId, cell->boIndBitMap);
 
-   if ((ueCb->dlLcPrbEst.defLcList.count == 0) && \
-         ((ueCb->dlLcPrbEst.dedLcInfo == NULL) || (ueCb->dlLcPrbEst.dedLcInfo->dedLcList.count == 0)))
-   {
-      DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
-      UNSET_ONE_BIT(ueId, cell->boIndBitMap);
+         /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
+         if(dciSlotAlloc->numSchedInfo == 0)
+         {
+            SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
+            cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
+         }
+         else
+            memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
 
-      /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
-      if(dciSlotAlloc->numSchedInfo == 0)
-      {
-         SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
-         cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
+         /*TRUE because this UE has nothing to be scheduled*/
+         return true;
       }
-      else
-         memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
-
-      /*TRUE because this UE has nothing to be scheduled*/
-      return true;
    }
 
    /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
@@ -468,40 +490,50 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t
 
    /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
     * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
-   if(maxFreePRB != 0)
+   if(isRetx == FALSE)
    {
-      mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
-      if((ueCb->dlLcPrbEst.dedLcInfo == NULLP) 
-            || ((maxFreePRB <  ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB)))
-      { 
-         ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB;
-         DU_LOG("\nDEBUG  --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
-               ueCb->dlLcPrbEst.sharedNumPrb);
-
-         /*PRB Alloc for Default LCs*/
-         prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
-               &(ueCb->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
-      }
-      else
+      if(maxFreePRB != 0)
       {
-         ueCb->dlLcPrbEst.sharedNumPrb = maxFreePRB - ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB;
-
-         /*PRB Alloc for Dedicated LCs*/
-         prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
-               &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
-
-         /*PRB Alloc for Default LCs*/
-         prbAllocUsingRRMPolicy(&(ueCb->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
-               &(ueCb->dlLcPrbEst.sharedNumPrb), &(ueCb->dlLcPrbEst.dedLcInfo->rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
+         mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
+
+         if(((*hqP)->dlLcPrbEst.dedLcList.count == NULLP) 
+               || ((maxFreePRB < rsvdDedicatedPRB)))
+         { 
+            (*hqP)->dlLcPrbEst.sharedNumPrb = maxFreePRB;
+            DU_LOG("\nDEBUG  --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
+                  (*hqP)->dlLcPrbEst.sharedNumPrb);
+
+            /*PRB Alloc for Default LCs*/
+            prbAllocUsingRRMPolicy(&((*hqP)->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
+                  &((*hqP)->dlLcPrbEst.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
+         }
+         else
+         {
+            (*hqP)->dlLcPrbEst.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
+            /*PRB Alloc for Dedicated LCs*/
+            prbAllocUsingRRMPolicy(&((*hqP)->dlLcPrbEst.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
+                  &((*hqP)->dlLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
+
+            /*PRB Alloc for Default LCs*/
+            prbAllocUsingRRMPolicy(&((*hqP)->dlLcPrbEst.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
+                  &((*hqP)->dlLcPrbEst.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
+         }
       }
    }
 
    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
-    * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ 
-   if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
-      updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.dedLcInfo->dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
+    * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/
+   if (isRetx == FALSE)
+   {
+      if((*hqP)->dlLcPrbEst.dedLcList.count != 0)
+         updateGrantSizeForBoRpt(&((*hqP)->dlLcPrbEst.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
 
-   updateGrantSizeForBoRpt(&(ueCb->dlLcPrbEst.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
+      updateGrantSizeForBoRpt(&((*hqP)->dlLcPrbEst.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
+   }
+   else
+   {
+      accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
+   }
 
    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
    if (!accumalatedSize)
@@ -521,7 +553,7 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t
    }
 
    /*[Step6]: pdcch and pdsch data is filled */
-   if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols)) != ROK)
+   if((schDlRsrcAllocDlMsg(cell, pdschTime, crnti, accumalatedSize, dciSlotAlloc, startPrb, pdschStartSymbol, pdschNumSymbols, isRetx, *hqP)) != ROK)
    {
       DU_LOG("\nERROR  --> SCH : Scheduling of DL dedicated message failed");
 
@@ -532,7 +564,9 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t
          cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueId -1] = NULL;
       }
       else
+      {
          memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
+      }
       return false;
    }
 
@@ -596,14 +630,14 @@ bool schFillBoGrantDlSchedInfo(SchCellCb *cell, SlotTimingInfo currTime, uint8_t
       dlMsgAlloc->numSchedInfo++;
    }
 
-   schAllocPucchResource(cell, pucchTime, crnti);
+   schAllocPucchResource(cell, pucchTime, crnti, ueCb, isRetx, *hqP);
+
    cell->schDlSlotInfo[pdcchTime.slot]->pdcchUe = ueId;
    cell->schDlSlotInfo[pdschTime.slot]->pdschUe = ueId;
    cell->schUlSlotInfo[pucchTime.slot]->pucchUe = ueId;
 
    /* after allocation is done, unset the bo bit for that ue */
    UNSET_ONE_BIT(ueId, cell->boIndBitMap);
    return true;
 }
 
@@ -732,10 +766,13 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
    bool      isMsg4Pending = false, isMsg4Scheduled = false;
    bool      isUlGrantPending = false, isUlGrantScheduled = false;
    bool      isDlMsgPending = false, isDlMsgScheduled = false;
-   CmLList       *pendingUeNode;
-   DlSchedInfo   dlSchedInfo;
-   DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
-   SchCellCb     *cell = NULLP;
+   CmLList        *pendingUeNode;
+   DlSchedInfo    dlSchedInfo;
+   DlBrdcstAlloc  *dlBrdcstAlloc = NULLP;
+   SchCellCb      *cell = NULLP;
+   CmLList        *node;
+   uint8_t*       ueNode;
+   SchDlHqProcCb  *hqP = NULLP, *ulHqP = NULLP;
 
    memset(&dlSchedInfo, 0, sizeof(DlSchedInfo));
    schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue);
@@ -798,8 +835,8 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
    {
       if(pendingUeNode->node)
       {
+         ueNode = (uint8_t *)pendingUeNode->node;
          ueId = *(uint8_t *)(pendingUeNode->node);
-
          /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and 
           * PUSCH to receive MSG3 as per k0-k2 configuration*/
          if(cell->raReq[ueId-1] != NULLP)
@@ -808,12 +845,34 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
             isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
          }
 
+         /*MSG3 retransmisson*/
+         if(cell->raCb[ueId-1].retxMsg3HqProc)
+         {            
+            schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
+         }
+
          /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
           * PUCCH to receive UL msg as per k0-k1 configuration  */
-         if(cell->raCb[ueId-1].msg4recvd)
+         if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
          {
+            /* Retransmission of MSG4 */
             isMsg4Pending = true;
-            isMsg4Scheduled = schProcessMsg4Req(cell, *slotInd, ueId);
+            if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
+               isMsg4Scheduled = true;
+         }
+         else
+         {
+            /* First transmission of MSG4 */
+            if(cell->raCb[ueId-1].msg4recvd)
+            {
+               isMsg4Pending = true;
+               if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4Proc) == ROK)
+                  isMsg4Scheduled = true;
+
+               /* If MSG4 scheduling failed, free the newly assigned HARQ process */
+               if(!isMsg4Scheduled)
+                  schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4Proc);
+            }
          }
 
          if(isRarPending || isMsg4Pending)
@@ -827,23 +886,56 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
             }
             /* If RAR/MSG4 is pending but couldnt be scheduled then,
              * put this UE at the end of linked list to be scheduled later */
-            else 
+            else
             {
                cmLListAdd2Tail(&cell->ueToBeScheduled, cmLListDelFrm(&cell->ueToBeScheduled, pendingUeNode));
             }
          }
 
-         if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
+         /* DL Data */
+         node = cell->ueCb[ueId-1].dlRetxHqList.first;
+         if(node != NULLP)
          {
-            isUlGrantPending = true;
-            isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId);
+            /* DL Data ReTransmisson */
+            isDlMsgPending = true;
+            isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
+            cmLListDelFrm(&cell->ueCb[ueId-1].dlRetxHqList, node);
          }
+         else
+         {
+            /* DL Data new transmission */
+            if((cell->boIndBitMap) & (1<<ueId))
+            {
+               isDlMsgPending = true;               
+               isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
 
-         if((cell->boIndBitMap) & (1<<ueId))
+               /* If DL scheduling failed, free the newly assigned HARQ process */
+               if(!isDlMsgScheduled)
+                  schDlReleaseHqProcess(hqP);
+            }
+         }
+
+         /* Scheduling of UL grant */
+         node = cell->ueCb[ueId-1].ulRetxHqList.first;
+         if(node != NULLP)
          {
-            isDlMsgPending = true;
-            isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId);
+            /* UL Data ReTransmisson */
+            isUlGrantPending = true;
+            isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
+            cmLListDelFrm(&cell->ueCb[ueId-1].ulRetxHqList, node);
+         }
+         else
+         {
+            /* UL Data new transmission */
+            if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
+            {
+               isUlGrantPending = true;
+               isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
+               if(!isUlGrantScheduled)
+                  schUlReleaseHqProcess(ulHqP, FALSE);
+            }
          }
+
          if(!isUlGrantPending && !isDlMsgPending)
          {
             /* No action required */  
@@ -854,7 +946,7 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
          }
          else
          {
-            SCH_FREE(pendingUeNode->node, sizeof(uint8_t));
+            SCH_FREE(ueNode, sizeof(uint8_t));
             deleteNodeFromLList(&cell->ueToBeScheduled, pendingUeNode);
          }
       }
@@ -880,7 +972,6 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst)
          dlSchedInfo.dlMsgAlloc[ueIdx] = cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx];
          cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx] = NULLP;
       }
-
    }
 
    if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.ulDciTime.slot]->ulGrant != NULLP)
index 3db4b1c..8ca3bac 100644 (file)
@@ -192,7 +192,7 @@ void fillSchUlLcCtxt(SchUlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg)
  *
  * ****************************************************************/
 
-uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, SchLcPrbEstimate *lcPrbEst, bool *isDedicated)
+uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, uint16_t *rsvdDedicatedPRB, bool *isDedicated)
 {
    uint8_t sliceCfgIdx =0;
    SchSliceCfg sliceCfg = schCb[inst].sliceCfg;
@@ -203,22 +203,13 @@ uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, SchLcPrbEstimate *lcPrbEst, b
       {
          if(memcmp(snssai, &(sliceCfg.listOfConfirguration[sliceCfgIdx]->snssai), sizeof(Snssai)) == 0)
          {
-            if(lcPrbEst->dedLcInfo == NULLP)
-            {
-               SCH_ALLOC(lcPrbEst->dedLcInfo, sizeof(DedicatedLCInfo));
-               if(lcPrbEst->dedLcInfo == NULLP)
-               {
-                  DU_LOG("\nINFO  -->  SCH : Memory Allocation Failed");
-                  return RFAILED;
-               }
-            }
             if(sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo)
             {
                /*Updating latest RrmPolicy*/
-               lcPrbEst->dedLcInfo->rsvdDedicatedPRB = \
+                *rsvdDedicatedPRB = \
                (uint16_t)(((sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo->policyDedicatedRatio)*(MAX_NUM_RB))/100);
                *isDedicated = TRUE;
-               DU_LOG("\nINFO  -->  SCH : Updated RRM policy, reservedPOOL:%d",lcPrbEst->dedLcInfo->rsvdDedicatedPRB);
+               DU_LOG("\nINFO  -->  SCH : Updated RRM policy, reservedPOOL:%d",*rsvdDedicatedPRB);
             }
          }
       }
@@ -250,11 +241,10 @@ uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, SchLcPrbEstimate *lcPrbEst, b
 
 uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
 {
-   uint8_t   lcIdx, ueLcIdx;
+   uint8_t   lcIdx, ueLcIdx, idx;
    uint8_t   freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0};
    SchPdschCfgCmn pdschCfg;
    SchPucchDlDataToUlAck *dlDataToUlAck;
-   CmLListCp *lcLL = NULLP;
    uint8_t retDL = ROK, retUL = ROK;
    bool isLcIdValid = FALSE;
 
@@ -280,7 +270,7 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
       {
          if(ueCb->ueCfg.spCellCfgPres && ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true)
          {
-            for(uint8_t idx = 0; idx < ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++)
+            for(idx = 0; idx < ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++)
             {
                if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0 && ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0)
                {
@@ -321,7 +311,6 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
    }
    memcpy(&ueCb->ueCfg.dlModInfo,  &ueCfg->dlModInfo , sizeof(SchModulationInfo));
    memcpy(&ueCb->ueCfg.ulModInfo,  &ueCfg->ulModInfo , sizeof(SchModulationInfo));
-
    //Updating SchUlCb and SchDlCb DB in SchUeCb
    for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++)
    {
@@ -343,12 +332,12 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
           * and Create the Dedicated LC List & Update the Reserve PRB number*/
          if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
          {
-            retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlLcPrbEst),\
+            retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
                   &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
          }
          if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
          {
-            retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulLcPrbEst),\
+            retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
                   &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
          }
 
@@ -368,7 +357,7 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
                /*Updating the RRM reserved pool PRB count*/
                if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
                {
-                  retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulLcPrbEst),\
+                  retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
                         &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
                }
                if(retUL == RFAILED)
@@ -382,21 +371,11 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
                /*Delete the LC node from the UL LC List*/
                if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)
                {
-                  if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
-                  {
-                     lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList);
-                     handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
-                     if(lcLL->count == 0)/*IF No Node in DedicateLCList to be deleted*/
-                     {
-                        /*Free the Dedicated LC Info structure*/
-                        SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
-                     }
-                  }
+                   /*Remove from HARQ Transmission or retransmission*/
                }
                else/*Default LC list*/
                {
-                  lcLL = &(ueCb->ulLcPrbEst.defLcList);
-                  handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
+
                }
                SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
                memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt));
@@ -411,7 +390,7 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
                /*Updating the RRM policy*/
                if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
                {
-                  retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlLcPrbEst), \
+                  retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB), \
                         &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
                }
                if(retDL == RFAILED)
@@ -425,21 +404,10 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
                /*Delete the LC node from the DL LC List*/
                if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)
                {
-                  if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
-                  {
-                     lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
-                     handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
-                     if(lcLL->count == 0)/*Last Node in DedicateLCList to be deleted*/
-                     {
-                        /*Free the Dedicated LC Info structure*/
-                        SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
-                     }
-                  }
+                  /*Remove from HARQ Transmission or retransmission*/
                }
                else
                {
-                  lcLL = &(ueCb->dlLcPrbEst.defLcList);
-                  handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
                }
                SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
                memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt));
@@ -519,7 +487,7 @@ SchCellCb *getSchCellCb(uint16_t srcEvent, Inst inst, SchUeCfg *ueCfg)
  * ****************************************************************/
 uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg)
 {
-   uint8_t      lcIdx = 0, ret = ROK;
+   uint8_t      lcIdx = 0, ret = ROK, idx = 0;
    SchCellCb    *cellCb = NULLP;
    SchUeCb      *ueCb = NULLP;
    SchUeCfgRsp  cfgRsp;
@@ -550,10 +518,35 @@ uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg)
 
    /* Fill received Ue Configuration in UeCb */
    memset(ueCb, 0, sizeof(SchUeCb));
+
    ueCb->ueId = ueCfg->ueId;
    ueCb->crnti = ueCfg->crnti;
+   ueCb->cellCb = cellCb;
+   schUlHqEntInit(cellCb, &cellCb->ueCb[ueCfg->ueId-1]);
+   schDlHqEntInit(cellCb, &cellCb->ueCb[ueCfg->ueId-1]);
+   SCH_ALLOC(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots));
+   SCH_ALLOC(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots));
 
+   if ( (ueCb->hqDlmap == NULLP) || (ueCb->hqUlmap == NULLP) )
+   {
+      DU_LOG("\nINFO  -->  SCH : Memory Allocation Failed");
+      return RFAILED;
+   }
+   for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
+   {
+      SCH_ALLOC(ueCb->hqDlmap[idx], sizeof(SchHqDlMap));
+      SCH_ALLOC(ueCb->hqUlmap[idx], sizeof(SchHqUlMap));
+      
+      if ( (ueCb->hqDlmap[idx] == NULLP) || (ueCb->hqUlmap[idx] == NULLP) )
+      {
+         DU_LOG("\nINFO  -->  SCH : Memory Allocation Failed");
+         return RFAILED;
+      }
+      cmLListInit(&ueCb->hqDlmap[idx]->hqList);
+      cmLListInit(&ueCb->hqUlmap[idx]->hqList);
+   }
    ret = fillSchUeCb(inst, ueCb, ueCfg);
+
    if(ret == ROK)
    {
       /* If UE has initiated RACH and then UE context is created, it means UE is
@@ -571,7 +564,6 @@ uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg)
          ueCb->state = SCH_UE_HANDIN_IN_PROGRESS;
       }
 
-      ueCb->cellCb = cellCb;
       ueCb->srRcvd = false;
       ueCb->bsrRcvd = false;
       for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
@@ -592,13 +584,15 @@ uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg)
 *
 *    Functionality: fills PUSCH info
 *
-* @params[in]
+* @params[in] SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize
+* @params[in] uint8_t startSymb, uint8_t symbLen, uint16_t startPrb
+* @params[in] bool isRetx, SchUlHqProcCb *hq
 * @return ROK     - success
 *         RFAILED - failure
 *
 * ****************************************************************/
 uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize, 
-                            uint8_t startSymb, uint8_t symbLen, uint16_t startPrb)
+                          uint8_t startSymb, uint8_t symbLen, uint16_t startPrb, bool isRetx, SchUlHqProcCb *hqP)
 {
   uint8_t  numRb          = 0;
   SchCellCb *cellCb       = NULLP;
@@ -622,23 +616,60 @@ uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSi
   numRb   = schCalcNumPrb(tbSize, ueCb->ueCfg.ulModInfo.mcsIndex, symbLen);
   allocatePrbUl(cellCb, puschTime, startSymb, symbLen, &startPrb, numRb);
 
-  puschInfo.crnti             = ueCb->crnti; 
-  puschInfo.harqProcId        = SCH_HARQ_PROC_ID;
-  puschInfo.resAllocType      = SCH_ALLOC_TYPE_1;
-  puschInfo.fdAlloc.startPrb  = startPrb;
-  puschInfo.fdAlloc.numPrb    = numRb;
-  puschInfo.tdAlloc.startSymb = startSymb;
-  puschInfo.tdAlloc.numSymb   = symbLen;
-  puschInfo.tbInfo.qamOrder   = ueCb->ueCfg.ulModInfo.modOrder;
-  puschInfo.tbInfo.mcs        = ueCb->ueCfg.ulModInfo.mcsIndex;
-  puschInfo.tbInfo.mcsTable   = ueCb->ueCfg.ulModInfo.mcsTable;
-  puschInfo.tbInfo.ndi        = 1; /* new transmission */
-  puschInfo.tbInfo.rv         = 0;
-  puschInfo.tbInfo.tbSize     = tbSize;
-  puschInfo.dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
-  puschInfo.nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
-  puschInfo.dmrsAddPos        = DMRS_ADDITIONAL_POS;
-
+   if (isRetx == FALSE)
+   {
+      puschInfo.crnti             = ueCb->crnti;
+      puschInfo.harqProcId        = SCH_HARQ_PROC_ID;
+      puschInfo.resAllocType      = SCH_ALLOC_TYPE_1;
+      puschInfo.fdAlloc.startPrb  = startPrb;
+      puschInfo.fdAlloc.numPrb    = numRb;
+      puschInfo.tdAlloc.startSymb = startSymb;
+      puschInfo.tdAlloc.numSymb   = symbLen;
+      puschInfo.tbInfo.qamOrder   = ueCb->ueCfg.ulModInfo.modOrder;
+      puschInfo.tbInfo.mcs        = ueCb->ueCfg.ulModInfo.mcsIndex;
+      puschInfo.tbInfo.mcsTable   = ueCb->ueCfg.ulModInfo.mcsTable;
+      puschInfo.tbInfo.ndi        = 1; /* new transmission */
+      puschInfo.tbInfo.rv         = 0;
+      puschInfo.tbInfo.tbSize     = tbSize;
+      puschInfo.dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
+      puschInfo.nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
+      puschInfo.dmrsAddPos        = DMRS_ADDITIONAL_POS;
+      hqP->puschResType = puschInfo.resAllocType;
+      hqP->puschStartPrb = puschInfo.fdAlloc.startPrb;
+      hqP->puschNumPrb = puschInfo.fdAlloc.numPrb;
+      hqP->strtSymbl = puschInfo.tdAlloc.startSymb;
+      hqP->numSymbl = puschInfo.tdAlloc.numSymb;
+      hqP->tbInfo.qamOrder = puschInfo.tbInfo.qamOrder;
+      hqP->tbInfo.iMcs = puschInfo.tbInfo.mcs;
+      hqP->tbInfo.mcsTable = puschInfo.tbInfo.mcsTable;
+      hqP->tbInfo.ndi = puschInfo.tbInfo.ndi;
+      hqP->tbInfo.rv = puschInfo.tbInfo.rv;
+      hqP->tbInfo.rvIdx = 0;
+      hqP->tbInfo.tbSzReq = puschInfo.tbInfo.tbSize;
+      hqP->dmrsMappingType = puschInfo.dmrsMappingType;
+      hqP->nrOfDmrsSymbols = puschInfo.nrOfDmrsSymbols;
+      hqP->dmrsAddPos = puschInfo.dmrsAddPos;
+   }
+   else
+   {
+      puschInfo.crnti             = ueCb->crnti;
+      puschInfo.harqProcId        = hqP->procId;
+      puschInfo.resAllocType      = hqP->puschResType;
+      puschInfo.fdAlloc.startPrb  = hqP->puschStartPrb;
+      puschInfo.fdAlloc.numPrb    = hqP->puschNumPrb;
+      puschInfo.tdAlloc.startSymb = hqP->strtSymbl;
+      puschInfo.tdAlloc.numSymb   = hqP->numSymbl;
+      puschInfo.tbInfo.qamOrder   = hqP->tbInfo.qamOrder;
+      puschInfo.tbInfo.mcs        = hqP->tbInfo.iMcs;
+      puschInfo.tbInfo.mcsTable   = hqP->tbInfo.mcsTable;
+      puschInfo.tbInfo.ndi        = hqP->tbInfo.ndi; /* retransmission */
+      hqP->tbInfo.rvIdx = (hqP->tbInfo.rvIdx +1) & 0x3;
+      puschInfo.tbInfo.rv         = schCmnDlRvTbl[hqP->tbInfo.rvIdx];
+      puschInfo.tbInfo.tbSize     = hqP->tbInfo.tbSzReq;
+      puschInfo.dmrsMappingType   = hqP->dmrsMappingType;  /* Setting Type-A */
+      puschInfo.nrOfDmrsSymbols   = hqP->nrOfDmrsSymbols;
+      puschInfo.dmrsAddPos        = hqP->dmrsAddPos;
+   }
   schUlSlotInfo = cellCb->schUlSlotInfo[puschTime.slot];
   SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
   if(!schUlSlotInfo->schPuschInfo)
@@ -650,6 +681,110 @@ uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSi
 
   return ROK;
 }
+/*******************************************************************
+*
+* @brief Fills UL DCI information for MSG3 retransmission
+*
+* @details
+*
+*    Function : schFillUlDciForMsg3Retx
+*
+*    Functionality: fills UL DCI information for MSG3 retransmission
+*
+* @params[in]
+* @return ROK     - success
+*         RFAILED - failure
+*
+* ****************************************************************/
+uint8_t schFillUlDciForMsg3Retx(SchRaCb *raCb, SchPuschInfo *puschInfo, DciInfo *dciInfo)
+{
+   SchCellCb         *cellCb  = raCb->cell;
+   dciInfo->cellId = cellCb->cellId;
+   dciInfo->crnti  = raCb->tcrnti;
+   SchUlHqProcCb *msg3HqProc = &raCb->msg3HqProc;
+   if (msg3HqProc == NULLP)
+   {
+      return RFAILED;
+   }
+
+   /* fill bwp cfg */
+   dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
+   dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
+   dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb;
+   dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; 
+
+   /*fill coreset cfg */
+   //Considering number of RBs in coreset1 is same as coreset0
+   dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
+   //Considering coreset1 also starts from same symbol as coreset0
+   dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
+   dciInfo->coresetCfg.durationSymbols  = coresetIdxTable[0][2];
+   memcpy(dciInfo->coresetCfg.freqDomainResource, cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
+   
+   dciInfo->coresetCfg.cceRegMappingType   = 1; /* coreset0 is always interleaved */
+   dciInfo->coresetCfg.regBundleSize       = 6; /* spec-38.211 sec 7.3.2.2 */
+   dciInfo->coresetCfg.interleaverSize     = 2; /* spec-38.211 sec 7.3.2.2 */
+   dciInfo->coresetCfg.coreSetType         = 0;
+   dciInfo->coresetCfg.coreSetSize         = coresetIdxTable[0][1];
+   dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
+   dciInfo->coresetCfg.precoderGranularity = 0;
+   dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
+   dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
+   
+   dciInfo->formatType = FORMAT0_0;
+   msg3HqProc->tbInfo.rvIdx++;
+   msg3HqProc->tbInfo.rv = schCmnDlRvTbl[msg3HqProc->tbInfo.rvIdx & 0x03];
+   /* fill UL grant */
+   dciInfo->format.format0_0.resourceAllocType   = msg3HqProc->puschResType;
+   dciInfo->format.format0_0.freqAlloc.startPrb  = msg3HqProc->puschStartPrb;
+   dciInfo->format.format0_0.freqAlloc.numPrb    = msg3HqProc->puschNumPrb;
+   dciInfo->format.format0_0.timeAlloc.startSymb = msg3HqProc->strtSymbl;
+   dciInfo->format.format0_0.timeAlloc.numSymb   = msg3HqProc->numSymbl;
+   dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
+   dciInfo->format.format0_0.mcs                 = msg3HqProc->tbInfo.iMcs;
+   dciInfo->format.format0_0.harqProcId          = msg3HqProc->procId;
+   dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
+   dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
+   dciInfo->format.format0_0.ndi                 = msg3HqProc->tbInfo.ndi; /* new transmission */
+   dciInfo->format.format0_0.rv                  = msg3HqProc->tbInfo.rv;
+   dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
+   dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
+   
+   /* Fill DCI Structure */
+   dciInfo->dciInfo.rnti                              = raCb->tcrnti;
+   dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
+   dciInfo->dciInfo.scramblingRnti                    = 0;
+   dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
+   dciInfo->dciInfo.aggregLevel                       = 4;
+   dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
+   dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
+   dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
+   dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
+   dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
+   dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
+   dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
+   dciInfo->dciInfo.pdschCfg                          = NULL; /* No DL data being sent */
+   msg3HqProc->tbInfo.txCntr++;
+
+  puschInfo->crnti             = raCb->tcrnti;
+  puschInfo->harqProcId        = msg3HqProc->procId;
+  puschInfo->resAllocType      = msg3HqProc->puschResType;
+  puschInfo->fdAlloc.startPrb  = msg3HqProc->puschStartPrb;
+  puschInfo->fdAlloc.numPrb    = msg3HqProc->puschNumPrb;
+  puschInfo->tdAlloc.startSymb = msg3HqProc->strtSymbl;
+  puschInfo->tdAlloc.numSymb   = msg3HqProc->numSymbl;
+  puschInfo->tbInfo.qamOrder   = msg3HqProc->tbInfo.qamOrder;
+  puschInfo->tbInfo.mcs        = msg3HqProc->tbInfo.iMcs;
+  puschInfo->tbInfo.mcsTable   = msg3HqProc->tbInfo.mcsTable;
+  puschInfo->tbInfo.ndi        = msg3HqProc->tbInfo.ndi; /* retransmission */
+  puschInfo->tbInfo.rv         = msg3HqProc->tbInfo.rvIdx;
+  puschInfo->tbInfo.tbSize     = msg3HqProc->tbInfo.tbSzReq;
+  puschInfo->dmrsMappingType   = msg3HqProc->dmrsMappingType;  /* Setting Type-A */
+  puschInfo->nrOfDmrsSymbols   = msg3HqProc->nrOfDmrsSymbols;
+  puschInfo->dmrsAddPos        = msg3HqProc->dmrsAddPos;
+
+   return ROK;
+}
 
 /*******************************************************************
  *
@@ -661,12 +796,13 @@ uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSi
  *
  *    Functionality: fills DCI for UL grant in response to BSR
  *
- * @params[in]
+ * @params[in] SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo,
+ * @params[in] bool isRetx, SchUlHqProcCb *hqP 
  * @return ROK     - success
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo)
+uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, bool isRetx, SchUlHqProcCb *hqP)
 {
    SchCellCb         *cellCb  = ueCb->cellCb;
    SchControlRsrcSet coreset1 ;
@@ -936,7 +1072,6 @@ void deleteSchUeCb(SchUeCb *ueCb)
    uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0;
    SchPucchCfg *pucchCfg = NULLP;
    SchPdschConfig *pdschCfg = NULLP;
-   CmLListCp *lcLL  = NULLP;
 
    if(ueCb)
    {
@@ -979,26 +1114,6 @@ void deleteSchUeCb(SchUeCb *ueCb)
          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
       }
 
-      /*Clearing out Dedicated LC list*/
-      if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
-      {
-         lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
-         deleteLcLL(lcLL);
-         SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
-      }
-      if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
-      {
-         lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList);
-         deleteLcLL(lcLL);
-         SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
-      }
-      /*Deleteing the Default LC list*/
-      lcLL = &(ueCb->dlLcPrbEst.defLcList);
-      deleteLcLL(lcLL);
-
-      lcLL = &(ueCb->ulLcPrbEst.defLcList);
-      deleteLcLL(lcLL);
-
       memset(ueCb, 0, sizeof(SchUeCb));
    }
 }
@@ -1287,11 +1402,63 @@ uint8_t MacSchCellDeleteReq(Pst *pst, SchCellDelete  *cellDelete)
          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): failed to send Cell Delete response");
          ret =  RFAILED;
       }
-
    }
    return ret;   
 }
+/*******************************************************************
+ *
+ * @brief Function updates DL HARQ Feedback
+ *
+ * @details
+ *
+ *    Function : schUpdateHarqFdbk
+ *
+ *    Functionality: Function updates DL HARQ feedback
+ *
+ * @params[in] SchUeCb *ueCb, UE cb struct pointer
+ * @params[in] uint8_t numHarq, number of HARQ processes in feedback 
+ * @params[in] uint8_t *harqPayload, harq feedback payload received
+ * @params[in] SlotTimingInfo *slotInd, slot timing information
+ * @return void
+ *
+ * ****************************************************************/
+void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload, SlotTimingInfo *slotInd)
+{
+   SchDlHqProcCb *hqP;
+   SchHqDlMap *hqDlMap;
+   CmLList  *node;
+   uint8_t fdbkPos = 0;
+
+   hqDlMap = ueCb->hqDlmap[slotInd->slot];
 
+   if (ueCb->cellCb->raCb[ueCb->ueId-1].raState == SCH_RA_STATE_MSG2_HANDLE)
+   {
+      return;
+   }
+   if (ueCb->cellCb->raCb[ueCb->ueId-1].raState != SCH_RA_STATE_MSG4_PENDING)
+   {
+      node = hqDlMap->hqList.first;
+      while(node)
+      {
+         hqP = (SchDlHqProcCb*)node->node;
+         node = node->next;
+         cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
+         /* 
+            Decode harq feedback if needed post FAPI message decoding also or check how to decode this FAPI msg.
+            case 1 semi static harq Ack/Nack codebook //Supported
+            case 2 dynamic harq ACK/NACK codebook //Not supported
+         */
+         schDlHqFeedbackUpdate(hqP, harqPayload[fdbkPos++], HQ_TB_ACKED);//Marking 2nd TB as ACKED for now as only one TB to be used
+      }
+   }
+   else
+   {
+      node = hqDlMap->hqList.first;
+      hqP = (SchDlHqProcCb*)node->node;
+      cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
+      schMsg4FeedbackUpdate(hqP, harqPayload[fdbkPos++]);
+   }
+}
 /**********************************************************************
   End of file
  **********************************************************************/
index 140efc8..d77ec86 100644 (file)
@@ -773,6 +773,7 @@ uint8_t minMsg3SchTime[MAX_NUM_MU] = {6, 6, 6, 6};
 
 uint8_t defaultUlAckTbl[DEFAULT_UL_ACK_LIST_COUNT]= {1, 2, 3 , 4, 5, 6, 7, 8};
 
+uint8_t schCmnDlRvTbl[4] = {0, 2, 3, 1};
 /**
  * @brief Function to find first DMRS symbol in PDSCH
  *
@@ -1465,7 +1466,6 @@ LcInfo* handleLcLList(CmLListCp *lcLL, uint8_t lcId, ActionTypeLL action)
 uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize)
 {
    LcInfo    *lcNode = NULLP;
-
    lcNode = handleLcLList(lcLL, lcId, CREATE);
 
    if(lcNode == NULLP)
@@ -1473,8 +1473,9 @@ uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize)
       DU_LOG("\nERROR  -->  SCH : LC is neither present nor able to create in List lcId:%d",lcId);
       return RFAILED;
    }
+
    lcNode->reqBO = payloadSize;
-   lcNode->allocBO = 0; 
+   lcNode->allocBO = 0;
    lcNode->allocPRB = 0; /*Re-Initializing the AllocPRB*/
    return ROK;
 }
index 2731642..5d3d41e 100644 (file)
@@ -107,7 +107,7 @@ uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4];
 uint8_t puschDeltaTable[MAX_MU_PUSCH];
 uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8];
 uint16_t numRbForPrachTable[MAX_RACH_NUM_RB_IDX][5];
-
+uint8_t schCmnDlRvTbl[4];
 /* Functions declarations : Linked list handler */
 uint8_t addNodeToLList(CmLListCp *llist, void *blockToAdd, CmLList *currNode);
 uint8_t deleteNodeFromLList(CmLListCp *llist, CmLList *node);
index 1cc4092..e8c0251 100644 (file)
@@ -370,6 +370,32 @@ CmLListCp *list2               /*-- node to be added --*/
    return;
 } /*-- end of cmLListCatLList --*/
 
+
+/*--
+  *
+  *       Fun:   cmLListDeleteLList
+  *
+  *       Desc:  delete a linked list
+  *
+  *       Ret:   None
+  *
+  *       Notes: None
+  *
+  *       File:  cm_llist.c
+  *
+  --*/
+Void cmLListDeleteLList
+(
+CmLListCp *list              /*-- list control point --*/
+)
+{
+   while(list->count)
+   {
+      cmLListDelFrm(list, list->first);
+   }
+   return;
+}
+
 /**********************************************************************
          End of file
 **********************************************************************/
index acafe77..40e4148 100755 (executable)
@@ -64,7 +64,7 @@ Void     cmLListInsCrnt  ARGS ((CmLListCp *lList, CmLList *node));
 Void     cmLListInsAfterCrnt  ARGS ((CmLListCp *lList, CmLList *node));
 CmLList *cmLListDelFrm   ARGS ((CmLListCp *lList, CmLList *node));
 Void cmLListCatLList ARGS (( CmLListCp *list1, CmLListCp *list2));
-
+Void cmLListDeleteLList ARGS ((CmLListCp *lList));
 #ifdef __cplusplus
 }
 #endif
index 1678c8f..0ed59ee 100644 (file)
@@ -63,6 +63,8 @@
 #define MAX_NUM_SRB  3    /* Max. no of Srbs */
 #define MAX_NUM_DRB  29   /* spec 38.331, maxDRB */
 #define MAX_NUM_SSB  64   /* spec 28.331, maxNrofSSBs */
+#define MAX_NUM_HARQ_PROC 16 /* spec 38.331, nrofHARQ-ProcessesForPDSCH */
+#define MAX_NUM_TB_PER_UE 2  /* spec 38.331, maxNrofCodeWordsScheduledByDCI */
 
 /* 5G ORAN phy delay */
 #define PHY_DELTA_DL 1
index ec64f29..9d1cd0e 100644 (file)
@@ -326,6 +326,36 @@ uint8_t packMacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd)
    return ROK;
 }
 
+/*******************************************************************
+ *
+ * @brief Pack and Send HARQ UCI Ind from MAC to SCH
+ *
+ * @details
+ *
+ *    Function : packMacHarqSchUciInd
+ *
+ *    Functionality:
+ *       Pack and Send HARQ UCI Ind from MAC to SCH
+ *
+ * @params[in]
+ * @return ROK     - success
+ *         RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t packMacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd)
+{
+   if((pst->selector == ODU_SELECTOR_LC) || (pst->selector == ODU_SELECTOR_LWLC))
+   {
+      /* TODO */
+   }
+   else
+   {
+      return RFAILED;
+   }
+   return ROK;
+}
+
+
 /*******************************************************************
  *
  * @brief Pack and Send Modify UE Config Request from MAC to SCH
@@ -685,6 +715,26 @@ uint8_t packSchMacDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc)
 {
    return ROK;
 }
+
+/**
+ * @brief function to pack Harq process release message 
+ *        from SCH to MAC
+ *
+ * @details
+ *
+ *     Function : packSchMacDlReleaseHarq 
+ *     
+ *     
+ *  @param[in]  Pst *pst, the post structure     
+ *  @param[in]  SchRlsHqInfo *rlsHqInfo
+ *  @return  S16
+ *      -# ROK
+ **/
+uint8_t packSchMacDlReleaseHarq(Pst *pst, SchRlsHqInfo *rlsHqInfo)
+{
+   return ROK;
+}
+
 /**********************************************************************
   End of file
  **********************************************************************/
index ddc0410..1ab00fb 100644 (file)
@@ -46,7 +46,7 @@
 #define EVENT_RACH_RESOURCE_RELEASE_TO_SCH  27
 #define EVENT_PAGING_IND_TO_SCH      28
 #define EVENT_DL_PAGING_ALLOC        29
-
+#define EVENT_DL_REL_HQ_PROC         30 
 /*macros*/
 #define MAX_SSB_IDX 1 /* forcing it as 1 for now. Right value is 64 */
 #define SCH_SSB_MASK_SIZE   1
@@ -67,6 +67,7 @@
 #define MAX_NUMBER_OF_CRC_IND_BITS 1
 #define MAX_NUMBER_OF_UCI_IND_BITS 1
 #define MAX_SR_BITS_IN_BYTES       1
+#define MAX_HARQ_BITS_IN_BYTES     1
 #define MAX_NUM_LOGICAL_CHANNEL_GROUPS 8
 #define MAX_NUM_SR_CFG_PER_CELL_GRP 8   /* Max number of scheduling request config per cell group */
 #define MAX_NUM_TAGS 4                  /* Max number of timing advance groups */
@@ -633,6 +634,7 @@ typedef struct schRachCfg
    uint8_t      raContResTmr;      /* RA Contention Resoultion Timer */
    uint8_t      rsrpThreshSsb;     /* RSRP Threshold SSB */
    uint8_t      raRspWindow;       /* RA Response Window */
+   uint8_t      maxMsg3Tx;         /* MAximum num of msg3 tx*/
 }SchRachCfg;
 
 typedef struct schBwpParams
@@ -763,6 +765,13 @@ typedef struct schPlmnInfoList
    Snssai         **snssai;         /* List of supporting snssai*/
 }SchPlmnInfoList;
 
+typedef struct schHqCfgParam
+{
+   uint8_t maxDlDataHqTx;
+   uint8_t maxMsg4HqTx;
+   uint8_t maxUlDataHqTx;
+}SchHqCfg;
+
 typedef struct schCellCfg
 {
    uint16_t       cellId;           /* Cell Id */
@@ -778,6 +787,7 @@ typedef struct schCellCfg
    SchBwpDlCfg    schInitialDlBwp;  /* Initial DL BWP */
    SchBwpUlCfg    schInitialUlBwp;  /* Initial UL BWP */
    SchPlmnInfoList plmnInfoList;     /* Consits of PlmnId and Snssai list */
+   SchHqCfg       schHqCfg;
 #ifdef NR_TDD
    TDDCfg         tddCfg;           /* TDD Cfg */ 
 #endif  
@@ -884,6 +894,7 @@ typedef struct lcSchInfo
 
 typedef struct dlMsgSchedInfo
 {
+   bool       isRetx;
    uint8_t    numLc;
    LcSchInfo  lcSchInfo[MAX_NUM_LC]; /* Scheduled LC info */
    BwpCfg     bwp;
@@ -1696,6 +1707,15 @@ typedef struct srUciIndInfo
    uint8_t     srPayload[MAX_SR_BITS_IN_BYTES];
 }SrUciIndInfo;
 
+typedef struct harqUciIndInfo
+{
+   uint16_t    cellId;
+   uint16_t    crnti;
+   SlotTimingInfo slotInd;
+   uint8_t     numHarq;
+   uint8_t     harqPayload[MAX_HARQ_BITS_IN_BYTES];
+}HarqUciIndInfo;
+
 typedef struct schRrmPolicyRatio
 {
    uint8_t policyMaxRatio;
@@ -1737,6 +1757,19 @@ typedef struct schPageInd
    uint8_t  *pagePdu;
 }SchPageInd;
 
+typedef struct schUeHqInfo
+{
+   uint16_t  crnti;
+   uint8_t   hqProcId;
+}SchUeHqInfo;
+
+typedef struct schRlsHqInfo
+{
+   uint16_t     cellId;
+   uint8_t      numUes;
+   SchUeHqInfo  *ueHqInfo;
+}SchRlsHqInfo;
+
 /* function pointers */
 typedef uint8_t (*SchCellCfgCfmFunc)    ARGS((
         Pst            *pst,           /* Post Structure */                         
@@ -1792,6 +1825,10 @@ typedef uint8_t (*MacSchBsrFunc)       ARGS((
    UlBufferStatusRptInd *bsrInd
 ));
 
+typedef uint8_t (*MacSchHarqUciIndFunc) ARGS((
+        Pst         *pst,         /* Post structure */
+        HarqUciIndInfo  *uciInd));    /* UCI IND Info */
+
 typedef uint8_t (*MacSchSrUciIndFunc) ARGS(( 
         Pst         *pst,         /* Post structure */
         SrUciIndInfo  *uciInd));    /* UCI IND Info */
@@ -1854,6 +1891,10 @@ typedef uint8_t (*MacSchPagingIndFunc) ARGS((
    Pst         *pst,           /* Post structure */
    SchPageInd *schPagingInd)); /* Paging Indication */
 
+typedef uint8_t (*SchMacDlReleaseHarqFunc) ARGS((
+   Pst         *pst,           /* Post structure */
+   SchRlsHqInfo *rlsHqInfo)); /* Release Harq proc */
+
 /* function declarations */
 uint8_t packMacSchSlotInd(Pst *pst, SlotTimingInfo *slotInd);
 uint8_t packSchMacDlAlloc(Pst *pst, DlSchedInfo  *dlSchedInfo);
@@ -1882,6 +1923,8 @@ uint8_t unpackMacSchSlotInd(MacSchSlotIndFunc func, Pst *pst, Buffer  *mBuf);
 uint8_t packMacSchBsr(Pst *pst, UlBufferStatusRptInd *bsrInd);
 uint8_t MacSchBsr(Pst *pst, UlBufferStatusRptInd *bsrInd);
 uint8_t packMacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd);
+uint8_t packMacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd);
+uint8_t MacSchHarqUciInd(Pst *pst, HarqUciIndInfo *uciInd);
 uint8_t MacSchSrUciInd(Pst *pst, SrUciIndInfo *uciInd);
 uint8_t packMacSchModUeConfigReq(Pst *pst, SchUeCfg *ueCfgToSch);
 uint8_t MacSchModUeConfigReq(Pst *pst, SchUeCfg *ueCfgToSch);
@@ -1913,6 +1956,8 @@ uint8_t packMacSchPagingInd(Pst *pst,  SchPageInd *pageInd);
 uint8_t MacSchPagingInd(Pst *pst,  SchPageInd *pageInd);
 uint8_t packSchMacDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc);
 uint8_t MacProcDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc);
+uint8_t packSchMacDlReleaseHarq(Pst *pst, SchRlsHqInfo *rlsHqInfo);
+uint8_t MacSchReleaseDlHarqProc(Pst *pst, SchRlsHqInfo *rlsHqInfo);
 /**********************************************************************
   End of file
  **********************************************************************/
index c3d33ae..8303333 100644 (file)
@@ -285,10 +285,36 @@ void l1HdlConfigReq(uint32_t msgLen, void *msg)
  *         RFAILED - failure
  *
  * ****************************************************************/
-uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn)
+uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn, fapi_ul_pusch_pdu_t puschPdu)
 {
+   uint8_t result[]={0,//MSG3
+                     0,//BSR
+                     0,//MSG5 RRC Setup Complete
+                     0,//Security Mode Complete
+                     0,//Registraion Complete
+                     0,//RRC Reconfiguration Complete
+                     0,//UL DATA -1
+                     0,//UL DATA -2
+                     0,//UL DATA -3
+                     0,//UL DATA -4
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
 #ifdef INTEL_FAPI
    uint8_t idx = 0;
+   static uint8_t ind=0;
+   uint16_t ret = ROK;
    fapi_crc_ind_t  *crcInd;
 
    MAC_ALLOC(crcInd, sizeof(fapi_crc_ind_t));
@@ -304,12 +330,17 @@ uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn)
    crcInd->slot = slot;
    crcInd->numCrcs = 1;
 
-   crcInd->crc[idx].handle = 0;
-   crcInd->crc[idx].rnti = 0;
-   crcInd->crc[idx].harqId = 0;
+   crcInd->crc[idx].handle = puschPdu.handle;
+   crcInd->crc[idx].rnti = puschPdu.rnti;
+   crcInd->crc[idx].harqId = puschPdu.puschData.harqProcessId;
    crcInd->crc[idx].tbCrcStatus = 0;
    crcInd->crc[idx].numCb = 1;
-   crcInd->crc[idx].cbCrcStatus[0] = 0;
+   crcInd->crc[idx].cbCrcStatus[0] = result[ind%50];
+   ret = (0== crcInd->crc[idx].cbCrcStatus[0])?ROK:RFAILED;
+   /*TBD: To use crc ind with random number and percentage */
+   //crcInd->crc[idx].cbCrcStatus[0] = (crcPassPer >= rand()%(100))?0:1;
+   
+   ind++;
    crcInd->crc[idx].ul_cqi = 0;
    crcInd->crc[idx].timingAdvance = 0;
    crcInd->crc[idx].rssi = 0;
@@ -317,12 +348,12 @@ uint16_t l1BuildAndSendCrcInd(uint16_t slot, uint16_t sfn)
    fillMsgHeader(&crcInd->header, FAPI_CRC_INDICATION, \
         sizeof(fapi_crc_ind_t) - sizeof(fapi_msg_t));
 
-   /* Sending RACH indication to MAC */
+   /* Sending CRC indication to MAC */
    DU_LOG("\nINFO   -->  PHY STUB: Sending CRC Indication to MAC");
    procPhyMessages(crcInd->header.msg_id, sizeof(fapi_crc_ind_t), (void *)crcInd);
    MAC_FREE(crcInd, sizeof(fapi_crc_ind_t));
 #endif
-   return ROK;
+   return ret;
 } /* l1BuildAndSendCrcInd */
 
 #ifdef INTEL_FAPI
@@ -890,9 +921,35 @@ S16 l1HdlTxDataReq(uint16_t msgLen, void *msg)
 uint8_t fillPucchF0F1PduInfo(fapi_uci_o_pucch_f0f1_t *pduInfo, fapi_ul_pucch_pdu_t pucchPdu)
 {
    uint8_t idx = 0;
+   static uint8_t ind=0;
+   uint8_t result[]={0,//msg4
+                     0,//Security Mode Command
+                     0,//Registration Accept
+                     0,//RRC Reconfiguration
+                     0,//Data 1
+                     0,//Data 2
+                     0,//Data 3
+                     0,//Data 4
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,
+                     0,0,0,0,0,};
 
    pduInfo->handle = pucchPdu.handle;
    pduInfo->pduBitmap = 1;  //hardcoded for SR
+   if (pucchPdu.bitLenHarq)
+   {
+      pduInfo->pduBitmap |= HARQ_PDU_BITMASK;
+   }
    pduInfo->pucchFormat = pucchPdu.formatType;
    pduInfo->ul_cqi = 0;
    pduInfo->rnti = pucchPdu.rnti;
@@ -900,8 +957,11 @@ uint8_t fillPucchF0F1PduInfo(fapi_uci_o_pucch_f0f1_t *pduInfo, fapi_ul_pucch_pdu
    pduInfo->rssi = 0;
    if(pduInfo->pduBitmap & SR_PDU_BITMASK)
    {
-      pduInfo->srInfo.srIndication = SR_DETECTED;
-      pduInfo->srInfo.srConfidenceLevel = CONFDC_LEVEL_GOOD;
+      if (result[ind%50] == 0)
+      {
+         pduInfo->srInfo.srIndication = SR_DETECTED;
+         pduInfo->srInfo.srConfidenceLevel = CONFDC_LEVEL_GOOD;
+      }
    }
    if(pduInfo->pduBitmap & HARQ_PDU_BITMASK)
    {
@@ -909,7 +969,10 @@ uint8_t fillPucchF0F1PduInfo(fapi_uci_o_pucch_f0f1_t *pduInfo, fapi_ul_pucch_pdu
       pduInfo->harqInfo.harqConfidenceLevel = CONFDC_LEVEL_GOOD;
       for(idx = 0; idx < pduInfo->harqInfo.numHarq; idx++)
       {
-         pduInfo->harqInfo.harqValue[idx] = HARQ_PASS;
+         pduInfo->harqInfo.harqValue[idx] = result[ind%50];
+         ind++;
+         /*TBD: To use harq ind with random number and percentage*/
+         //pduInfo->harqInfo.harqValue[idx] = (dlHqPassPer >= rand()%(100))?HARQ_PASS:HARQ_FAIL;
       }
    }
    return ROK;
@@ -1062,7 +1125,10 @@ S16 l1HdlUlTtiReq(uint16_t msgLen, void *msg)
       if(ulTtiReq->pdus[numPdus-1].pduType == 1)
       {
          DU_LOG("\nINFO   -->  PHY STUB: PUSCH PDU");
-         l1BuildAndSendRxDataInd(ulTtiReq->slot, ulTtiReq->sfn, ulTtiReq->pdus[numPdus-1].pdu.pusch_pdu); 
+         if (ROK == l1BuildAndSendCrcInd(ulTtiReq->slot, ulTtiReq->sfn,ulTtiReq->pdus[numPdus-1].pdu.pusch_pdu))
+         {
+            l1BuildAndSendRxDataInd(ulTtiReq->slot, ulTtiReq->sfn, ulTtiReq->pdus[numPdus-1].pdu.pusch_pdu); 
+         }
       }
       if(ulTtiReq->pdus[numPdus-1].pduType == 2)
       {
@@ -1088,6 +1154,7 @@ S16 l1HdlUlTtiReq(uint16_t msgLen, void *msg)
       l1BuildAndSendRachInd(ulTtiReq->slot, ulTtiReq->sfn, CB_RA_PREAMBLE_IDX);
       phyDb.ueDb.numActvUe++;
    }
+   
 #if 0
    /* Send RACH Ind to L2 for second UE */
    if(phyDb.ueDb.ueCb[UE_IDX_1].rachIndSent == false && ulTtiReq->sfn == 304 && ulTtiReq->slot == 0)