Initial commit for Bronze release
[o-du/l2.git] / src / 5gnrsch / rg_sch_dhm.c
diff --git a/src/5gnrsch/rg_sch_dhm.c b/src/5gnrsch/rg_sch_dhm.c
new file mode 100755 (executable)
index 0000000..f6c8c59
--- /dev/null
@@ -0,0 +1,5251 @@
+/*******************************************************************************
+################################################################################
+#   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.                                             #
+################################################################################
+*******************************************************************************/
+
+/************************************************************************
+     Name:     LTE-MAC layer
+  
+     Type:     C source file
+  
+     Desc:     C source code for Entry point fucntions
+  
+     File:     rg_sch_dhm.c
+  
+**********************************************************************/
+
+/** @file rg_sch_dhm.c
+@brief APIs related to Downlink HARQ for the scheduler.
+*/
+
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_FILE_ID=242;
+static int RLOG_MODULE_ID=4096;
+
+/* header include files -- defines (.h) */
+#include "envopt.h"        /* environment options */
+#include "envdep.h"        /* environment dependent */
+#include "envind.h"        /* environment independent */
+#include "gen.h"           /* general layer */
+#include "ssi.h"           /* system service interface */
+#include "cm5.h"           /* common timers */
+#include "cm_hash.h"       /* common hash list */
+#include "cm_mblk.h"       /* common memory link list library */
+#include "cm_llist.h"      /* common linked list library */
+#include "cm_err.h"        /* common error */
+#include "cm_lte.h"        /* common LTE */
+#include "lrg.h"
+#include "rgr.h"
+#include "rgm.h"
+#include "tfu.h"
+#include "rg_env.h"
+#include "rg_sch_err.h"
+#include "rg_sch_inf.h"         /* typedefs for Scheduler */
+#include "rg_sch.h"
+#include "rg_sch_cmn.h"
+#include "rl_interface.h"
+#include "rl_common.h"
+
+/* header/extern include files (.x) */
+#include "gen.x"           /* general layer */
+#include "ssi.x"           /* system service interface */
+#include "cm5.x"           /* common timers */
+#include "cm_lib.x"        /* common library */
+#include "cm_hash.x"       /* common hash list */
+#include "cm_llist.x"      /* common linked list library */
+#include "cm_mblk.x"       /* memory management */
+#include "cm_tkns.x"       /* common tokens */
+#include "cm_lte.x"        /* common LTE */
+#include "lrg.x"
+#include "rgr.x"
+#include "rgm.x"
+#include "tfu.x"
+#include "rg_sch_inf.x"         /* typedefs for Scheduler */
+#include "rg_sch.x"
+#include "rg_sch_cmn.x"
+
+#ifdef RGSCH_SPS_STATS
+extern U32 rgNumSPSSchedDropMaxRetx;
+extern U32 rgNumActDtx;
+#endif
+PUBLIC U32  nackSf[10];
+
+
+
+#ifdef MAC_SCH_STATS
+PUBLIC RgSchNackAckStats hqFailStats;
+PUBLIC RgSchHqRetxStats  hqRetxStats;
+#endif /* MAC_SCH_STATS */
+//Chandan Stats Collection
+#ifdef DLHQ_STATS
+U32 statsCnt;
+RgSchDlHqStats dlHqStats[10000] = {{0,0,0}};
+#endif
+
+#ifdef TFU_TDD
+/* For special bundling case: convert numOfAcks to ACK/NACK
+ * The below table derives the HARQ aknowledgement as ACK or NACK using the 
+ * number of transmission done and the feedback value received
+ * The below table is based on Table 7.3-X from 36.213 and 
+ * table 79 from FAPIv1.1 doc
+ */
+U8 rgSchNumOfAcksToAckNack[RG_SCH_MAX_NUM_EXPECTED_ACKS][RG_SCH_NUM_FDBK_VALUE] = {
+{TFU_HQFDB_ACK,     TFU_HQFDB_NACK,    TFU_HQFDB_NACK},
+{TFU_HQFDB_NACK,    TFU_HQFDB_ACK,     TFU_HQFDB_NACK},
+{TFU_HQFDB_NACK,    TFU_HQFDB_NACK,    TFU_HQFDB_ACK},
+{TFU_HQFDB_ACK,     TFU_HQFDB_NACK,    TFU_HQFDB_NACK},
+{TFU_HQFDB_NACK,    TFU_HQFDB_ACK,     TFU_HQFDB_NACK},
+{TFU_HQFDB_NACK,    TFU_HQFDB_NACK,    TFU_HQFDB_ACK},
+{TFU_HQFDB_ACK,     TFU_HQFDB_NACK,    TFU_HQFDB_NACK},
+{TFU_HQFDB_NACK,    TFU_HQFDB_ACK,     TFU_HQFDB_NACK},
+{TFU_HQFDB_NACK,    TFU_HQFDB_NACK,    TFU_HQFDB_ACK}
+};
+#endif
+
+/* local typedefs */
+/* local externs */
+
+PRIVATE Void rgSCHDhmFdbkIndHndlTa ARGS((RgSchDlHqProcCb *hqP, U8 tbIdx, U8 fdbk,
+            Bool maxHqRetxReached));
+PUBLIC void rgEmtcsetNullSubFrm ARGS((RgSchDlHqProcCb *hqP));
+#ifndef LTE_TDD
+PRIVATE S16 rgSCHDhmProcHqFdbkAckNackRep ARGS((
+RgSchDlHqProcCb      *hqP,
+RgSchDlSf            *sf,
+U8                   tbCnt,
+U8                   *isAck
+));
+#endif
+#ifdef DL_LA
+PRIVATE S16 rgSCHDhmUpdateAckNackHistory ARGS((
+        RgSchCellCb             *cell,
+        RgSchUeCb               *ueCb,
+        U8                      hqfdbk,
+        U8                      tbCnt
+        ));
+#endif
+#ifdef LTE_TDD
+PRIVATE Void rgSCHDhmPrcSplBundlFdbk ARGS((
+        RgSchCellCb  *cell,
+        TfuHqInfo    *fdbk,
+        U8            hqCnt
+        ));
+#ifdef LTE_ADV
+PRIVATE Void rgSchGetHqFdbkPosForM1 ARGS((
+        RgSchUeCb            *ue,
+        RgSchDlHqProcCb      *hqP,
+        U8                  *isAck, 
+        RgTfuHqInfo          *fdbk,
+        U8                   tbIdx,
+        RgSchTddANInfo       *anInfo
+        ));
+PRIVATE Void rgSchGetHqFdbkPosForM234 ARGS((
+        RgSchUeCb            *ue,
+        RgSchDlHqProcCb      *hqP,
+        U8                   *isAck, 
+        RgTfuHqInfo          *fdbk,
+        U8                   tbIdx,
+        RgSchTddANInfo       *anInfo,
+        U8                    M,
+        CmLteTimingInfo      timeInfo
+        ));
+#endif/*LTE_ADV*/
+#endif/*LTE_TDD*/
+
+/* Freeing up the HARQ proc blocked for
+ * indefinite time in case of Retx */
+PUBLIC S16 rgSCHDhmDlRetxAllocFail ARGS((
+RgSchUeCb        *ue, 
+RgSchDlHqProcCb  *proc
+));
+
+#ifdef EMTC_ENABLE
+EXTERN S16 rgSCHDhmEmtcRgrCellCfg ARGS((
+RgSchCellCb   *cell
+));
+#endif
+
+#ifdef CA_DBG
+extern U32 gPCellTb1AckCount,gPCellTb2AckCount,gPCellTb1NackCount,gPCellTb2NackCount;
+extern U32 gSCellSchedCount,gPrimarySchedCount;
+extern U32 gSCellTb1AckCount,gSCellTb2AckCount,gSCellTb1NackCount,gSCellTb2NackCount;
+extern U32 gPCellTb1DtxCount, gPCellTb2DtxCount, gSCellTb1DtxCount, gSCellTb2DtxCount;
+extern U32 gHqFdbkCount;
+
+#endif
+#ifdef EMTC_ENABLE
+EXTERN Void rgSCHEmtcUtlDlHqPTbRmvFrmTx
+(
+RgSchEmtcDlSf               *subFrm,
+RgSchDlHqProcCb            *hqP,
+U8                         tbIdx,
+Bool                       isRepeting
+);
+EXTERN RgSchEmtcDlSf* rgSCHEmtcUtlSubFrmGet
+(
+RgSchCellCb            *cell,
+CmLteTimingInfo        frm
+);
+EXTERN Void rgSCHEmtcHqInfoAlloc ARGS((RgSchCellCb *cell, RgSchDlHqProcCb *hqP));
+#endif
+/* forward references */
+
+/**
+ * @brief This function initializes the DL HARQ Entity of UE.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmHqEntInit
+ *     Purpose:  This function initializes the DL HARQ entity of 
+ *               UE control block. This is performed at the time
+ *               of creating UE control block.
+ *     
+ *     Invoked by: configuration module
+ *     
+ *  @param[in]  RgSchCellCb*  cell
+ *  @return  RgSchDlHqEnt *
+ *
+ **/
+/*MS_WORKAROUND for ccpu00122893*/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqEntReset
+(
+   RgSchDlHqEnt      *hqE
+)
+#else
+PUBLIC Void rgSCHDhmHqEntReset(hqE)
+   RgSchDlHqEnt      *hqE;
+#endif
+{
+   RgSchDlHqProcCb   *hqP;
+   U8                i;
+   TRC2(rgSCHDhmHqEntReset)
+   cmLListInit(&hqE->inUse);     
+   cmLListInit(&hqE->free);      
+   for (i=0; i < hqE->numHqPrcs; i++)
+   {
+      hqP              = &hqE->procs[i];
+      hqP->hqE         = hqE;
+      hqP->procId      = i;
+      /* Fix  - reset numLch */
+      hqP->tbInfo[0].numLch      = 0;
+      hqP->tbInfo[1].numLch      = 0;
+      hqP->tbInfo[0].txCntr      = 0;
+      hqP->tbInfo[0].ndi         = 0;  /* Initialize the NDI to Zero */
+      hqP->tbInfo[1].txCntr      = 0;
+      hqP->tbInfo[1].ndi         = 0;  /* Initialize the NDI to Zero */
+      hqP->tbInfo[0].tbIdx       = 0;
+      hqP->tbInfo[1].tbIdx       = 1;
+      hqP->tbInfo[0].hqP         = hqP;
+      hqP->tbInfo[1].hqP         = hqP;
+      hqP->tbInfo[0].state       = HQ_TB_ACKED;
+      hqP->tbInfo[1].state       = HQ_TB_ACKED;
+      hqP->tbInfo[0].contResCe   = NOTPRSNT;
+      hqP->tbInfo[1].contResCe   = NOTPRSNT;
+      hqP->lnk.node = (PTR)hqP;
+      //cmLListAdd2Tail(&hqE->free, &hqP->lnk);
+      hqP->hqPLst = NULLP;
+      rgSCHDhmHqPAdd2FreeLst(hqP);
+      hqP->tbInfo[0].lchSchdData = hqP->tbInfo[0].lchSchdDataArr;
+      hqP->tbInfo[1].lchSchdData = hqP->tbInfo[1].lchSchdDataArr;
+      hqP->drxCb.rttIndx  = DRX_INVALID;
+      hqP->drxCb.reTxIndx = DRX_INVALID;
+      hqP->tbInfo[0].cntrRetxAllocFail = 0;
+      hqP->tbInfo[1].cntrRetxAllocFail = 0;
+      hqP->hasDcch = FALSE;
+      hqP->cwSwpEnabled = FALSE;
+      hqP->pdcch   = NULLP;
+      hqP->subFrm  = NULLP;
+
+#ifdef LTE_ADV
+      rgSCHLaaResetDlHqProcCb(hqP);
+#endif
+   }
+   RETVOID;
+} /* rgSCHDhmHqEntReset */
+
+/**
+ * @brief This function assigns dlHqEnt of raCb to ueCb.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmAssgnUeHqEntFrmRaCb 
+ *     Purpose:  This function assigns dlHqEnt of raCb to ueCb.
+ *     
+ *     Invoked by: configuration module
+ *     
+ *  @param[in]  RgSchUeCb       *ue
+ *  @param[in]  RgSchRaCb       *raCb
+ *  @return  Void 
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmAssgnUeHqEntFrmRaCb 
+(
+RgSchUeCb       *ue,
+RgSchRaCb       *raCb
+)
+#else
+PUBLIC Void rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb)
+RgSchUeCb       *ue;
+RgSchRaCb       *raCb;
+#endif
+{
+   TRC2(rgSCHDhmAssgnUeHqEntFrmRaCb)
+
+   ue->cellInfo[0]->hqEnt = raCb->dlHqE;
+   ue->cellInfo[0]->hqEnt->ue = ue;
+   /* Update the DL Harq related information */
+   ue->cellInfo[0]->hqEnt->maxHqTx = ue->cell->dlHqCfg.maxDlHqTx;
+   raCb->dlHqE = NULLP;
+   /* Fix : set UE active in DL as UE initialization completed */
+   ue->dl.dlInactvMask &= ~(RG_HQENT_INACTIVE);
+   ue->ul.ulInactvMask &= ~(RG_HQENT_INACTIVE);
+   rgSCHCmnDlInitHqEnt(ue->cell, ue->cellInfo[0]->hqEnt);
+   
+   RETVOID;
+}
+
+/**
+ * @brief This function deletes the dlHqEnt.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmDelHqEnt 
+ *     Purpose:  This function deletes the dlHqEnt.
+ *     
+ *     Invoked by: configuration module
+ *     
+ *  @param[in]  RgSchCellCb       *cell 
+ *  @param[in]  RgSchDlHqEnt      **hqE 
+ *  @return  Void 
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmDelHqEnt 
+(
+RgSchCellCb       *cell,
+RgSchDlHqEnt      **hqE
+)
+#else
+PUBLIC Void rgSCHDhmDelHqEnt(cell, hqE)
+RgSchCellCb       *cell;
+RgSchDlHqEnt      **hqE;
+#endif
+{
+   TRC2(rgSCHDhmDelHqEnt)
+
+   if (!(*hqE))
+   {
+      RETVOID;    
+   }
+
+   rgSCHCmnDlDeInitHqEnt(cell, *hqE);
+
+   rgSCHUtlFreeSBuf(cell->instIdx, (Data **)hqE, 
+       sizeof(RgSchDlHqEnt));
+   
+   RETVOID;
+}
+
+#ifdef ANSI
+PUBLIC RgSchDlHqEnt *rgSCHDhmHqEntInit
+(
+RgSchCellCb           *cell
+)
+#else
+PUBLIC RgSchDlHqEnt *rgSCHDhmHqEntInit(cell)
+RgSchCellCb           *cell;
+#endif
+{
+   RgSchDlHqEnt      *hqE;
+   Inst              inst = cell->instIdx;
+
+   TRC2(rgSCHDhmHqEntInit)
+
+   /* Init the HARQ data structure */
+   if (rgSCHUtlAllocSBuf(inst, (Data **)&hqE, sizeof(RgSchDlHqEnt)) != ROK)
+   {
+      RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
+                                         "rgSCHDhmHqEntInit hqE alloc fail"); 
+      RETVALUE(NULLP);
+   }
+#ifdef LTE_TDD
+   /* Init the HARQ processes */
+   hqE->numHqPrcs = rgSchTddDlNumHarqProcTbl[cell->ulDlCfgIdx];
+   if (rgSCHUtlAllocSBuf(inst, (Data **)&hqE->procs, 
+                           hqE->numHqPrcs * sizeof(RgSchDlHqProcCb)) != ROK)
+   {
+      RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
+                                         "rgSCHDhmHqEntInit hqP alloc fail in hqE"); 
+      RETVALUE(NULLP);
+   }
+#else
+   hqE->numHqPrcs = RGSCH_NUM_DL_HQ_PROC;
+#endif
+
+#ifdef LTE_ADV
+   rgSCHLaaInitDlHqProcCb (cell, hqE);
+#endif
+
+   /* Initialize maximum tranmission counter */
+   hqE->maxHqTx = cell->dlHqCfg.maxDlHqTx;
+   
+
+   /* MW_WORKAROUND for ccpu00122893 */
+   rgSCHDhmHqEntReset(hqE); 
+   /* CA Dev Start*/
+   hqE->cell = cell;
+   /* CA Dev End*/
+
+   RETVALUE(hqE);
+} /* rgSCHDhmHqEntInit */
+
+/**
+ * @brief This function gets an available HARQ process.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmGetAvlHqProc
+ *     Purpose:  This function returns an available HARQ process in 
+ *               the DL direction. All HARQ processes are maintained
+ *               in queues of free and inuse.
+ *
+ *               1. Check if the free queue is empty. If yes, return
+ *                  RFAILED
+ *               2. If not empty, update the proc variable with the
+ *                  first process in the queue. Return ROK.
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[in]  RgSchUeCb           *ue
+ *  @param[in]  CmLteTimingInfo  timingInfo
+ *  @param[out] RgSchDlHqProc       **hqP
+ *  @return  S16       
+ *         -#ROK     if successful
+ *         -#RFAILED otherwise
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmGetAvlHqProc
+(
+RgSchCellCb           *cell,
+RgSchUeCb               *ue,
+CmLteTimingInfo         timingInfo,
+RgSchDlHqProcCb         **hqP
+)
+#else
+PUBLIC S16 rgSCHDhmGetAvlHqProc (cell, ue, timingInfo, hqP)
+RgSchCellCb           *cell;
+RgSchUeCb               *ue;
+CmLteTimingInfo         timingInfo;
+RgSchDlHqProcCb         **hqP;
+#endif
+{
+   RgSchDlHqEnt         *hqE = NULLP;
+   RgSchDlHqProcCb   *tmpHqProc;
+   CmLList           *tmp;
+   TRC2(rgSCHDhmGetAvlHqProc);
+
+   hqE      = RG_SCH_CMN_GET_UE_HQE(ue, cell);
+   if (hqE == NULLP)
+   {   
+      RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHDhmGetAvlHqProc hqE NULL ue %d"
+                           , ue->ueId);     
+      RETVALUE(RFAILED);
+   }
+
+
+   CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
+
+   if (NULLP == tmp)
+   {
+    RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,
+                        "rgSCHDhmGetAvlHqProc free %ld inUse %ld ue %d"
+                                           , hqE->free.count, hqE->inUse.count, ue->ueId);
+      /* No Harq Process available in the free queue. */
+      RETVALUE(RFAILED);
+   }
+
+   tmpHqProc = (RgSchDlHqProcCb *)(tmp->node);
+
+#ifdef LTEMAC_SPS
+   /* If SPS HARQ procs are in use, do not use SPS harq procs for non-SPS
+    * transmissions */
+   if (ue->dl.isSpsHqPInUse)
+   {
+      while (tmpHqProc->procId < ue->dl.dlSpsCfg.numSpsHqProc)
+      {
+         CM_LLIST_NEXT_NODE(&(hqE->free), tmp);
+         if (!tmp)
+         {
+            break;
+         }
+         tmpHqProc = (RgSchDlHqProcCb *)(tmp->node);
+      }
+      if (!tmp)
+      {
+         /* No Harq Process available in the free queue. */
+         RETVALUE(RFAILED);
+      }
+   }
+#endif
+
+
+   tmpHqProc->tbInfo[0].timingInfo = timingInfo;
+   tmpHqProc->tbInfo[1].timingInfo = timingInfo;
+   tmpHqProc->hasDcch = FALSE;
+   tmpHqProc->cwSwpEnabled = FALSE;
+
+   /* Remove the element from the free Queue */
+   //cmLListDelFrm(&hqE->free, tmp);
+   rgSCHDhmHqPDelFrmFreeLst(tmpHqProc);
+
+   /* Add the element into the inUse Queue as well */
+   //cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk);
+   rgSCHDhmHqPAdd2InUseLst(tmpHqProc);
+
+   *hqP = tmpHqProc;
+   
+#ifdef LTE_ADV
+   rgSCHLaaResetDlHqProcCb(tmpHqProc);
+#endif
+
+   /* LAA DBG Only */
+   tmpHqProc->tbSizeAtEstimate[0] = 0;
+   tmpHqProc->tbSizeAtEstimate[1] = 0;
+   tmpHqProc->tbSizeAtFnlz[0] = 0;
+   tmpHqProc->tbSizeAtFnlz[1] = 0;
+   tmpHqProc->tbSizeOfMvdTb[0] = 0;
+   tmpHqProc->tbSizeOfMvdTb[1] = 0;
+   tmpHqProc->itbsAtEstimate[0] = 0;
+   tmpHqProc->itbsAtEstimate[1] = 0;
+   tmpHqProc->prbAtEstimate = 0;
+
+   RETVALUE(ROK);
+} /* rgSCHDhmGetAvlHqProc */
+
+
+/**
+ * @brief This function adds HARQ process for a given TB in to 
+ *        the inuse queue upon retx.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmHqTbRetx
+ *     Purpose:  This function handles when a HARQ process is scheduled
+ *               for retransmission. It adds the HARQ procss to inuse
+ *               queue.
+ *               1. Check if this HqP is already added to the inUse
+ *                  queue as part of this function call for other
+ *                  TB's retransmission.
+ *               2. If already present in inUse Q then do not add.
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[in]  RgSchDlHqEnt     *hqE
+ *  @param[in]  CmLteTimingInfo  timingInfo
+ *  @param[out] RgDlHqProc       *hqP
+ *  @param[in]  U8               tbIdx
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqTbRetx
+(
+RgSchDlHqEnt            *hqE,
+CmLteTimingInfo         timingInfo,
+RgSchDlHqProcCb         *hqP,
+U8                      tbIdx
+)
+#else
+PUBLIC Void rgSCHDhmHqTbRetx(hqE, timingInfo, hqP, tbIdx)
+RgSchDlHqEnt            *hqE;
+CmLteTimingInfo         timingInfo;
+RgSchDlHqProcCb         *hqP;
+U8                      tbIdx;
+#endif
+{
+   U8 othrTbIdx = tbIdx ^ 1;
+   TRC2(rgSCHDhmHqTbRetx)
+
+   hqP->tbInfo[tbIdx].timingInfo = timingInfo;
+
+   if (hqE->msg4Proc == hqP)
+   {
+       RETVOID;
+   }
+   /* fix for ccpu00118633 No Hq proc Avl end*/
+      
+   /* Extra:check if Harq process is already linked to in-use
+      Queue by means of other TB handling. */
+   if (hqP->tbInfo[othrTbIdx].state != HQ_TB_WAITING)
+   {
+      /*Fix FIXME */
+      if (hqE->msg4Proc != hqP)
+      {
+         //cmLListAdd2Tail(&hqE->inUse, &hqP->lnk);
+         rgSCHDhmHqPAdd2InUseLst(hqP);
+      }
+   }
+
+    hqP->tbInfo[tbIdx].cntrRetxAllocFail = 0;
+
+   RETVOID;
+} /* rgSCHDhmHqTbRetx */
+
+/**
+ * @brief This function returns last scheduled HARQ process for
+ *        a UE's HARQ entity.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmLastSchedHqProc
+ *     Purpose:  This function returns the last (most recent)
+ *               process in the inUse list, which corresponds
+ *               to the last scheduled process. Returns NULLP
+ *               if list is empty.
+ *               The reason for introducing this is to have
+ *               an ability to check if UE was scheduled
+ *               in the current subframe (scheduling would
+ *               have caused a proc to be added to the end
+ *               of the list, and checking time (only subframe
+ *               number probably works) would confirm this.
+ *
+ *     Invoked by: scheduler
+ *     
+ *  @param[in]  RgSchDlHqEnt        *hqE
+ *  @return  RgSchDlHqProcCb *
+ *
+ **/
+#ifdef ANSI
+PUBLIC RgSchDlHqProcCb * rgSCHDhmLastSchedHqProc
+(
+RgSchDlHqEnt            *hqE
+)
+#else
+PUBLIC RgSchDlHqProcCb * rgSCHDhmLastSchedHqProc(hqE)
+RgSchDlHqEnt            *hqE;
+#endif
+{
+   TRC2(rgSCHDhmLastSchedHqProc);
+   /* GRPPWR_CNTRL Fix: UE context will not hold a valid hqE,
+    * until RACH procedure is completed */
+   if ((hqE == NULLP) || (hqE->inUse.last == NULLP))
+   {
+      RETVALUE(NULLP);
+   }
+   RETVALUE((RgSchDlHqProcCb *)hqE->inUse.last->node);
+} /* rgSCHDhmLastSchedHqProc */
+
+#ifdef RGR_V1
+/**
+ * @brief This function gets an available HARQ process for MSG 4.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmGetCcchSduHqProc
+ *     Purpose:  This function returns an available HARQ process in 
+ *               the DL direction. All HARQ processes are maintained
+ *               in queues of free and inuse.
+ *
+ *               1. Check if the free queue is empty. If yes, return
+ *                  RFAILED.
+ *               2. If not empty, update the proc variable with the
+ *                  first process in the queue. Return ROK.
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[in]  RgSchRaCb           *raCb
+ *  @param[in]  CmLteTimingInfo  timingInfo
+ *  @param[out] RgSchDlHqProcCb  **hqP
+ *  @return  S16       
+ *         -#ROK     if successful
+ *         -#RFAILED otherwise
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmGetCcchSduHqProc
+(
+RgSchUeCb               *ueCb,
+CmLteTimingInfo         timingInfo,
+RgSchDlHqProcCb         **hqP
+)
+#else
+PUBLIC S16 rgSCHDhmGetCcchSduHqProc (ueCb, timingInfo, hqP)
+RgSchUeCb               *ueCb;
+CmLteTimingInfo         timingInfo;
+RgSchDlHqProcCb         **hqP;
+#endif
+{
+   RgSchDlHqProcCb      *tmpHqProc;
+   CmLList              *tmp;
+   RgSchDlHqEnt         *hqE;
+
+   TRC2(rgSCHDhmGetCcchSduHqProc)
+
+   hqE = ueCb->cellInfo[0]->hqEnt;
+   CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
+   if (NULLP == tmp)
+   {
+      /* No Harq Process available in the free queue. */
+      RETVALUE(RFAILED);
+   }
+
+   /* Remove the element from the free Queue and */
+   /* set the MSG 4 HARQ proc pointer            */
+   //cmLListDelFrm(&hqE->free, tmp);
+
+   tmpHqProc             = (RgSchDlHqProcCb *)(tmp->node);
+
+   rgSCHDhmHqPDelFrmFreeLst(tmpHqProc);
+
+   tmpHqProc->tbInfo[0].timingInfo = timingInfo;
+   /* Fix : syed minor code reorg */
+   *hqP = tmpHqProc;
+   /*Updating ccchSduProc to identify feedback for CCCH SDU sent without 
+    * Cont Res CE*/
+   hqE->ccchSduProc         = tmpHqProc;
+   //cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk);
+   rgSCHDhmHqPAdd2InUseLst(tmpHqProc);
+   
+   RETVALUE(ROK);
+} /* rgSCHDhmGetCcchSduHqProc */
+#endif
+
+/**
+ * @brief This function gets an available HARQ process for MSG 4.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmGetMsg4HqProc
+ *     Purpose:  This function returns an available HARQ process in 
+ *               the DL direction. All HARQ processes are maintained
+ *               in queues of free and inuse.
+ *
+ *               1. Check if the free queue is empty. If yes, return
+ *                  RFAILED.
+ *               2. If not empty, update the proc variable with the
+ *                  first process in the queue. Return ROK.
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[in]  RgSchRaCb           *raCb
+ *  @param[in]  CmLteTimingInfo  timingInfo
+ *  @param[out]  RgDlHqProc       **hqP
+ *  @return  S16       
+ *         -#ROK     if successful
+ *         -#RFAILED otherwise
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmGetMsg4HqProc
+(
+RgSchRaCb               *raCb,
+CmLteTimingInfo         timingInfo
+)
+#else
+PUBLIC S16 rgSCHDhmGetMsg4HqProc (raCb, timingInfo)
+RgSchRaCb               *raCb;
+CmLteTimingInfo         timingInfo;
+#endif
+{
+   RgSchDlHqProcCb      *tmpHqProc;
+   CmLList              *tmp;
+   RgSchDlHqEnt         *hqE;
+
+   TRC2(rgSCHDhmGetMsg4HqProc)
+
+   hqE = raCb->dlHqE;
+   CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
+   if (NULLP == tmp)
+   {
+      /* No Harq Process available in the free queue. */
+      RETVALUE(RFAILED);
+   }
+
+   /* Remove the element from the free Queue and */
+   /* set the MSG 4 HARQ proc pointer            */
+   //cmLListDelFrm(&hqE->free, tmp);
+   tmpHqProc             = (RgSchDlHqProcCb *)(tmp->node);
+   rgSCHDhmHqPDelFrmFreeLst(tmpHqProc);
+   tmpHqProc->tbInfo[0].timingInfo = timingInfo;
+   hqE->msg4Proc         = tmpHqProc;
+
+   RETVALUE(ROK);
+} /* rgSCHDhmGetMsg4HqProc */
+
+/**
+ * @brief This function releases a HARQ process.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmRlsHqpTb 
+ *     Purpose:  This function resets the TB specific fields
+ *               Based on the other TBs state, this HqProcess
+ *               is returned to the HqEnt.
+ *     
+ *               1. Add the HARQ process to the free queue.
+ *     Invoked by: scheduler and HARQ processing
+ *     
+ *  @param[in]  RgDlHqProc    *hqP
+ *  @param[in]  U8            tbIdx
+ *  @param[in]  Bool          togNdi 
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmRlsHqpTb
+(
+RgSchDlHqProcCb         *hqP,
+U8                      tbIdx,
+Bool                    togNdi
+) 
+#else
+PUBLIC Void rgSCHDhmRlsHqpTb(hqP, tbIdx, togNdi) 
+RgSchDlHqProcCb         *hqP;
+U8                      tbIdx;
+Bool                    togNdi;
+#endif
+{
+   RgSchDlHqEnt         *hqE;
+   U8                   othrTbIdx = tbIdx ^ 1;
+#ifdef LTEMAC_SPS
+   RgSchCmnDlHqProc        *cmnHqDl;
+#endif
+   /* L2_COUNTERS */
+#ifdef LTE_L2_MEAS
+   RgSchDlLcCb*         lcCb = NULLP;
+   U8                   numLch = 0;
+#endif
+
+   TRC2(rgSCHDhmRlsHqpTb)
+
+   /* Reset all tbInfo values */
+
+   hqE = hqP->hqE;
+
+#ifdef MAC_SCH_STATS
+   if (hqP->hqE->ue != NULLP)
+   {
+      RgSchUeCb      *ueCb  = hqP->hqE->ue;
+      RgSchCmnUe     *cmnUe = (RgSchCmnUe*)ueCb->sch;
+      RgSchCmnDlUe   *dlUe  = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/
+      U8             cqi    = dlUe->mimoInfo.cwInfo[0].cqi;
+      /* to get retransmission, decreasing transmission counter */
+      U16            numDlRetx = hqP->tbInfo[0].txCntr-1; 
+      U8             tbs       = dlUe->mimoInfo.cwInfo[0].iTbs[0];
+      static U32 retxCnt1      = 0;
+
+      RG_SCH_CMN_DL_TBS_TO_MCS(tbs, \
+            hqRetxStats.dlCqiStat[(cqi - 1)].mcs);
+
+      switch (numDlRetx)
+      {
+         case 1:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1++;
+            break;
+         case 2:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2++;
+            break;
+         case 3:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3++;
+            break;
+         case 4:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4++;
+            break;
+      }
+      hqRetxStats.dlCqiStat[(cqi - 1)].totalTx = \
+             hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1 + \
+            (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \
+            (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \
+            (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4 * 4); 
+
+      retxCnt1 += numDlRetx;
+   }
+#endif /* MAC_SCH_STATS */
+   RGSCH_ARRAY_BOUND_CHECK(0, hqP->tbInfo, tbIdx);
+   /* Toggle ndi */
+   if(togNdi == TRUE)
+   {
+      hqP->tbInfo[tbIdx].ndi          ^= 1;
+   }
+
+   /* L2_COUNTERS */
+#ifdef LTE_L2_MEAS
+   for (numLch =0; numLch < hqP->tbInfo[tbIdx].numLch; numLch++)
+   {
+      if (NULLP != (lcCb = rgSCHDbmGetDlDedLcCb( hqP->hqE->ue,
+                  hqP->tbInfo[tbIdx].lchSchdDataArr[numLch].lcId)))
+      {
+         if (lcCb->lcType == CM_LTE_LCH_DTCH)
+         {
+            if (hqP->hqE->ue->qciActiveLCs[lcCb->qciCb->qci])
+            {
+               hqP->hqE->ue->qciActiveLCs[lcCb->qciCb->qci]--;
+            }
+
+            if (!(hqP->hqE->ue->qciActiveLCs[lcCb->qciCb->qci]))
+            {
+               lcCb->qciCb->dlUeCount--;
+            }
+         }
+      }
+   }
+#endif
+
+   /* Initialization */
+   hqP->tbInfo[tbIdx].tbSz           = 0;
+   hqP->tbInfo[tbIdx].numLch         = 0;
+   hqP->tbInfo[tbIdx].txCntr         = 0;
+   /* FOR ACK NACK REP */
+   hqP->tbInfo[tbIdx].fbkRepCntr     = 0;
+   hqP->tbInfo[tbIdx].fbkRecpRepCntr = 0;
+   hqP->tbInfo[tbIdx].ackCount       = 0;
+   /* pdcch is moved from TbCb to HqCb.
+      This pdcch will be set to NULL when 
+      HqCb will be pushed to free list*/
+   hqP->tbInfo[tbIdx].state          = HQ_TB_ACKED;
+   hqP->tbInfo[tbIdx].isAckNackDtx   = 0;
+   hqP->tbInfo[tbIdx].nackCount      = 0;
+   hqP->tbInfo[tbIdx].dtxCount       = 0;
+   hqP->tbInfo[tbIdx].schdTa.pres    = NOTPRSNT;
+   hqP->tbInfo[tbIdx].contResCe      = NOTPRSNT;
+#ifdef LTE_ADV
+   hqP->tbInfo[tbIdx].schdSCellActCe.pres = NOTPRSNT;
+#endif
+   hqP->tbInfo[tbIdx].minRlcReordrTmr = 0;
+   /* Handling msg4 hqProc */
+   if (hqE->msg4Proc == hqP)
+   {
+      hqE->msg4Proc = NULLP;
+      hqP->pdcch    = NULLP;
+      hqP->subFrm   = NULLP;
+      /* Add the proc to the free list */
+      //cmLListAdd2Tail(&hqE->free, &hqP->lnk);
+      rgSCHDhmHqPAdd2FreeLst(hqP);
+      RETVOID;
+   }
+#ifdef RGR_V1
+   /* MS_WORKAROUND : syed The check (hqE->ccchSduProc != NULLP)
+    * is dangerous and it expects ccchSduProc is the first
+    * DL allocation for a UE, and considering a scenario
+    * of multiple UEs contending and 1 UE per TTI, this 
+    * assumption can be wronged, leading to inUse list
+    * corruption. Hence altering this check.
+    * A better approach would be do avoid having this 
+    * special handling for ccchSduProc, streamline 
+    * it with the usual approach. */
+   if (hqE->ccchSduProc == hqP)
+   {
+      hqE->ccchSduProc = NULLP;
+      /* ccpu00137582- If hqP is in reTxLst then it will be no more available
+       * in inUse list, Hence need not to delete from inUse list*/
+      if(NULLP == hqP->tbInfo[tbIdx].ccchSchdInfo.retxLnk.node)
+      {
+         //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+         rgSCHDhmHqPDelFrmInUseLst(hqP);
+      }
+      else
+      {
+         hqP->tbInfo[tbIdx].ccchSchdInfo.retxLnk.node = NULLP;
+      }
+      hqP->pdcch    = NULLP;
+      hqP->subFrm   = NULLP;
+      /* Add the proc to the free list */
+      //cmLListAdd2Tail(&hqE->free, &hqP->lnk);
+      rgSCHDhmHqPAdd2FreeLst(hqP);
+      RETVOID;
+   }
+#endif
+      
+   /* extra:check if other TB is also free for allocation then 
+    * add it to FREE List */
+   switch(hqP->tbInfo[othrTbIdx].state)
+   {
+      case HQ_TB_ACKED:
+         /* Remove the element from the inUse Queue */
+         /* Freeing up the HARQ proc blocked for
+          * indefinite time in case of Retx */
+         if (hqP->tbInfo[tbIdx].cntrRetxAllocFail != RG_SCH_MAX_RETX_ALLOC_FAIL)
+         {
+            //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+            rgSCHDhmHqPDelFrmInUseLst(hqP);
+         }
+         hqP->pdcch   = NULLP;
+         hqP->subFrm  = NULLP;
+#ifdef EMTC_ENABLE
+rgEmtcsetNullSubFrm(hqP);
+#endif
+         /* Add the proc to the free list */
+         //cmLListAdd2Tail(&hqE->free, &hqP->lnk);
+         rgSCHDhmHqPAdd2FreeLst(hqP);
+#ifdef LAA_DBG
+         if (hqE->free.count > 8)
+         {
+            int *p = NULL;
+            printf("Crashing invalid hq count after free \n");
+            printf("Crashing %d \n", *p);
+            *p = 10;
+         }
+#endif
+#ifdef LTEMAC_SPS
+         cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
+         if (cmnHqDl) 
+         {
+            cmnHqDl->spsAction = 0;
+            cmnHqDl->isSpsActv = FALSE;
+            cmnHqDl->isSpsSvcSchd = FALSE;
+         }
+#endif
+         break;
+         case HQ_TB_NACKED:
+         /* Remove the element from the inUse Queue */
+         /* Freeing up the HARQ proc blocked for
+          * indefinite time in case of Retx */
+         if (hqP->tbInfo[othrTbIdx].cntrRetxAllocFail == 0)
+         {
+            //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+            rgSCHDhmHqPDelFrmInUseLst(hqP);
+         }
+         break;
+         case HQ_TB_WAITING:
+            /* Do nothing */
+         break;
+   }
+   
+   hqP->tbInfo[tbIdx].cntrRetxAllocFail = 0;
+
+   RETVOID;
+} /* rgSCHDhmRlsHqpTb */
+
+/**
+ * @brief This function releases a HARQ process.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmRlsHqProc
+ *     Purpose:  This function returns a HARQ process to HARQ Entity 
+ *               in the DL direction.
+ *     
+ *               1. Add the HARQ process to the free queue.
+ *     Invoked by: scheduler and HARQ processing
+ *     
+ *  @param[in]  RgDlHqProc    *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmRlsHqProc
+(
+RgSchDlHqProcCb         *hqP
+)
+#else
+PUBLIC Void rgSCHDhmRlsHqProc(hqP)
+RgSchDlHqProcCb         *hqP;
+#endif
+{
+
+   TRC2(rgSCHDhmRlsHqProc)
+
+
+#ifdef MAC_SCH_STATS
+    /* THIS FUNCTION IS NOT CALLED */
+   if (hqP->hqE->ue != NULLP)
+   {
+      RgSchUeCb      *ueCb  = hqP->hqE->ue;
+      RgSchCmnUe     *cmnUe = (RgSchCmnUe*)ueCb->sch;
+      RgSchCmnDlUe   *dlUe  = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/
+      U8             cqi    = dlUe->mimoInfo.cwInfo[0].cqi;
+      /* to get retransmission, decreasing transmission counter */
+      U16            numDlRetx = hqP->tbInfo[0].txCntr-1; 
+      U8             tbs       = dlUe->mimoInfo.cwInfo[0].iTbs[0];
+
+      RG_SCH_CMN_DL_TBS_TO_MCS(tbs, hqRetxStats.dlCqiStat[(cqi - 1)].mcs);
+
+      switch (numDlRetx)
+      {
+         case 1:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1++;
+            break;
+         case 2:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2++;
+            break;
+         case 3:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3++;
+            break;
+         case 4:
+            hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4++;
+            break;
+      }
+      hqRetxStats.dlCqiStat[(cqi - 1)].totalTx = \
+             hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_1 + \
+            (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_2 * 2) + \
+            (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_3 * 3) + \
+            (hqRetxStats.dlCqiStat[(cqi - 1)].numOfHQ_4 * 4);
+   }
+#endif /* MAC_SCH_STATS */
+      hqP->pdcch   = NULLP;
+      hqP->subFrm  = NULLP;
+#ifdef EMTC_ENABLE
+rgEmtcsetNullSubFrm(hqP);
+#endif
+      rgSCHDhmHqPDelFrmInUseLst(hqP);
+      rgSCHDhmHqPAdd2FreeLst(hqP);
+#ifdef TFU_UPGRADE
+   hqP->tbCnt = 0;
+#endif
+
+   RETVOID;
+} /* rgSCHDhmRlsHqProc */
+
+#ifdef LTEMAC_SPS
+/**
+ * @brief This function gets HARQ process with the given ID.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmGetHqProcFrmId
+ *     Purpose:  This function returns the HARQ process with the given ID.
+ *     Invoked by: ROM
+ *     
+ *  @param[in]  RgSchUeCb     *ue
+ *  @param[in]  U8            idx
+ *  @param[in]  RgDlHqProc    **hqP
+ *  @return  S16       
+ *         -#   ROK     if successful
+ *         -#   RFAILED otherwise
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmGetHqProcFrmId
+(
+RgSchCellCb           *cell,
+RgSchUeCb               *ue,
+U8                      idx,
+RgSchDlHqProcCb         **hqP
+)
+#else
+PUBLIC S16 rgSCHDhmGetHqProcFrmId(cell, ue, idx, hqP)
+RgSchCellCb           *cell;
+RgSchUeCb               *ue;
+U8                      idx;
+RgSchDlHqProcCb         **hqP;
+#endif
+{
+   RgSchDlHqEnt         *hqE;
+   TRC2(rgSCHDhmGetHqProcFrmId)
+
+   hqE      = RG_SCH_CMN_GET_UE_HQE(ue, cell);
+   /* Pick the proc based on the index provided */
+   *hqP = &(hqE->procs[idx]);
+
+   RETVALUE(ROK);
+} /* rgSCHDhmGetHqProcFrmId */
+
+/**
+ * @brief This function gets SPS HARQ process from the given time
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmSpsDlGetHqProc
+ *     Purpose:  This function returns the SPS HARQ process for the given time
+ *     
+ *  @param[in]  RgSchUeCb       *ue
+ *  @param[in]  CmLteTimingInfo timingInfo
+ *  @return  RgSchDlHqProcCb control block 
+ *
+ **/
+#ifdef ANSI
+PUBLIC RgSchDlHqProcCb* rgSCHDhmSpsDlGetHqProc
+(
+RgSchCellCb           *cell,
+RgSchUeCb               *ue,
+CmLteTimingInfo         timingInfo
+)
+#else
+PUBLIC RgSchDlHqProcCb* rgSCHDhmSpsDlGetHqProc(cell, ue, timingInfo)
+RgSchCellCb           *cell,
+RgSchUeCb               *ue;
+CmLteTimingInfo         timingInfo;
+#endif
+{
+   RgSchDlHqEnt         *hqE;
+   U8                    idx;
+   RgSchDlHqProcCb       *hqProc = NULLP;
+   CmLList               *tmp = NULLP;
+
+   TRC2(rgSCHDhmSpsDlGetHqProc);
+
+   hqE      = RG_SCH_CMN_GET_UE_HQE(ue, cell);
+
+   CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
+
+   if (NULLP == tmp)
+   {
+      /* No Harq Process available in the free queue. */
+      RETVALUE(NULLP);
+   }
+
+   idx = ((timingInfo.sfn * RGSCH_NUM_SUB_FRAMES_5G + timingInfo.subframe)/
+         ue->dl.dlSpsCfg.dlSpsPrdctyEnum) % ue->dl.dlSpsCfg.numSpsHqProc;
+
+
+   hqProc = (RgSchDlHqProcCb *)(tmp->node);
+
+   /* If the  HARQ process is in the free list, retrieve the process */
+   while (hqProc->procId != idx)
+   {
+      CM_LLIST_NEXT_NODE(&(hqE->free), tmp);
+      if (!tmp)
+      {
+         break;
+      }
+      hqProc = (RgSchDlHqProcCb *)(tmp->node);
+   }
+
+   if (!tmp)
+   {
+      /* No Harq Process available in the free queue. */
+      RETVALUE(NULLP);
+   }
+
+   hqProc->tbInfo[0].timingInfo = timingInfo;
+   hqProc->tbInfo[1].timingInfo = timingInfo;
+
+   /* Remove the element from the free Queue */
+   //cmLListDelFrm(&hqE->free, tmp);
+   rgSCHDhmHqPDelFrmFreeLst(hqProc);
+
+   /* Add the element into the inUse Queue as well */
+   //cmLListAdd2Tail(&hqE->inUse, &hqProc->lnk);
+   rgSCHDhmHqPAdd2InUseLst(hqProc);
+
+#ifdef LTE_ADV
+   rgSCHLaaResetDlHqProcCb(hqProc);
+#endif
+
+   RETVALUE(hqProc);
+} /* rgSCHDhmSpsDlGetHqProc */
+#endif /* LTEMAC_SPS */
+
+
+/** * @brief Handler for handling TA. 
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmFdbkIndHndlTa
+ *     
+ *     This function handles the TA state and values based on the 
+ *     feedback indication received.
+ *           
+ *  @param[in]  RgSchDlHqProcCb   *hqP
+ *  @param[in]  U8                tbIdx
+ *  @param[in]  U8                fdbk
+ *  @return     Void
+ *      -# None.
+ **/
+#ifdef ANSI
+PRIVATE Void rgSCHDhmFdbkIndHndlTa
+(
+RgSchDlHqProcCb   *hqP,
+U8                tbIdx,
+U8                fdbk,
+Bool              maxHqRetxReached
+)
+#else
+PRIVATE Void rgSCHDhmFdbkIndHndlTa(hqP, tbIdx, fdbk,maxHqRetxReached)
+RgSchDlHqProcCb   *hqP;
+U8                tbIdx;
+U8                fdbk;
+Bool              maxHqRetxReached;
+#endif
+{
+   RgSchUeCb      *ueCb;
+   RgSchCellCb    *cell;
+
+   TRC2(rgSCHDhmFdbkIndHndlTa)
+
+   ueCb  = hqP->hqE->ue;
+   cell  = ueCb->cell;
+   switch(fdbk)
+   {
+      case TRUE:
+         /*ccpu00130018 -ADD - To prevent duplicate insert into the TA list*/  
+         hqP->tbInfo[tbIdx].taSnt =  FALSE;
+         /* To prevent duplicate inserts of ueCb into TA list */
+         if (ueCb->taLnk.node == NULLP)
+         {
+            ueCb->taLnk.node         =  (PTR)ueCb;
+            cmLListAdd2Tail(&cell->taUeLst, &ueCb->taLnk);
+         }
+         else
+         { 
+#ifdef DEBUGP            
+            RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Trying to add CRNTI:%d into TA"
+                     "ACK List twice", ueCb->ueId);
+#endif            
+         } 
+         break;
+
+      case FALSE:
+         /* If Ta was sent and its the final NACK, then reset only the 
+          * taState to IDLE and not the value */
+         /* Changed handling in case maxhqretx is reached for TA */
+         if(TRUE == maxHqRetxReached)
+         {
+            hqP->tbInfo[tbIdx].taSnt    =  FALSE;
+            hqP->hqE->ue->dl.taCb.state =  RGSCH_TA_IDLE;
+
+            rgSCHUtlReTxTa(cell, ueCb);
+            RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId, 
+                  "Nack Rcvd for TA. Max Tries Attempted");
+         }
+         break;
+      case TFU_HQFDB_DTX:
+         /* If Ta was sent and its the final NACK, then reset only the 
+          * taState to IDLE and not the value */
+         if(TRUE == maxHqRetxReached)
+         {
+            hqP->tbInfo[tbIdx].taSnt    =  FALSE;
+            hqP->hqE->ue->dl.taCb.state =  RGSCH_TA_IDLE;
+
+            /*ccpu00131191 and ccpu00131317 - Fix for RRC Reconfig failure
+             * issue for VoLTE call */
+            rgSCHUtlDlTARpt(cell, ueCb);
+         }
+         break;
+
+      default:
+         break;
+   }
+
+   RETVOID;
+} /* rgSCHDhmFdbkIndHndlTa */
+
+/* 3.1 MIMO: TA cmd details at TB level rather than Hq Level */
+/** * @brief Handler for scheduling TA.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmShcdTa
+ *     
+ *     This function is called by scheduler when resource allocation
+ *     for TA transmission is done.
+ *           
+ *  @param[in]  RgSchUeCb         *ue
+ *  @param[out] RgSchDlHqTbCb     *tbInfo
+ *  @return     Void
+ *      -# None.
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmSchdTa
+(
+RgSchUeCb         *ueCb,
+RgSchDlHqTbCb     *tbInfo
+)
+#else
+PUBLIC Void rgSCHDhmSchdTa(ueCb, tbInfo)
+RgSchUeCb         *ueCb;
+RgSchDlHqTbCb     *tbInfo;
+#endif
+{
+
+   TRC2(rgSCHDhmSchdTa)
+
+   ueCb->dl.taCb.state = RGSCH_TA_SCHEDULED;
+    ueCb->dl.taCb.numRemSf  =  2; 
+   tbInfo->schdTa.pres    = PRSNT_NODEF;
+   tbInfo->schdTa.val     = ueCb->dl.taCb.ta;
+
+   RETVOID;
+} /* rgSCHDhmSchdTa */
+
+#ifdef LTE_TDD
+/** * @brief Handler for fetching Harq Proc given the feeback information.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmHqProcByFdbkTime
+ *
+ *     This function shall fetch all the harq proc having the feedback
+ *     timing information.
+ *
+ *  @param[in]  RgSchDlHqEnt       *hqE
+ *  @param[in]  CmLteTimingInfo    timeInfo
+ *  @param[in]  Bool               *isMsg4
+ *  @param[out] RgSchDlHqProcCb    **hqPrcs
+ *  @param[out] U8                 *numTbs
+ *  @param[out] S8                 *tbStrtIdx
+ *  @param[out] U8                 *cntHqPrcs
+ *  @return     S16
+ **/
+#ifdef ANSI
+PRIVATE S16 rgSCHDhmHqProcByFdbkTime
+(
+RgSchDlHqEnt            *hqE,
+CmLteTimingInfo         timeInfo,
+Bool                    *isMsg4,
+RgSchDlHqProcCb         **hqPrcs,
+U8                      *numTbs,
+S8                      *tbStrtIdx,
+U8                      *cntHqPrcs,
+RgSchCellCb             *cell
+)
+#else
+PRIVATE S16 rgSCHDhmHqProcByFdbkTime(hqE, timeInfo, isMsg4, hqPrcs,
+                                     numTbs, tbStrtIdx, cntHqPrcs)
+RgSchDlHqEnt            *hqE;
+CmLteTimingInfo         timeInfo;
+Bool                    *isMsg4;
+RgSchDlHqProcCb         **hqPrcs;
+U8                      *numTbs;
+S8                      *tbStrtIdx;
+U8                      *cntHqPrcs;
+RgSchCellCb             *cell;
+#endif
+{
+   RgSchDlHqTbCb        *tbCb;
+   RgSchDlHqProcCb      *hqP;
+   CmLteTimingInfo      schdSfTime;
+   RgSchTddDlAscSetIdxK ascIdx;
+   U8                   noFdbks;
+   U8                   i;
+   U8                   idx;
+   U8                   dlIdx;
+   CmLListCp            *lnk;
+   CmLList              *node;
+
+   *cntHqPrcs = 0;
+   if (hqE->msg4Proc)
+   {
+      if (RGSCH_TIMEINFO_SAME(hqE->msg4Proc->tbInfo[0].fdbkTime, timeInfo))
+      {
+          *isMsg4 = TRUE;
+          hqPrcs[*cntHqPrcs] = hqE->msg4Proc;
+          tbStrtIdx[*cntHqPrcs] = 0;
+          numTbs[*cntHqPrcs] = 1;
+          (*cntHqPrcs)++;
+          RETVALUE(ROK);
+      }
+   }
+   ascIdx = rgSchTddDlAscSetIdxKTbl[cell->ulDlCfgIdx][timeInfo.subframe];
+   noFdbks = ascIdx.numFdbkSubfrms;
+
+   for(idx=0; idx<noFdbks; idx++)
+   {
+      /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output 
+       * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is 
+       * serving the purpose */
+      RGSCHDECRFRMCRNTTIME(timeInfo,schdSfTime,ascIdx.subfrmNum[idx]);
+      dlIdx = rgSCHUtlGetDlSfIdx(cell, &schdSfTime);
+      lnk = &hqE->ue->dl.dlSfHqInfo[dlIdx].hqPLst;
+      node = lnk->first;
+      while (node)
+      {
+         hqP = (RgSchDlHqProcCb*)node->node;
+         node = node->next; 
+
+         numTbs[*cntHqPrcs] = 0;
+         tbStrtIdx[*cntHqPrcs] = -1;
+         for (i = 0; i < 2; i++)
+         {
+            /* Extra:check which TB is waiting for feedback */
+            if (hqP->tbInfo[i].state == HQ_TB_WAITING)
+            {
+               if (tbStrtIdx[*cntHqPrcs] == -1)
+               {
+                  tbStrtIdx[*cntHqPrcs] = i;
+               }
+               numTbs[*cntHqPrcs]++;
+            }
+         }
+         if (numTbs[*cntHqPrcs] > 0)
+         {
+            hqPrcs[*cntHqPrcs] = hqP;
+            (*cntHqPrcs)++;
+         }
+      }
+
+      /* AN REP Hq Procs */
+      node = cell->subFrms[dlIdx]->ackNakRepQ.first;
+      while(node)
+      {
+         tbCb = (RgSchDlHqTbCb *)(node->node);
+         hqP = tbCb->hqP;
+
+         numTbs[*cntHqPrcs] = 0;
+         tbStrtIdx[*cntHqPrcs] = -1;
+         for (i = 0; i < 2; i++)
+         {
+            /* Extra:check which TB is waiting for feedback */
+            if (hqP->tbInfo[i].state == HQ_TB_WAITING)
+            {
+               if (tbStrtIdx[*cntHqPrcs] == -1)
+               {
+                  tbStrtIdx[*cntHqPrcs] = i;
+               }
+               numTbs[*cntHqPrcs]++;
+            }
+         }
+         if (numTbs[*cntHqPrcs] == 2)
+         {
+            node = node->next;
+         }
+         if (numTbs[*cntHqPrcs] > 0)
+         {
+            hqPrcs[*cntHqPrcs] = hqP;
+            (*cntHqPrcs)++;
+         }
+
+         node = node->next;
+      }
+   }
+
+
+   RETVALUE(ROK);
+}
+#else  /* LTE_TDD */
+/** * @brief Handler for fetching Harq Proc given the timming information.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmHqProcByTime
+ *     
+ *     This function shall fetch the harq proc using the timing information.
+ *           
+ *  @param[in]  RgSchDlHqEnt    *hqE
+ *  @param[in]  CmLteTimingInfo timeInfo
+ *  @param[in]  Bool            *isMsg4
+ *  @param[out] U8              *numTbs
+ *  @param[out] S8              *tbStrtIdx 
+ *  @return     RgSchDlHqProcCb*
+ *      -# RgSchDlHqProcCb* 
+ *      -# NULLP 
+ **/
+#ifdef ANSI
+PUBLIC RgSchDlHqProcCb *rgSCHDhmHqProcByTime
+(
+RgSchDlHqEnt            *hqE,
+CmLteTimingInfo         timeInfo,
+Bool                    *isMsg4,
+RgSchDlSf               *sf
+)
+#else
+PUBLIC RgSchDlHqProcCb *rgSCHDhmHqProcByTime(hqE, timeInfo,
+                                              isMsg4,sf)
+RgSchDlHqEnt            *hqE;
+CmLteTimingInfo         timeInfo;
+Bool                    *isMsg4;
+RgSchDlSf               *sf;
+#endif
+{
+   if (hqE->msg4Proc)
+   {
+      if (RGSCH_TIMEINFO_SAME(hqE->msg4Proc->tbInfo[0].timingInfo, timeInfo))
+      {
+          *isMsg4    = TRUE;
+          RETVALUE(hqE->msg4Proc);
+      }
+   }
+   
+   RETVALUE(NULLP);
+}
+#endif
+
+/** * @brief Handler for handling the harq transaction failure.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmHqTbTrnsFail
+ *     
+ *     This function handled the harq TB transaction failure :
+ *     - If retries have not reached maximum, add to the reTx Q.
+ *     - else do error recovery.
+ *           
+ *  @param[in]  RgSchCellCb             *cell
+ *  @param[in]  RgSchDlHqProcCb         *hqP
+ *  @param[in]  U8                      tbCnt
+ *  @param[out] Bool                    *isMaxRetx
+ *  @return    Void
+ *             -#None.
+ *      
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqTbTrnsFail
+(
+RgSchCellCb             *cell,
+RgSchDlHqProcCb         *hqP,
+U8                      tbCnt,
+Bool                    *isMaxRetx
+)
+#else
+PUBLIC Void rgSCHDhmHqTbTrnsFail(cell, hqP, tbCnt, isMaxRetx)
+RgSchCellCb             *cell;
+RgSchDlHqProcCb         *hqP;
+U8                      tbCnt;
+Bool                    *isMaxRetx;
+#endif
+{
+   RgSchDlHqEnt         *hqE;
+   U8                   maxHqTx;
+
+   TRC2(rgSCHDhmHqTbTrnsFail)
+
+   hqE = hqP->hqE;
+
+   /* Fetch the maximum number of harq transmissions */
+   if (hqE->msg4Proc == hqP)
+   {
+#ifdef RGR_V1
+      if(hqP->hqE->raCb->expiryTime.sfn == RGSCH_CONTRES_EXP)
+      {
+         RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
+               "rgSCHDhmHqTbTrnsFail contRes exp(): tmpCRNTI = %u",
+               hqP->hqE->raCb->tmpCrnti);
+         rgSCHRamMsg4Done(cell, (RgSchRaCb *)hqP->hqE->raCb);
+         RETVOID;
+      }
+#endif
+      maxHqTx  = cell->dlHqCfg.maxMsg4HqTx;
+   }
+   else
+   {
+      maxHqTx  = hqE->maxHqTx;
+   }
+
+#ifdef MAC_SCH_STATS
+   if (hqE->ue != NULLP)
+   {
+      RgSchUeCb      *ueCb  = hqE->ue;
+      RgSchCmnUe     *cmnUe = (RgSchCmnUe*)ueCb->sch;
+      RgSchCmnDlUe   *dlUe  = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/
+      U8             tbs    = dlUe->mimoInfo.cwInfo[0].iTbs[0];
+      static U32 retxCnt    = 0;
+
+      {
+         ++retxCnt;
+         hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].numOfNacks++;
+      }
+      RG_SCH_CMN_DL_TBS_TO_MCS(tbs, 
+               (hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].mcs));
+   }
+#endif /* MAC_SCH_STATS */ 
+
+   RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, hqP->tbInfo, tbCnt);
+   /* Reset the PDCCH reference */
+   hqP->pdcch =  NULL;
+   if (hqP->tbInfo[tbCnt].txCntr < maxHqTx)
+   {
+      hqP->tbInfo[tbCnt].state = HQ_TB_NACKED;
+
+      if((hqE->ue != NULLP) && (hqE->ue->isDrxEnabled == TRUE))
+      {
+
+         /*If DRX is enabled for the UE, we need to start the HARQ RTT timer
+          * for the UE. Addtion to the retransmission queue will be done on
+          * HARQ RTT timer expiry.--*/
+         switch(hqP->tbInfo[tbCnt ^ 1].state)
+         {
+            case HQ_TB_ACKED:
+               /*As the first TB is ACKED we have not started HARQ RTT for the
+                * HqP, so start it here.*/
+               //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+               rgSCHDhmHqPDelFrmInUseLst(hqP);
+               /* CA Dev Start */
+               rgSCHDrxStartHarqRTTTmr(hqP->hqE->ue->cell, hqP, tbCnt);
+               /* CA Dev End*/
+#ifdef LTEMAC_SPS
+               /* Integration fix */   
+               /* Setting cntrRetxAllocFail to MAX value here */
+               /* Since the hqP entry is already deleted from inUse list of HqEntity
+                  setting the value here will ensure the entry is not deleted
+                  again during release harq proc */
+               if ( (hqP->sch != (RgSchCmnDlHqProc *)NULLP) && 
+                     (RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)))
+               {
+                  hqP->tbInfo[0].cntrRetxAllocFail = RG_SCH_MAX_RETX_ALLOC_FAIL;
+                  if (hqP->tbInfo[1].txCntr)
+                  {
+                     hqP->tbInfo[1].cntrRetxAllocFail = RG_SCH_MAX_RETX_ALLOC_FAIL;
+                  }
+               }
+#endif
+               break;
+            case HQ_TB_NACKED:
+               /*As the first TB is NACKED we have already started HARQ RTT for the
+                * HqP, so dont start it here, just delete from in use queue.*/
+               //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+               rgSCHDhmHqPDelFrmInUseLst(hqP);
+               break;
+            case HQ_TB_WAITING:
+               /*As this is the first TB to be fed back and is NACKED start
+                * the HARQ RTT here.*/
+               /* CA Dev Start */
+               rgSCHDrxStartHarqRTTTmr(hqP->hqE->ue->cell, hqP,tbCnt);
+               /* CA Dev End*/
+               break;
+         }
+         RETVOID;
+      }
+      /* extra:check if already removed as part of other TB processing
+       * then donot remove from InUse Q */
+      /* Check if other TB is not waiting for feedback.
+       * Makinf sure hqP is present in inUse Queue until
+       * it is fedback for all its TBs */
+      switch(hqP->tbInfo[tbCnt ^ 1].state)
+      {
+         case HQ_TB_ACKED:
+            /*Fix for ccpu00113296 - Do not delete for Msg4 Harq Entities*/
+            if(hqE->msg4Proc != hqP)
+            {
+              //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+              rgSCHDhmHqPDelFrmInUseLst(hqP);
+            }
+            /* Retransmission needs to be done. Add to the scheduler Q */
+            rgSCHUtlDlProcAddToRetx(hqP->hqE->cell, hqP);
+            break;
+         case HQ_TB_NACKED:
+            /*Fix for ccpu00113296 - Do not delete for Msg4 Harq Entities*/
+            if(hqE->msg4Proc != hqP)
+            {
+              //cmLListDelFrm(&hqE->inUse, &hqP->lnk);
+              rgSCHDhmHqPDelFrmInUseLst(hqP);
+            }
+            break;
+         case HQ_TB_WAITING:
+            /* Retransmission needs to be done. Add to the scheduler Q */
+            /* CA Dev Start*/
+            rgSCHUtlDlProcAddToRetx(hqP->hqE->cell, hqP);
+            /* CA Dev End*/
+            break;
+      }
+      *isMaxRetx = FALSE; 
+   }
+   else
+   {
+      /* Failure Notification */
+      if (hqE->msg4Proc == hqP)
+      {
+       /* SR_RACH_STATS : MSG4 Max Retx Fail*/
+         rgNumMsg4FailMaxRetx++;
+#ifdef TENB_STATS
+         hqE->cell->tenbStats->sch.msg4Fail ++;
+#endif
+
+         /* Perform RAM MSG4 done processing */
+         RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
+               "rgSCHDhmHqTbTrnsFail(): hq max retx fail: tmpCRNTI = %u",
+               hqP->hqE->raCb->tmpCrnti);
+         rgSCHRamMsg4Done(cell, (RgSchRaCb *)hqP->hqE->raCb);
+      }
+      else
+      {
+         /* Release the Harq Proc */
+         rgSCHDhmRlsHqpTb(hqP, tbCnt, TRUE);
+      }
+      *isMaxRetx = TRUE; 
+   }
+
+   RETVOID;
+} /* rgSCHDhmHqTbTrnsFail */
+
+PUBLIC U32 rgHqRvStats[2][4][2] = {{{0, 0}, {0, 0}, {0, 0}, {0, 0}}, 
+                                   {{0, 0}, {0, 0}, {0, 0}, {0, 0}}};
+#ifdef LTE_TDD
+#ifdef LTE_ADV
+/** * @brief Function to decode the position of HarqFb for M=1.
+ *
+ * @details
+ *
+ *     Function : rgSchGetHqFdbkPosForM1
+ *           
+ *  @param[in]  RgSchUeCb            *ue,
+ *  @param[in]  RgSchDlHqProcCb      *hqP,
+ *  @param[in]  U8                 *isAck, 
+ *  @param[in]  RgTfuHqInfo          *fdbk,
+ *  @param[in]  U8                   tbIdx,
+ *  @param[in]  RgSchTddANInfo       *anInfo;
+ *  @return     RETVOID
+ **/
+#ifdef ANSI
+PRIVATE Void rgSchGetHqFdbkPosForM1
+(
+ RgSchUeCb            *ue,
+ RgSchDlHqProcCb      *hqP,
+ U8                  *isAck, 
+ RgTfuHqInfo          *fdbk,
+ U8                   tbIdx,
+ RgSchTddANInfo       *anInfo
+ )
+#else
+PRIVATE Void rgSchGetHqFdbkPosForM1(ue,hqP,isAck,fdbk,tbIdx,anInfo)
+ RgSchUeCb            *ue;
+ RgSchDlHqProcCb      *hqP;
+ U8                   *isAck;
+ RgTfuHqInfo          *fdbk;
+ U8                   tbIdx;
+ RgSchTddANInfo       *anInfo;
+#endif
+{
+   if((ue != NULLP))
+   {
+      /* handle pusch and pucch cases */
+      /* PUSCH:: Fdbks are in the increasing order
+       * of servCellIdx as per 36.212 section 5.2.26*/
+      switch(ue->f1bCsAVal)
+      {
+         case RG_SCH_A_VAL_2:
+            {
+               if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) 
+               {
+                  *isAck = fdbk->isAck[1];/*SCell*/
+               }
+               else
+               {
+                  *isAck = fdbk->isAck[0];/*PCell*/
+               }
+               break;
+            }
+         case RG_SCH_A_VAL_3:
+            {
+                  if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) 
+                  {
+                     U8 cellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
+                           hqP->hqE->cell->cellId,
+                           hqP->hqE->ue);
+
+                     if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[cellIdx]->txMode.txModeEnum) > 1)
+                     {/*SCell - mimo mode*/
+                        if(TRUE == fdbk->isPusch)
+                        {
+                           *isAck = fdbk->isAck[tbIdx + 1];
+                        }
+                        else
+                        {
+                           *isAck = fdbk->isAck[tbIdx];
+                        }
+                     }
+                     else
+                     {/*SCell - siso mode*/
+                        *isAck = fdbk->isAck[2];
+                     }
+                  }else
+                  {
+                     if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1)
+                     {/*Primary Cell - mimo mode*/
+                        *isAck = fdbk->isAck[tbIdx];
+                     }
+                     else
+                     {/*Primary Cell - siso mode*/
+                        if((TRUE == fdbk->isPusch) && (FALSE == anInfo->isSpsOccasion))
+                        {
+                           /* If fdbk is on PUSCH but its not an SPS occasion*/
+                           *isAck = fdbk->isAck[0];
+                        }
+                        else
+                        {
+                           /* If fdbk is on PUCCH or its an SPS occasion*/
+                           *isAck = fdbk->isAck[2];
+                        }
+                     }
+                  }
+               break;
+            }
+         case RG_SCH_A_VAL_4:
+            {
+               if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) 
+               {
+                  *isAck = fdbk->isAck[tbIdx + 2];
+               }
+               else
+               {
+                  *isAck = fdbk->isAck[tbIdx];
+               }
+               break;
+            }
+         default:
+            break;
+      }
+   }
+   RETVOID;
+}/* End of rgSchGetHqFdbkPosForM1 */
+
+/** * @brief Function to decode the position of HarqFb for M>=2 cases.
+ *
+ * @details
+ *
+ *     Function : rgSchGetHqFdbkPosForM234
+ *           
+ *  @param[in]  RgSchUeCb            *ue,
+ *  @param[in]  RgSchDlHqProcCb      *hqP,
+ *  @param[in]  U8                   *isAck, 
+ *  @param[in]  RgTfuHqInfo          *fdbk,
+ *  @param[in]  U8                   tbIdx,
+ *  @param[in]  RgSchTddANInfo       *anInfo;
+ *  @param[in]  CmLteTimingInfo      timeInfo;
+ *  @return     RETVOID
+ **/
+#ifdef ANSI
+PRIVATE Void rgSchGetHqFdbkPosForM234
+(
+ RgSchUeCb            *ue,
+ RgSchDlHqProcCb      *hqP,
+ U8                   *isAck, 
+ RgTfuHqInfo          *fdbk,
+ U8                   tbIdx,
+ RgSchTddANInfo       *anInfo,
+ U8                   M,
+ CmLteTimingInfo      timeInfo
+ )
+#else
+PRIVATE Void rgSchGetHqFdbkPosForM234(ue,hqP,isAck,fdbk,tbIdx,anInfo,M,timeInfo)
+ RgSchUeCb            *ue;
+ RgSchDlHqProcCb      *hqP;
+ U8                  *isAck;
+ RgTfuHqInfo          *fdbk;
+ U8                   tbIdx;
+ RgSchTddANInfo       *anInfo;
+ U8                    M;
+ CmLteTimingInfo      timeInfo;
+#endif
+{
+   U8                   fdbkIdx;
+   Bool                 isSCell;
+   RgSchTddANInfo       *pCellAnInfo;
+   U8                   incr = 0;
+
+   if(NULLP != ue)
+   {
+      isSCell = RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell);
+      pCellAnInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo, RGSCH_PCELL_INDEX);
+
+      if(TRUE == fdbk->isPusch)
+      {
+         if(TRUE == isSCell) 
+         {/*SCell*/
+            if (anInfo->wUlDai == 3)
+            {
+               incr = anInfo->wUlDai;
+            }
+            else
+            {
+               incr = M;
+            }
+            if(1 == anInfo->ulDai)
+            {
+               fdbkIdx = (hqP->tbInfo[tbIdx].dai - 1) + 
+                  hqP->tbInfo[tbIdx].tbIdx + incr;
+            }
+            else
+            {
+               fdbkIdx = (hqP->tbInfo[tbIdx].dai - 1) + incr;
+            }
+         }
+         else
+         {/*PCell*/
+            if(1 == anInfo->ulDai)
+            {
+               if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1)
+               {
+                  fdbkIdx = (hqP->tbInfo[tbIdx].dai - 1) + (hqP->tbInfo[tbIdx].tbIdx);
+               }
+               else
+               {
+                  fdbkIdx = (hqP->tbInfo[tbIdx].dai) - 1; 
+               }
+            }
+            else
+            {
+               fdbkIdx = (hqP->tbInfo[tbIdx].dai) - 1; 
+            }
+         }
+      }
+      else
+      {/*PUCCH*/
+         if(TRUE == isSCell) 
+         {
+            /* pucchFdbkIdx is set to DAI hence -1 to get index */
+            fdbkIdx = ((hqP->tbInfo[tbIdx].pucchFdbkIdx) + M -1); 
+         }
+         else
+         {
+            if(M > 2)
+            {
+               /* SPS occasion feedback in case of M > 2 will
+                * be always present in the index 0*/
+#ifdef LTEMAC_SPS
+               if(hqP->spsN1PucchRes.pres == TRUE)
+               {/* SPS occasion hq proc */
+                  fdbkIdx = 0;
+               }else 
+#endif
+               if((NULLP != pCellAnInfo) && 
+                     (pCellAnInfo->dlDai != pCellAnInfo->ulDai))
+               {
+                  fdbkIdx = hqP->tbInfo[tbIdx].pucchFdbkIdx; 
+               }else
+               {/* NO SPS occasion was present in the bundle*/
+                  fdbkIdx = hqP->tbInfo[tbIdx].pucchFdbkIdx - 1; 
+               }
+            }
+            else
+            {
+               fdbkIdx = hqP->tbInfo[tbIdx].pucchFdbkIdx - 1; 
+            }
+         }
+      }
+      *isAck = fdbk->isAck[fdbkIdx];
+#ifdef DLHQ_STATS
+      static RgSchDlHqProcCb      *temp = NULLP;
+      if (temp != hqP->tbInfo[tbIdx].hqP)
+      {
+         statsCnt = statsCnt % 10000;
+         dlHqStats[statsCnt].cellId = hqP->hqE->cell->cellId;
+         dlHqStats[statsCnt].sfn = hqP->tbInfo[tbIdx].timingInfo.sfn; 
+         dlHqStats[statsCnt].sf = hqP->tbInfo[tbIdx].timingInfo.subframe; 
+         dlHqStats[statsCnt].ack = *isAck;
+         dlHqStats[statsCnt].fdbkIdx = fdbkIdx;
+         dlHqStats[statsCnt].ue = hqP->hqE->ue->ueId;;
+         if (anInfo)
+            dlHqStats[statsCnt].ulDai = incr;
+         if(TRUE == fdbk->isPusch)
+         {
+            dlHqStats[statsCnt].dlDai = hqP->tbInfo[tbIdx].dai;
+         }
+         else
+         {
+            dlHqStats[statsCnt].dlDai = hqP->tbInfo[tbIdx].pucchFdbkIdx;
+         }
+         if (*isAck != 1)
+         {
+            dlHqStats[statsCnt].ack0 = fdbk->isAck[0];
+            dlHqStats[statsCnt].ack1 = fdbk->isAck[1];
+            dlHqStats[statsCnt].ack2 = fdbk->isAck[2];
+            dlHqStats[statsCnt].ack3 = fdbk->isAck[3];
+            dlHqStats[statsCnt].ack4 = fdbk->isAck[4];
+            dlHqStats[statsCnt].ack5 = fdbk->isAck[5];
+            dlHqStats[statsCnt].ack6 = fdbk->isAck[6];
+            dlHqStats[statsCnt].ack7 = fdbk->isAck[7];
+         }
+         statsCnt++; 
+         temp = hqP->tbInfo[tbIdx].hqP;
+      }
+#endif
+   }/*ue*/
+   RETVOID;
+}/*rgSchGetHqFdbkPosForM234*/
+#endif/*LTE_ADV*/
+
+/*
+ * @brief Handler for HARQ feedback received for DL transmission.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmHqFdbkInd
+ *
+ *     This function shall act on the feedback received from TOM for DL
+ *     transmission. If the feedback for msg4 is final (after max transmissions
+ *     or ACK) inform RAM that Msg4 transmission is done.
+ *
+ *
+ *  @param[in]  Void                *cb
+ *  @param[in]  U8                  cbType
+ *  @param[in]  RgSchCellCb         cellCb
+ *  @param[in]  CmLteTimingInfo     timeInfo 
+ *  @param[in]  TfuHqInfo           *fdbk
+ *  @param[in]  RgInfRlsHqInfo      *rlsHqBufs
+ *  @param[in]  RgSchErrInfo        *err
+ *  @return     S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmHqFdbkInd
+(
+Void                 *cb,
+U8                   cbType,
+RgSchCellCb          *cellCb,
+CmLteTimingInfo      timeInfo,
+TfuHqInfo            *fdbk,
+RgInfRlsHqInfo       *rlsHqBufs,
+RgSchErrInfo         *err
+)
+#else
+PUBLIC S16 rgSCHDhmHqFdbkInd(cb, cbType, cellCb, timeInfo, fdbk, rlsHqBufs, err)
+Void                    *cb;
+U8                      cbType;
+RgSchCellCb             *cellCb;
+CmLteTimingInfo         timeInfo;
+TfuHqInfo               *fdbk;
+RgInfRlsHqInfo          *rlsHqBufs;
+RgSchErrInfo            *err;
+#endif
+{
+   RgSchCellCb *sCell = NULLP;
+   RgSchDlHqEnt      *hqE;
+   /*ccpu00127339 - MOD - change to avoid the crash*/
+   RgSchUeCb         *ue = NULLP;
+   RgSchDlSf         *sf;
+   Bool              isMsg4 = FALSE;
+   RgSchRaCb         *raCb = NULLP;
+   U16               rnti=0;
+   /* Maximum possible HARQ processes in UL-DL configuration 5 that is
+    * given feedback at a time */
+   RgSchDlHqProcCb   *hqPrcs[(RGSCH_NUM_SUB_FRAMES-1)*5];  /*MAX 5 Cells*/
+   U8                numTb[(RGSCH_NUM_SUB_FRAMES-1)*5];
+   S8                tbStrtIdx[(RGSCH_NUM_SUB_FRAMES-1)*5];
+   U8                hqCnt;
+   U8                idx;
+   RgSchTddANInfo    *anInfo = NULLP;
+   U8                isAck = 0;
+   U8                tbCnt;
+   RgrTddAckNackMode ackNackMode;
+   Bool              hqRls = FALSE;
+   RgSchDlSf         *nxtDlsf = NULLP;
+   /* U8                rcvCnt = 0; */
+   CmLteTimingInfo   nxtfrm = {0,0};
+   Bool              anUpd = FALSE;
+   Bool              maxHqRetxReached;
+#ifdef LTEMAC_SPS
+   Bool              hasRelPdcch = FALSE;
+#endif
+
+#if ((defined LTEMAC_SPS_AN_MUX) || (defined LTE_ADV))
+   RgSchTddDlAscSetIdxK    ascIdx;
+   U8                      noFdbks;
+#endif
+
+#ifdef LTEMAC_SPS_AN_MUX
+   Bool                    isPusch   = FALSE;   
+   U8                      tmpIdx;
+   U8                      hIdx;   
+   /* Subframes in which transmissions are scheduled and whose feedback can come
+    * in this subframe. Used only for Multiplexing mode */
+   CmLteTimingInfo         schdSfTime[RGSCH_TDD_MAX_FDBK];
+#ifdef RGSCH_SPS_STATS
+   RgSchCmnDlHqProc        *cmnHqDl;
+#endif
+#endif
+#ifdef LTE_ADV
+   U8                  sCellActCePres = 0;
+#endif
+/* LTEMAC_SPS_AN_MUX*/
+   RgrSchFrmt1b3TypEnum uciFrmtTyp  = RG_SCH_UCI_FORMAT1A_1B; 
+   TRC2(rgSCHDhmHqFdbkInd)
+
+   if (cbType == RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB)
+   {
+      raCb     = (RgSchRaCb *)(cb);
+      ackNackMode = RGR_TDD_ACKNACK_MODE_BUNDL;
+      hqE      = raCb->dlHqE;
+      /* ccpu00139061 Fix */
+      rnti     = raCb->tmpCrnti;
+   }
+   else
+   {
+      ue       = (RgSchUeCb *)(cb);
+      ackNackMode = ue->dl.ackNackMode;
+      hqE      = RG_SCH_CMN_GET_UE_HQE(ue, cellCb);
+      rnti     = ue->ueId;
+#ifdef LTEMAC_SPS_AN_MUX
+      isPusch = fdbk->isPusch;
+#endif
+
+#ifdef LTEMAC_SPS      
+      if (RGSCH_TIMEINFO_SAME(timeInfo, ue->relPdcchFbkTiming))
+      {
+         hasRelPdcch = TRUE;
+      }
+#endif
+   }
+   
+#if ((defined LTEMAC_SPS_AN_MUX) || (defined LTE_ADV))
+   ascIdx = rgSchTddDlAscSetIdxKTbl[cellCb->ulDlCfgIdx][timeInfo.subframe];
+   noFdbks = ascIdx.numFdbkSubfrms;
+#endif
+#ifdef LTEMAC_SPS_AN_MUX
+   /* Calculate the subframe time at which transmissions should have happened to
+    * receive feedback in this subframe */
+   if (ackNackMode == RGR_TDD_ACKNACK_MODE_MULT)
+   {
+      for(idx=0; idx<noFdbks; idx++)
+      {
+         /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output 
+          * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is 
+          * serving the purpose */
+          RGSCHDECRFRMCRNTTIME(timeInfo,schdSfTime[idx],ascIdx.subfrmNum[idx]);
+      }
+   }
+#endif
+
+   rgSCHDhmHqProcByFdbkTime(hqE, timeInfo, &isMsg4, hqPrcs, numTb, \
+                            tbStrtIdx, &hqCnt,hqE->cell);
+   /* Fetch the harqProc from the inUse list */
+#ifdef LTEMAC_SPS
+   if ((FALSE == hasRelPdcch) && (hqCnt == 0))
+#endif
+   if(hqCnt == 0)
+   {
+      err->errType   = RGSCHERR_DHM_FDBK_IND;
+      err->errCause  = RGSCHERR_DHM_FDBK_IND_INVALID_CB;
+      RETVALUE(RFAILED);
+   }
+
+   /* ccpu00147469 : This code is moved below as here this code always try to
+    * get the primary cell aninfo. it is due to hqE->cell->cellId as it is
+    * cellId of PCEll
+    */
+
+   if(fdbk->hqFdbkMode == TFU_ACK_NACK_SPECIAL_BUNDLING)
+   {
+      rgSCHDhmPrcSplBundlFdbk(cellCb, fdbk, hqCnt);    
+   }
+
+#ifdef TFU_TDD
+#endif
+
+#ifdef LTEMAC_SPS_AN_MUX
+   /* Check if feedback came on configured UL SPS grant in Muxing mode */
+  if((ackNackMode == RGR_TDD_ACKNACK_MODE_MULT) && 
+        (isPusch == TRUE) )
+   {
+      hIdx = 0;
+      /* Pick the valid feedbacks out of M feedbacks */
+      for(idx=0; idx<noFdbks; idx++)
+      {
+         /* Skip the feedback if hqProc[idx] did not transmit in schdSf[idx] 
+          * and no release pdcch is sent in prevTime */
+         /* TODO: SPS_TDD: Check this while testing */
+         if ((hqPrcs[hIdx] && !RGSCH_TIMEINFO_SAME(hqPrcs[hIdx]->\
+                     tbInfo[(S16)(tbStrtIdx[hIdx])].timingInfo,\
+                        schdSfTime[idx])) &&
+               !RGSCH_TIMEINFO_SAME(ue->relPdcchTxTime, schdSfTime[idx]))
+         { 
+            /* Discard the feedback which is corresponding to a subframe in
+             * which no DL transmission took place */
+            tmpIdx = idx+1;
+            while(tmpIdx < noFdbks)
+            {
+               fdbk->isAck[tmpIdx-1] = fdbk->isAck[tmpIdx];
+               fdbk->isAck[tmpIdx-1] = fdbk->isAck[tmpIdx];
+               tmpIdx++;
+            }
+            rcvCnt--;
+            ++hIdx;
+         }
+      } /* end of for loop */
+   } /* end of configured UL SPS grant check */
+#endif   
+#ifdef CA_DBG
+  {
+     if(ue)
+     {
+        gHqFdbkCount++;
+     }
+  }
+
+#endif   
+
+  for(idx=0;idx < hqCnt; idx++)
+  {
+     /* Fix for CR ccpu00147469: Get the anInfo for each harq proc */
+     if(ue)
+     {
+#ifdef LTE_ADV
+        U8 servCellIdx = rgSchUtlGetServCellIdx(hqPrcs[idx]->hqE->cell->instIdx,
+        hqPrcs[idx]->hqE->cell->cellId,ue);
+
+        if(ue->cellInfo[servCellIdx]->sCellState != RG_SCH_SCELL_ACTIVE)  
+        {
+           continue; 
+        }
+        anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo,servCellIdx);
+#else
+        anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo,RGSCH_PCELL_INDEX);
+#endif
+        if(anInfo == NULLP)
+        {
+           RGSCHDBGINFO(cellCb->instIdx,(rgSchPBuf(cellCb->instIdx), 
+                    "Ack Rcvd. No Ack/Nack feedback available \n"));
+           RETVALUE(RFAILED);
+        }
+     }
+
+     sCell = hqPrcs[idx]->hqE->cell;
+     rlsHqBufs = &(sCell->rlsHqArr[sCell->crntHqIdx]);
+     rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0;
+     for (tbCnt = tbStrtIdx[idx]; (tbCnt-tbStrtIdx[idx]) < numTb[idx]; tbCnt++)
+     {
+        /* Fix : syed MultiUe per TTI crash in TA List. */
+        hqRls = FALSE;
+        maxHqRetxReached = FALSE;
+        /* Remove the harq process from the subframe */
+        sf = rgSCHUtlSubFrmGet(cellCb, hqPrcs[idx]->tbInfo[tbCnt].timingInfo);
+
+        if(NULLP != ue)
+        {
+           uciFrmtTyp = ue->dl.dlSfHqInfo[cellCb->cellId][sf->dlIdx].uciFrmtTyp;
+        }
+
+        if(uciFrmtTyp != RG_SCH_UCI_FORMAT1B_CS)
+        {
+           if((fdbk->hqFdbkMode != TFU_ACK_NACK_SPECIAL_BUNDLING)&&
+                 (RGR_TDD_ACKNACK_MODE_MULT == ackNackMode))
+           {
+              isAck = fdbk->isAck[hqPrcs[idx]->tbInfo[tbCnt].m];
+           }
+           else
+           {
+              /* TODO: review for TM4 and CA interaction */
+              if((TRUE == hqPrcs[idx]->cwSwpEnabled) && (1 < numTb[idx]))
+              {
+                 isAck = fdbk->isAck[!tbCnt];
+              }
+              else
+              {
+                 isAck = fdbk->isAck[tbCnt];
+              } 
+           }
+        }
+#ifdef LTE_ADV
+        else
+        {
+              if(1 == noFdbks)
+              {/* M == 1 case */
+                 rgSchGetHqFdbkPosForM1(ue, hqPrcs[idx], &isAck, fdbk, tbCnt, anInfo); 
+              }
+              else
+              {
+                 rgSchGetHqFdbkPosForM234(ue, hqPrcs[idx], &isAck, fdbk, tbCnt, anInfo, noFdbks, timeInfo); 
+              }
+        }
+#endif
+
+#ifdef BRDCM
+         /* revanth tweakin AN PUSCH to ACK always */
+         if (hqPrcs[idx]->isPuschFdbk)
+         {
+            isAck = 1;
+         }
+#endif
+
+         hqPrcs[idx]->tbInfo[tbCnt].isAckNackDtx = isAck;
+         if(cellCb->ulDlCfgIdx != 5)
+         {
+            rgSCHUtlGetNxtDlSfInfo(hqPrcs[idx]->tbInfo[tbCnt].timingInfo,\
+                                   cellCb, sf, &nxtDlsf, &nxtfrm);
+         }
+         /* Keep a tab on how many ACKs or NACKs we have received */
+         if (isAck == TFU_HQFDB_ACK)
+         {
+            hqPrcs[idx]->tbInfo[tbCnt].ackCount += 1; /* Ack counter */ 
+            rgHqRvStats[tbCnt][hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv][0]++;
+#ifdef TENB_STATS
+            sCell->tenbStats->sch.dlAckNack[tbCnt]\
+               [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++;
+#endif
+            /* Do not update the Ul Trans Time in case of raCb */
+            if (ue)
+            { 
+               rgSCHUtlHdlUlTransInd(cellCb, ue, timeInfo);
+#ifdef TENB_STATS
+               ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt] ++;
+#endif
+            }
+         }
+         else if (isAck == TFU_HQFDB_NACK)
+         {
+            hqPrcs[idx]->tbInfo[tbCnt].nackCount += 1; /* Nack Counter */ 
+            rgHqRvStats[tbCnt][hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv][1]++;
+#ifdef TENB_STATS
+            sCell->tenbStats->sch.dlNack[tbCnt]\
+               [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++;
+            sCell->tenbStats->sch.dlAckNack[tbCnt]\
+               [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++;
+#endif
+            /* Do not update the Ul Trans Time in case of raCb */
+            if (ue)
+            { 
+               rgSCHUtlHdlUlTransInd(cellCb, ue, timeInfo);
+#ifdef TENB_STATS
+               ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlNackCnt[tbCnt] ++;
+               ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt] ++;
+#endif
+            }
+#ifdef LTE_L2_MEAS           
+            if(hqPrcs[idx]->tbInfo[tbCnt].txCntr == 1)
+            {
+               cellCb->dlUlTbCnt.tbTransDlFaulty++; 
+            }   
+#endif            
+         }
+         else
+         {
+            hqPrcs[idx]->tbInfo[tbCnt].dtxCount += 1;  /* DTX Counter*/
+#ifdef TENB_STATS
+            sCell->tenbStats->sch.dlDtx[tbCnt]\
+               [hqPrcs[idx]->tbInfo[tbCnt].dlGrnt.rv]++;
+            if (ue)
+            {
+               ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlDtxCnt[tbCnt] ++;
+            }
+#endif
+#ifdef LTE_L2_MEAS           
+            if(hqPrcs[idx]->tbInfo[tbCnt].txCntr == 1)
+            {
+               cellCb->dlUlTbCnt.tbTransDlFaulty++; 
+            }   
+#endif            
+         }
+#ifdef CA_DBG
+         if(ue && RG_SCH_IS_CELL_SEC(ue,hqPrcs[idx]->hqE->cell))
+         {
+            if(isAck == TFU_HQFDB_ACK)
+            {
+               gSCellTb1AckCount++;
+               gSCellTb2AckCount++;
+            }else if(isAck == TFU_HQFDB_NACK)
+            {
+               gSCellTb1NackCount++;
+               gSCellTb2NackCount++;
+            }else
+            {
+               gSCellTb1DtxCount++;
+               gSCellTb2DtxCount++;
+            }
+         }
+         else
+         {
+            if(isAck == TFU_HQFDB_ACK)
+            {
+               gPCellTb1AckCount++;
+               gPCellTb2AckCount++;
+            }else if(isAck == TFU_HQFDB_NACK)
+            {
+               gPCellTb1NackCount++;
+               gPCellTb2NackCount++;
+            }else
+            {
+               gPCellTb1DtxCount++;
+               gPCellTb2DtxCount++;
+            }
+         }
+#endif
+         /* Check if this is repeating UE */
+         if (hqPrcs[idx]->tbInfo[tbCnt].fbkRepCntr != 0)
+         {
+            rgSCHUtlDlHqPTbRmvFrmTx(sf, hqPrcs[idx], tbCnt, TRUE);
+            /* Check if last repetition */
+            if (--hqPrcs[idx]->tbInfo[tbCnt].fbkRepCntr)
+            {
+               RGSCH_NULL_CHECK(cellCb->instIdx, nxtDlsf);
+               /* Update feedback time for this hqP TB so that 
+                * next subframe its picked up */
+               RGSCH_UPD_HQAN_FDBKTIME(&hqPrcs[idx]->tbInfo[tbCnt],\
+                                       nxtDlsf, nxtfrm);
+               RGSCH_NULL_CHECK(cellCb->instIdx, anInfo);
+               RGSCH_UPD_ANINFO_WITH_HQ(anInfo, &hqPrcs[idx]->tbInfo[tbCnt]);
+               anUpd = TRUE;
+               continue;
+            }
+            /* For a repeating UE take the decision here */
+            /* For a repeating UE take the decision here */
+            if (((hqPrcs[idx]->tbInfo[tbCnt].ackCount) > (hqPrcs[idx]->tbInfo[tbCnt].nackCount)) && 
+               ((hqPrcs[idx]->tbInfo[tbCnt].ackCount) > (hqPrcs[idx]->tbInfo[tbCnt].dtxCount)))
+            {
+               isAck = TFU_HQFDB_ACK; 
+            }
+            else if (((hqPrcs[idx]->tbInfo[tbCnt].dtxCount) > (hqPrcs[idx]->tbInfo[tbCnt].nackCount)) && 
+                  ((hqPrcs[idx]->tbInfo[tbCnt].dtxCount) > (hqPrcs[idx]->tbInfo[tbCnt].ackCount)))
+            {
+               isAck = TFU_HQFDB_DTX; 
+            }
+            else
+            {
+               isAck = TFU_HQFDB_NACK; 
+            }
+            hqPrcs[idx]->tbInfo[tbCnt].isAckNackDtx = isAck;
+         }
+         else
+         {
+            rgSCHUtlDlHqPTbRmvFrmTx(sf, hqPrcs[idx], tbCnt, FALSE);
+         }
+#ifdef LTEMAC_SPS
+         if (((isAck == TFU_HQ_NACK) || (isAck == TFU_HQ_ACK)) &&
+               ((hqPrcs[idx]->sch != (RgSchCmnDlHqProc *)NULLP) &&
+                (RG_SCH_CMN_SPS_DL_IS_SPS_TX_HQP(hqPrcs[idx])))
+            )
+         {
+            /* ACK or NACK received for SPS ACTV PDCCH
+             * Hence consider SPS ACTVN PDCCH received successfully */
+            rgSCHUtlDlProcAck(cellCb, hqPrcs[idx]);
+         }
+#endif
+         if(TFU_HQFDB_ACK == isAck)
+         {
+            /* SPS_REVIEW */
+            if (isMsg4 == TRUE)
+            {
+               if (raCb == NULLP)
+               {
+                  raCb = rgSCHDbmGetRaCb(cellCb, rnti);
+               }
+               /* Inform Random Access Module regarding the ack received */
+               if (raCb != NULLP)
+               {
+                  /*RRC Connection Setup failure issue where RRC connection
+                   * setup was not reaching UE due to message 4 HARQ failure */
+#ifdef XEON_SPECIFIC_CHANGES
+                  CM_LOG_DEBUG(CM_LOG_ID_SCH, "Msg4 Harq SUCCESS for UE(%d)\n", rnti);
+#endif 
+                  rgSCHRamMsg4Done(cellCb, raCb);
+               }
+            }
+            else /*ccpu00114124- HARQ Release for Msg4 */
+            {
+#ifdef DL_LA
+               /*Update feedback history for every Tx/Retx */
+                  rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt);
+#endif
+               RGSCH_NULL_CHECK(cellCb->instIdx, ue);
+               RG_UPD_ACQI_TRIG_WT(ue, sCell, isAck);
+#ifdef LTE_ADV
+               /* Store activation CE presence as it is required later to start
+                *activation delay timer */
+               sCellActCePres = hqPrcs[idx]->tbInfo[tbCnt].schdSCellActCe.pres; 
+#endif
+               rgSCHDhmRlsHqpTb(hqPrcs[idx], tbCnt, TRUE);
+            }
+            hqRls = TRUE;
+         }
+         else
+         {
+            /* If this Msg4 DTX, there will be 
+             * no DlHqProc as it has its own HarqProc */
+             /* SPS_REVIEW */
+            {
+               rgSCHDhmHqTbTrnsFail(cellCb, hqPrcs[idx], tbCnt, &hqRls);
+               maxHqRetxReached = hqRls;
+#ifdef DL_LA
+               if ((isMsg4 == FALSE))
+               {
+                  /*Update feedback history for every Tx/Retx */
+                  rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt);
+               }
+#endif
+               if (isMsg4 == FALSE)
+               {
+                  RGSCH_NULL_CHECK(cellCb->instIdx, ue);
+                  RG_UPD_ACQI_TRIG_WT(ue, sCell, isAck);
+               }
+            }
+         }
+
+         if(TRUE == hqRls)
+         {
+     /* MS_WORKAROUND: to increase Harq Fail Counter .
+       The status field is required for tracking the number of harq faliures at MAC*/
+         if (isAck)
+         {
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\
+               rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = TRUE;
+         }
+         else
+         {
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\
+               rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = FALSE;
+         }
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[\
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = tbCnt + 1;
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs++;
+         }
+
+         /* Handle the TA */
+         if (hqPrcs[idx]->tbInfo[tbCnt].taSnt == TRUE)
+         {
+            rgSCHDhmFdbkIndHndlTa(hqPrcs[idx], tbCnt, isAck, maxHqRetxReached);
+         }
+#ifdef LTE_ADV
+         /* Handle Scell activation */
+         if (TRUE == sCellActCePres)
+         {
+            /* Primary Cellcb needs to be retrived
+             * if the feedback is coming on pusch of 
+             * sec cell. THis needs to be considered
+             * while UL_CA*/
+            rgSCHSCellHndlFdbkInd(hqPrcs[idx], tbCnt, isAck, maxHqRetxReached);
+         }
+#endif
+      }
+     if (hqRls == FALSE)
+     {
+        hqPrcs[idx]->cwSwpEnabled = FALSE;
+     }
+      if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs)
+      {
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti;
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = 
+            hqPrcs[idx]->procId;
+         rlsHqBufs->numUes++;
+      }
+#ifdef BRDCM
+      hqPrcs[idx]->isPuschFdbk = 0;
+#endif
+   }
+
+#ifdef LTEMAC_SPS
+  /*it is possible for some TDD configurations (like TDD cfg 5) 
+   * to have multiple feedback for 13 subframes before. It is 
+   * possible in such a case to have a release sent after data
+   * thus running into a situation where we are receiving feedback
+   * for both data and relese pdcch 
+   */
+/*
+   if ( (hqCnt == 0) ||
+        (hasRelPdcch && rcvCnt > hqCnt)
+      ) 
+      */
+   if (ue && hasRelPdcch)   
+   {
+      /* Bool found      = FALSE; */
+      
+      sf = rgSCHUtlSubFrmGet(cellCb, ue->relPdcchTxTime);
+
+      /*
+      if ( !sf->relPdcch)
+      {
+         found = FALSE;
+      } 
+      */
+
+      
+#if ((defined LTEMAC_SPS_AN_MUX) || (defined LTE_ADV))
+      if(ackNackMode == RGR_TDD_ACKNACK_MODE_MULT)
+      {
+         CmLteTimingInfo txTime;
+         U8   ulDlCfgIdx = 0;
+         U8   maxFdbks   = 0;
+         U8   itr        = 0;
+
+         ulDlCfgIdx  = cellCb->ulDlCfgIdx;
+
+         maxFdbks = rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx]
+            [timeInfo.subframe].
+            numFdbkSubfrms;
+
+         for(itr=0; itr< maxFdbks; itr++)
+         {
+#ifdef LTE_ADV
+            /* Handling the case of only SPS release pdcch
+             * and no other scheduling in both the serving cells
+             * */
+            if(ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS)
+            {/* Using the sorted K table */
+               RGSCHDECRFRMCRNTTIME (timeInfo, txTime, 
+                     rgSchTddDlHqPucchResCalTbl[ulDlCfgIdx][timeInfo.subframe].subfrmNum[itr]);
+            }else
+#endif
+            {
+               RGSCHDECRFRMCRNTTIME (timeInfo, txTime, 
+                     rgSchTddDlAscSetIdxKTbl[ulDlCfgIdx][timeInfo.subframe].subfrmNum[itr]);
+            }
+
+            if (RGSCH_TIMEINFO_SAME (txTime, ue->relPdcchTxTime))
+            {
+#ifdef LTE_ADV
+               if((ue->uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS)&&
+                     (maxFdbks == 1))
+               {/* M == 1 case */
+                  if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1)
+                  {
+                     isAck = fdbk->isAck[0];
+                  }else
+                  {
+                     isAck = fdbk->isAck[2];
+                  }
+               }
+               else
+                  /* M > 1 same below logic apply. 
+                     If SPS occasion and rel pdcch is present
+                     SPS occasion after SPS release cannot 
+                     happen in a bundle
+                     */
+#endif
+               {
+                  isAck = fdbk->isAck[itr];
+               }
+               
+               rgSCHUtlDlRelPdcchFbk(cellCb, ue, isAck);
+
+               RGSCH_NULL_CHECK(cellCb->instIdx, sf->relPdcch);
+               /* Remove release PDCCH from the subframe */
+               rgSCHUtlPdcchPut(cellCb, &sf->pdcchInfo, sf->relPdcch);
+               sf->relPdcch = NULLP;
+               /* found = TRUE; */
+               break;
+            }
+
+         }
+      }
+      else
+#endif
+      {
+         RGSCH_NULL_CHECK(cellCb->instIdx, sf->relPdcch);
+         /* Remove release PDCCH from the subframe */
+         rgSCHUtlPdcchPut(cellCb, &sf->pdcchInfo, sf->relPdcch);
+         sf->relPdcch = NULLP;
+         /* found = TRUE; */
+         rgSCHUtlDlRelPdcchFbk(cellCb, ue, fdbk->isAck[0]);
+      }
+      /*
+         if ( found == FALSE ) 
+         {
+         RGSCH_NULL_CHECK(cellCb->instIdx, ue);
+         RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId,"CRNTI:%d"
+         " NO HARQ proc available for feedback:timeInfo:snf %d,subframe %d",
+         ue->ueId,timeInfo.sfn, timeInfo.subframe);
+         err->errType   = RGSCHERR_DHM_FDBK_IND;
+         err->errCause  = RGSCHERR_DHM_FDBK_IND_INVALID_CB;
+         RETVALUE(RFAILED);
+         }
+       */
+   }/*if(hqCnt==0)*/
+#endif /* LTEMAC_SPS */
+   /* Initialise the Ack/Nack feedback */
+   /* [ccpu00127651] - MOD For Msg4 Harq Proc, anInfo will not be filled while 
+      scheduling. So added a condition !isMsg4 to avoid calling the function 
+      rgSCHUtlInitUeANFdbkInfo*/
+   if((ue) && (!anUpd) && (!isMsg4))
+   {
+#ifdef LTE_ADV
+      /* TODO:: Initi the anInfo all the serving cells */
+      for(idx = 0; idx <= RG_SCH_MAX_SCELL; idx++)
+      {
+         if(ue->cellInfo[idx])
+         {
+            anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &timeInfo,idx);
+            /* Fix for CR ccpu00147693: If anInfo is there then initialize it
+             * else don't do anything. basically continue for next serving
+             * cell*/
+            if(anInfo)
+            {
+               rgSCHUtlInitUeANFdbkInfo(anInfo);
+            }
+         }
+      }
+#else
+      rgSCHUtlInitUeANFdbkInfo(anInfo);
+#endif
+   }
+
+   RETVALUE(ROK);
+}
+//#endif /* LTEMAC_SPS */
+
+#else /* LTE_TDD */
+/** * @brief Handler for HARQ feedback received for DL transmission.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmPrcFdbkForTb
+ *     
+ *                Process Hq Prc Fdbk for a TB
+ *           
+ *  @param[in]  RgSchCellCb         *cell
+ *  @param[in]  RgTfuHarqAckIndInfo *fdbk
+ *  @param[in]  RgSchErrInfo        *err
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmPrcFdbkForTb
+(
+RgSchCellCb          *cell,
+RgSchUeCb            *ue,
+RgSchDlHqProcCb      *hqP,
+RgSchDlSf            *sf,
+Bool                 isMsg4,
+U16                  rnti,
+U8                   tbCnt,
+CmLteTimingInfo      timingInfo,
+U8                   isAck,
+RgInfRlsHqInfo       *rlsHqBufs,
+RgSchErrInfo         *err
+)
+#else
+PUBLIC S16 rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, tbCnt, timingInfo, isAck, rlsHqBufs, err)
+RgSchCellCb             *cell;
+RgSchUeCb               *ue;
+RgSchDlHqProcCb         *hqP;
+RgSchDlSf               *sf;
+Bool                    isMsg4;
+U16                     rnti;
+U8                      tbCnt;
+CmLteTimingInfo         timingInfo;
+U8                      isAck;
+RgInfRlsHqInfo          *rlsHqBufs;
+RgSchErrInfo            *err;
+#endif
+{
+#ifdef DEBUGP
+   Inst    inst = cell->instIdx;
+#endif
+#ifdef RGSCH_SPS_STATS
+   RgSchCmnDlHqProc        *cmnHqDl;
+#endif
+   S16                  ret = ROK;
+   RgSchRaCb            *raCb = NULLP;
+   Bool                 hqRls=FALSE;
+   Bool                 hqFreed =FALSE;
+   Bool                 maxHqRetxReached = FALSE;
+   RgSchCmnDlUe         *ueDl = NULLP;
+   RgSchCellCb          *sCell = hqP->hqE->cell;
+#ifdef EMTC_ENABLE
+   RgSchEmtcDlSf        *emtcSf;
+   CmLteTimingInfo      frm = timingInfo;
+#endif
+
+   TRC2(rgSCHDhmPrcFdbkForTb)
+   if (ue)
+   {
+      ueDl     = RG_SCH_CMN_GET_DL_UE(ue,cell);
+   }
+   hqRls   = FALSE;
+   /* Fix : syed MultiUe per TTI crash in TA List. */
+   maxHqRetxReached = FALSE;
+
+   /* Fix : syed Consider CW to TB mapping for Hq Feedback.
+    * TODO: Need to enhance this in case of TM4 testing,
+    * when cwSwap flag is considered. */
+
+   RGSCHDBGINFO(inst, (rgSchPBuf(inst), "rgSCHDhmHqFdbkInd():\
+            tbCnt=%d , isAck=%d",tbCnt,isAck));
+   if (isAck == TFU_HQFDB_ACK)
+   {
+      hqP->tbInfo[tbCnt].ackCount += 1; /* Ack counter */
+      /*sanjay*/
+      rgHqRvStats[tbCnt][hqP->tbInfo[tbCnt].dlGrnt.rv][0]++;
+      /* Do not update the Ul Trans Time in case of raCb */
+      if (ue)
+      { 
+         rgSCHUtlHdlUlTransInd(cell, ue, timingInfo);
+#ifdef TENB_STATS
+         ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt]++;
+#endif
+
+      }
+
+#ifdef TENB_STATS
+      sCell->tenbStats->sch.dlAckNack[tbCnt]\
+         [hqP->tbInfo[tbCnt].dlGrnt.rv]++;
+
+#endif
+
+   }
+   else if (isAck == TFU_HQFDB_NACK)
+   {
+      hqP->tbInfo[tbCnt].nackCount += 1; /* Nack Counter */
+      RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), "<HARQ> HqP[%d:%d] NACKED "
+               "ue(%d)\n", hqP->procId, tbCnt, hqP->hqE->ue->ueId));
+      rgHqRvStats[tbCnt][hqP->tbInfo[tbCnt].dlGrnt.rv][1]++;
+      /* Do not update the Ul Trans Time in case of raCb */
+
+#ifdef TENB_STATS
+      sCell->tenbStats->sch.dlAckNack[tbCnt]\
+         [hqP->tbInfo[tbCnt].dlGrnt.rv]++;
+      
+      sCell->tenbStats->sch.dlNack[tbCnt]\
+         [hqP->tbInfo[tbCnt].dlGrnt.rv]++;
+
+
+#endif
+
+      if (ue)
+      { 
+         rgSCHUtlHdlUlTransInd(cell, ue, timingInfo);
+#ifdef TENB_STATS
+         ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlAckNackCnt[tbCnt]++;
+         ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlNackCnt[tbCnt] ++;
+#endif
+      }
+      /* Added Dl TB count for NACKED data*/
+#ifdef LTE_L2_MEAS
+      if(hqP->tbInfo[tbCnt].txCntr == 1)
+      {   
+         cell->dlUlTbCnt.tbTransDlFaulty++;
+      }   
+#endif         
+   }
+   else
+   {
+      RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"<HARQ> HqP[%d:%d] DTXED UE(%d)\n",
+               hqP->procId, tbCnt,hqP->hqE->ue->ueId));
+      hqP->tbInfo[tbCnt].dtxCount += 1;  /* DTX Counter*/
+
+#ifdef TENB_STATS
+      sCell->tenbStats->sch.dlDtx[tbCnt]\
+         [hqP->tbInfo[tbCnt].dlGrnt.rv]++;
+      if (ue)
+      {
+         ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(sCell)].dlDtxCnt[tbCnt]++;
+      }
+#endif
+
+
+      /* Added Dl TB count for DTXED data*/
+#ifdef LTE_L2_MEAS
+      if(hqP->tbInfo[tbCnt].txCntr == 1)
+      {   
+         cell->dlUlTbCnt.tbTransDlFaulty++;
+      }
+#endif         
+   }
+
+   /* Check if this is repeating UE */
+   if (hqP->tbInfo[tbCnt].fbkRepCntr != 0)
+   {
+      if((rgSCHDhmProcHqFdbkAckNackRep(hqP,sf,tbCnt,&isAck)) != ROK)
+      {
+         RETVALUE(ret);
+      }
+   }
+   else
+   {
+     /* For a Normal UE take the decision here */
+     hqP->tbInfo[tbCnt].isAckNackDtx = isAck;
+     {
+         rgSCHUtlDlHqPTbRmvFrmTx(sf, hqP, tbCnt, FALSE);
+     }
+   }
+   /* Process either the ACK received or max retries have occurred */
+   /* Assuming for Repetition that 2 ACKs and 2 NACKs make an NACK */
+   if (TFU_HQFDB_ACK == isAck)
+   {
+      if (isMsg4 == TRUE) 
+      {
+         /* SR_RACH_STATS : MSG4 ACK*/
+         rgNumMsg4Ack++;
+
+         if (raCb == NULLP)
+         {
+            raCb = rgSCHDbmGetRaCb(cell, rnti);
+         }
+         RGSCHDBGINFO(cell->instIdx,
+               (rgSchPBuf(cell->instIdx), "Ack Rcvd. FdbkInd for Msg4Done\n"));
+         /* Inform Random Access Module regarding the ack received */
+         if (raCb != NULLP)
+         {
+            /*RRC Connection Setup failure issue where RRC connection 
+             * setup was not reaching UE due to message 4 HARQ failure */
+            printf("\nMSG4 Ack ,calling rgSCHRamMsg4Done\n");
+            ret = rgSCHRamMsg4Done(cell, raCb);
+            hqFreed = TRUE;
+         }
+         else
+         {
+            printf("\nraCb is NULLP\n");
+         }
+      }
+      else /*ccpu00114124- HARQ Release for Msg4 */
+      {
+         RGSCH_NULL_CHECK(cell->instIdx, ueDl);
+         /* Push this harq process back to the free queue */
+         ueDl->mimoInfo.cwInfo[tbCnt].ackCnt++;
+#ifdef DL_LA
+         if(hqP->tbInfo[tbCnt].txCntr == 1)
+         {
+            rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt);
+         } 
+#endif
+         RGSCH_NULL_CHECK(cell->instIdx, ue);
+         RG_UPD_ACQI_TRIG_WT(ue, sCell,isAck);
+         rgSCHDhmRlsHqpTb(hqP, tbCnt, TRUE);
+      }
+      hqRls = TRUE;
+   }
+   else
+   {
+      {
+         if(!isMsg4)
+         {
+            RGSCH_NULL_CHECK(cell->instIdx, ueDl);
+            ueDl->mimoInfo.cwInfo[tbCnt].nackCnt++;
+#ifdef DL_LA
+            if(hqP->tbInfo[tbCnt].txCntr == 1)
+            {
+               rgSCHDhmUpdateAckNackHistory(sCell, ue, isAck, tbCnt);
+            }
+#endif
+            RGSCH_NULL_CHECK(cell->instIdx, ue);
+            RG_UPD_ACQI_TRIG_WT(ue, sCell, isAck);
+         }
+         else
+         { 
+#ifdef XEON_SPECIFIC_CHANGES
+            CM_LOG_DEBUG(CM_LOG_ID_SCH,"Msg4 Harq FAILURE for UE(%d)\n", rnti);
+#endif
+            rgNumMsg4Nack++;
+         }
+         rgSCHDhmHqTbTrnsFail(cell, hqP, tbCnt, &hqRls);
+         maxHqRetxReached = hqRls;
+      }
+   }
+
+   if(hqRls == TRUE)
+   {
+      /* MS_WORKAROUND: to increase Harq Fail Counter .
+         The status field is required for tracking the number of harq faliures at MAC*/
+      if (isAck)
+      {
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = TRUE;
+      }
+#ifdef LTE_L2_MEAS
+      else if(maxHqRetxReached)
+      {
+         /* this is to differentiat the NACK with data loss used for UU loss L2 meas */
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = 0xFF; /* RGU_NACK_LOSS; */
+      }
+#endif
+      else
+      {
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].status[\
+            rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = FALSE;
+      }
+      rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[\
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs] = tbCnt + 1;
+      rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs++;
+   }
+
+   /* Handle the TA */
+   if (hqFreed == FALSE && hqP->tbInfo[tbCnt].taSnt == TRUE)
+   {
+      rgSCHDhmFdbkIndHndlTa(hqP, tbCnt, isAck, maxHqRetxReached);
+   }
+   RETVALUE(ret);
+}  /* rgSCHDhmPrcFdbkForTb */
+/** * @brief Function to decode the position of HarqFb for eachCell.
+ *
+ * @details
+ *
+ *     Function : rgSchGetHqFdbkPos
+ *           
+ *  @param[in]  RgSchCellCb          *cell,
+ *  @param[in]  RgSchUeCb            *ue,
+ *  @param[in]  RgSchDlHqProcCb      *hqP,
+ *  @param[in]  RgrSchFrmt1b3TypEnum uciFrmtTyp, 
+ *  @param[in]  Bool                 *isAck, 
+ *  @param[in]  RgTfuHqInfo          *fdbk,
+ *  @return     RETVOID
+ **/
+#ifdef ANSI
+PUBLIC Void rgSchGetHqFdbkPos
+(
+ RgSchCellCb          *cell,
+ RgSchUeCb            *ue,
+ RgSchDlHqProcCb      *hqP,
+ RgrSchFrmt1b3TypEnum uciFrmtTyp, 
+ U8                  *isAck, 
+ RgTfuHqInfo          *fdbk
+ )
+#else
+PUBLIC Void rgSchGetHqFdbkPos(cell,ue,hqP,uciFrmtTyp,isAck,fdbk)
+ RgSchCellCb          *cell;
+ RgSchUeCb            *ue;
+ RgSchDlHqProcCb      *hqP;
+ RgrSchFrmt1b3TypEnum uciFrmtTyp;
+ U8                  *isAck;
+ RgTfuHqInfo          *fdbk;
+#endif
+{
+   if(uciFrmtTyp != RG_SCH_UCI_FORMAT1B_CS)
+   {
+      isAck[0] = fdbk->isAck[0];
+      isAck[1] = fdbk->isAck[1];
+      RETVOID;
+   }
+#ifdef LTE_ADV
+   /* LAA Making all ack for LAA CELL */
+   //if (hqP->hqE && rgSCHLaaSCellEnabled(hqP->hqE->cell))
+   if (0)
+   {
+      isAck[0] = TRUE;
+      isAck[1] = TRUE;
+      RETVOID;
+   }
+
+   if((ue != NULLP))
+   {
+      /* PUSCH:: Fdbks are in the increasing order
+       * of servCellIdx as per 36.212 section 5.2.26*/
+      switch(ue->f1bCsAVal)
+      {/* A Value */
+         case RG_SCH_A_VAL_2:
+            {
+               if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) 
+               {
+                  isAck[0] = fdbk->isAck[1];/*SCell*/
+                  isAck[1] = fdbk->isAck[1];/*SCell*/
+               }
+               else
+               {
+                  isAck[0] = fdbk->isAck[0];/*PCell*/
+                  isAck[1] = fdbk->isAck[0];/*PCell*/
+               }
+               break;
+            }
+         case RG_SCH_A_VAL_3:
+            {
+               if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) 
+               {
+#ifdef LTE_ADV
+                  U8 servCellIdx = rgSchUtlGetServCellIdx(hqP->hqE->cell->instIdx,
+                        hqP->hqE->cell->cellId,
+                        ue);
+
+                  if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[servCellIdx]->txMode.txModeEnum) > 1)
+#else
+                     if(rgSCHUtlGetMaxTbSupp(ue->cellInfo[RGSCH_PCELL_INDEX]->txMode.txModeEnum) > 1)
+#endif
+                     {  /* Sec cell is in mimo mode */
+                        /* use 0 and 1 for sec in case of pucch
+                         * and 1 and 2 in case of PUSCH as the primary cell is in
+                         * siso case as A =3 */
+                        if(!fdbk->isPusch)
+                        {
+                           isAck[0] = fdbk->isAck[0];
+                           isAck[1] = fdbk->isAck[1];
+                        }else
+                        {/* PUSCH as per 36.212 serction 5.2.26*/
+                           isAck[0] = fdbk->isAck[1];
+                           isAck[1] = fdbk->isAck[2];
+                        }
+                     }else
+                     {/* sec cell is in siso */
+                        isAck[0] = fdbk->isAck[2];
+                     }
+               }else
+               {
+                  if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1)
+                  {/* primay cell is in mimo
+                      use 0 and 1 */
+                     isAck[0] = fdbk->isAck[0];
+                     isAck[1] = fdbk->isAck[1];
+                  }else
+                  {
+                     if(!fdbk->isPusch)
+                     {
+                        isAck[0] = fdbk->isAck[2];
+                     }else
+                     {/* PUSCH as per 36.212 serction 5.2.26*/
+                        isAck[0] = fdbk->isAck[0];
+                     }
+                  }
+               }
+               break;
+            }
+         case RG_SCH_A_VAL_4:
+            {
+               if(RG_SCH_IS_CELL_SEC(ue,hqP->hqE->cell)) 
+               {
+                  isAck[0] = fdbk->isAck[2];
+                  isAck[1] = fdbk->isAck[3];
+#ifdef CA_DBG
+                  {
+                     if(isAck[0] == TFU_HQFDB_ACK)
+                     {
+                        gSCellTb1AckCount++;
+                     }else if(isAck[0] == TFU_HQFDB_NACK)
+                     {
+                        gSCellTb1NackCount++;
+                     }else
+                     {
+                        gSCellTb1DtxCount++;
+                     }
+
+                     if(isAck[1] == TFU_HQFDB_ACK)
+                     {
+                        gSCellTb2AckCount++;
+                     }else if(isAck[1] == TFU_HQFDB_NACK)
+                     {
+                        gSCellTb2NackCount++;
+                     }else
+                     {
+                        gSCellTb2DtxCount++;
+                     }
+
+                  }
+#endif
+               }
+               else
+               {
+                  isAck[0] = fdbk->isAck[0];
+                  isAck[1] = fdbk->isAck[1];
+#ifdef CA_DBG
+                  {
+                     if(isAck[0] == TFU_HQFDB_ACK)
+                     {
+                        gPCellTb1AckCount++;
+                     }else if(isAck[0] == TFU_HQFDB_NACK)
+                     {
+                        gPCellTb1NackCount++;
+                     }else
+                     {
+                        gPCellTb1DtxCount++;
+                     }
+
+                     if(isAck[1] == TFU_HQFDB_ACK)
+                     {
+                        gPCellTb2AckCount++;
+                     }else if(isAck[1] == TFU_HQFDB_NACK)
+                     {
+                        gPCellTb2NackCount++;
+                     }else
+                     {
+                        gPCellTb2DtxCount++;
+                     }
+
+                  }
+#endif
+
+               }
+               break;
+            }
+         default:
+            break;
+      }
+   }
+#endif
+   RETVOID;
+}/* End of rgSchGetHqFdbkPos */
+#ifdef LTE_ADV
+#ifdef ANSI
+PUBLIC Void rgSchGetHqFdbkPosFormat3
+(
+ RgSchDlHqProcCb      *hqP,
+ U8                   *isAck,
+ TfuHqFdbk            *fdbk
+ )
+#else
+PUBLIC Void rgSchGetHqFdbkPosFormat3(hqP,isAck,fdbk)
+ RgSchDlHqProcCb      *hqP;
+ U8                  *isAck;
+ TfuHqFdbk           *fdbk;
+#endif
+{
+   U8 cellIdx = RG_SCH_CMN_GET_CELL_IDX_FROM_HQP(hqP);
+   isAck[0] = (U8)fdbk[cellIdx]; 
+   isAck[1] = (U8)fdbk[cellIdx + 1]; 
+}
+#endif
+/** * @brief Handler for HARQ feedback received for DL transmission.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhm5gtfHqFdbkInd 
+ *     
+ *     This function shall act on the feedback received from TOM for DL
+ *     transmission. If the feedback for msg4 is final (after max transmissions
+ *     or ACK) inform RAM that Msg4 transmission is done. 
+ *     
+ *           
+ *  @param[in]  Void                *cb
+ *  @param[in]  U8                  cbType
+ *  @param[in]  RgSchCellCb         *cell
+ *  @param[in]  RgTfuHarqAckIndInfo *fdbk
+ *  @param[in]  RgInfRlsHqInfo      *rlsHqBufs
+ *  @param[in]  RgSchErrInfo        *err
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhm5gtfHqFdbkInd 
+(
+RgSchUeCb            *ue,
+RgSchCellCb          *cell,
+CmLteTimingInfo      timingInfo,
+TfuHqFdbk            fdbk,
+RgSchErrInfo         *err
+)
+#else
+PUBLIC S16 rgSCHDhm5gtfHqFdbkInd(ue, cell, timingInfo, fdbk, err)
+RgSchUeCb            *ue;
+RgSchCellCb          *cell;
+CmLteTimingInfo      timingInfo;
+TfuHqFdbk            fdbk;
+RgSchErrInfo         *err;
+#endif
+{
+   RgSchDlHqProcCb      *hqP = NULLP;   
+   CmLList              *node = NULLP;
+   CmLListCp            *lnk; 
+   S16                  ret = ROK;
+   RgSchDlSf            *sf;
+   Bool                 isMsg4 = FALSE;
+   U16                  rnti=0;
+   U16                  procId=0;
+   U8                   hqPCount = 0;
+   RgInfRlsHqInfo       *rlsHqBufs = NULLP;
+
+   TRC2(rgSCHDhm5gtfHqFdbkInd)
+
+   RGSCHDECRFRMCRNTTIME(timingInfo, timingInfo, 4); 
+
+   sf = rgSCHUtlSubFrmGet(cell, timingInfo);
+
+   lnk      = &ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst;
+   node     = lnk->first; 
+   hqPCount = lnk->count;
+   rnti     = ue->ueId;
+
+   while (hqPCount)
+   {
+      hqP = (RgSchDlHqProcCb *)node->node;
+      node = node->next;
+      rlsHqBufs = &(hqP->hqE->cell->rlsHqArr[hqP->hqE->cell->crntHqIdx]);
+      procId = hqP->procId;
+
+      rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0;
+
+      if (HQ_TB_WAITING == hqP->tbInfo[0].state)
+      {
+         rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, 0, 
+            timingInfo, fdbk, rlsHqBufs, err);
+      }
+      if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs)
+      {
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti;
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = 
+            (U8)procId;
+         rlsHqBufs->numUes++;
+      }
+      hqPCount--;
+   }
+
+   RETVALUE(ret);
+}  /* rgSCHDhm5gtfHqFdbkInd */
+
+/** * @brief Handler for HARQ feedback received for DL transmission.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmHqFdbkInd
+ *     
+ *     This function shall act on the feedback received from TOM for DL
+ *     transmission. If the feedback for msg4 is final (after max transmissions
+ *     or ACK) inform RAM that Msg4 transmission is done. 
+ *     
+ *           
+ *  @param[in]  Void                *cb
+ *  @param[in]  U8                  cbType
+ *  @param[in]  RgSchCellCb         *cell
+ *  @param[in]  RgTfuHarqAckIndInfo *fdbk
+ *  @param[in]  RgInfRlsHqInfo      *rlsHqBufs
+ *  @param[in]  RgSchErrInfo        *err
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmHqFdbkInd
+(
+Void                 *cb, 
+U8                   cbType,
+RgSchCellCb          *cell,
+CmLteTimingInfo      timingInfo,
+RgTfuHqInfo          *fdbk,
+RgInfRlsHqInfo       *rlsHqBufs,
+RgSchErrInfo         *err
+)
+#else
+PUBLIC S16 rgSCHDhmHqFdbkInd(cb, cbType, cell, timingInfo, fdbk, rlsHqBufs, err)
+Void                    *cb;
+U8                      cbType;
+RgSchCellCb             *cell;
+CmLteTimingInfo         timingInfo;
+RgTfuHqInfo             *fdbk;
+RgInfRlsHqInfo          *rlsHqBufs;
+RgSchErrInfo            *err;
+#endif
+{
+   RgSchDlHqTbCb        *tbCb;
+   RgSchDlHqEnt         *hqE = NULLP;
+   RgSchDlHqProcCb      *hqP = NULLP;   
+   CmLList              *node = NULLP;
+   CmLListCp            *lnk; 
+  /* Create and Initialize Ue it so that Its not Deferenced Unnecessarily */
+   RgSchUeCb            *ue = NULLP;
+
+   S16                  ret = ROK;
+   RgSchDlSf            *sf;
+   Bool                 isMsg4 = FALSE;
+   RgSchRaCb            *raCb = NULLP;
+   U16                  rnti=0;
+  /* Added Insure Fixes Of UR.Initialized procId  */
+   U16                  procId=0;
+   /* DTX Change: Bool is converted into U8*/
+   U8                   isAck[2]={0}; /*Changed to Array of 2*/
+   U8                   tbCnt;
+   U8                   hqPCount = 0;
+
+#ifdef LTEMAC_SPS
+   CmLteTimingInfo      fdbkRcptTime = timingInfo;
+#ifdef RGSCH_SPS_STATS
+   RgSchCmnDlHqProc        *cmnHqDl;
+#endif
+#endif
+#ifdef LTE_ADV
+   TfuHqFdbk            format3Ack[CM_LTE_MAX_CELLS *2] = {0};
+#endif
+   RgrSchFrmt1b3TypEnum uciFrmtTyp = RG_SCH_UCI_FORMAT1A_1B;
+
+   TRC2(rgSCHDhmHqFdbkInd)
+
+   /* Get the subframe associated with the feedback */
+   /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper output 
+    * if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() as it is 
+    * serving the purpose */
+   RGSCHDECRFRMCRNTTIME(timingInfo, timingInfo, 4); 
+
+   sf = rgSCHUtlSubFrmGet(cell, timingInfo);
+   if (cbType == RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB)
+   {
+      raCb     = (RgSchRaCb *)(cb);
+      hqE      = raCb->dlHqE;
+      hqP      = rgSCHDhmHqProcByTime(hqE, timingInfo, &isMsg4,\
+                                      sf);
+      if(hqP)
+      {
+         hqPCount = 1;
+      }
+      rnti     = raCb->tmpCrnti;
+   }
+   else
+   {
+      ue       = (RgSchUeCb *)(cb);
+      hqE      = RG_SCH_CMN_GET_UE_HQE(ue, cell);
+      {
+         lnk      = &ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst;
+      }
+      node     = lnk->first; 
+      hqPCount = lnk->count;
+      rnti     = ue->ueId;
+#ifdef LTE_ADV
+      uciFrmtTyp = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].uciFrmtTyp;
+#endif
+   }
+   /*
+      TO ADD STATS 
+      from Harq Proc get ueCb = hqP->hqEnt->ueCb
+      from ueCb get cmnUecb = (RgSchCmnUe *)ueCb->sch;
+      from ueCb get dlUe = (RgSchCmnDlUe)cmnUeCb->dl
+      from get cmInfo "RgSchCmnDlUeCwInfo" dlUe->mimoInfo->cwInfo[0] 
+      from get CQI from cmInfo->cqi 
+      from cmInfo get iTbs cmInfo->iTbs[0]
+      call RG_SCH_CMN_DL_TBS_TO_MCS to map iTbs=>MCS 
+      Update stats in cellCb
+      cellCb->hqFailStats[cmInfo->cqi].mcs = RG_SCH_CMN_DL_TBS_TO_MCS(cmInfo->iTbs[0]);
+      if (fdbk->isAck == TRUE)
+      cellCb->hqFailStats[cmInfo->cqi].numOfNacks += 1;
+      else
+      cellCb->hqFailStats[cmInfo->cqi].numOfAcks += 1;
+      DL Ack/Nack statistics
+    */   
+#ifdef MAC_SCH_STATS
+   if (hqE->ue != NULLP)
+   {
+      RgSchUeCb      *ueCb  = hqE->ue;
+      RgSchCmnUe     *cmnUe = (RgSchCmnUe*)ueCb->sch;
+      RgSchCmnDlUe   *dlUe  = RG_SCH_CMN_GET_DL_UE(ueCb,hqE->cell);/*CA dev*/
+      U8             tbs    = dlUe->mimoInfo.cwInfo[0].iTbs[0];
+      static U32 retxCnt    = 0;
+
+      if (fdbk->isAck[0] == TFU_HQFDB_ACK)
+      {
+         hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].numOfAcks++;
+      }
+      else
+      {
+         ++retxCnt;
+         hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].numOfNacks++;
+      }
+      RG_SCH_CMN_DL_TBS_TO_MCS(tbs, 
+               (hqFailStats.dlCqiStat[(dlUe->mimoInfo.cwInfo[0].cqi - 1)].mcs));
+   }
+#endif /* MAC_SCH_STATS */
+
+   /* Fetch the harqProc from the inUse list */
+#ifdef LTEMAC_SPS
+   /* Check if the feedback timing matches with ue->relPdcchFbkTiming*/
+   /* Call Common module with the feedback information */
+   if (ue && (ue->relPdcchFbkTiming.sfn != (RGSCH_MAX_SFN + 1)))
+   {
+      if (RGSCH_TIMEINFO_SAME(fdbkRcptTime, ue->relPdcchFbkTiming))
+      {
+         sf = rgSCHUtlSubFrmGet(cell, timingInfo);
+
+#ifdef LTE_ADV
+         if(uciFrmtTyp == RG_SCH_UCI_FORMAT1B_CS)
+         {/* Feedback for SPS Release on PCell
+             If Pcell is in mimo, feedback index will be 0
+             else 2 */
+            if(rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode) > 1)
+            {
+               isAck[0] = fdbk->isAck[0];
+            }else
+            {
+               isAck[0] = fdbk->isAck[2];
+            }
+
+            /* Not releasing pdcch here
+             * as it is already done at the time of
+             * reception req */
+            rgSCHUtlDlRelPdcchFbk(cell, ue, isAck[0]);
+         }
+         else
+#endif
+         {
+            if (!sf->relPdcch)
+            {
+               RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, 
+                  "CRNTI:%d NO HARQ proc available for feedback: TimingInfo: "
+                  "sfn %d subframe %d", ue->ueId, timingInfo.sfn,
+                  timingInfo.subframe);
+               RETVALUE(RFAILED);
+            }
+
+            isAck[0] = fdbk->isAck[0];
+            /* Note: Since relPdcchFbkTimimg matches with the recieved
+             * feedback, assumed that feedback is for release PDCCH */
+            rgSCHUtlDlRelPdcchFbk(cell, ue, isAck[0]);
+
+            /* Remove release PDCCH from the subframe */
+            rgSCHUtlPdcchPut(cell, &sf->pdcchInfo, sf->relPdcch);
+            sf->relPdcch = NULLP;
+            RETVALUE(ROK);
+         }
+      }
+   }
+#endif /* LTEMAC_SPS */
+   
+   /* Remove the harq process from the subframe */
+   sf = rgSCHUtlSubFrmGet(cell, timingInfo);
+   RG_SCH_ADD_TO_CRNT_TIME(timingInfo, timingInfo, 1);
+   
+#ifdef CA_DBG
+   {
+      if(ue)
+      {
+         gHqFdbkCount++;
+      }
+   }
+
+#endif   
+   while (hqPCount)
+   {
+      if(cbType != RGSCH_HQ_FDB_IND_CB_TYPE_RA_CB)
+      {
+         hqP = (RgSchDlHqProcCb *)node->node;
+         node = node->next;
+         rlsHqBufs = &(hqP->hqE->cell->rlsHqArr[hqP->hqE->cell->crntHqIdx]);
+      }
+      procId = hqP->procId;
+
+      rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0;
+
+      /*Get the position of Ack/Nack from 2 bytes fdbkInfo.
+       * On the basis of f1bCsAVal find the position of iAck or Nack*/
+#ifdef LTE_ADV
+      if (uciFrmtTyp == RG_SCH_UCI_FORMAT3)
+      {
+         rgSchGetHqFdbkPosFormat3(hqP,isAck,format3Ack); 
+      }
+      else
+#endif
+      {
+         rgSchGetHqFdbkPos(cell,ue,hqP, uciFrmtTyp, isAck,fdbk); 
+      }
+      for (tbCnt = 0; tbCnt < 2; tbCnt++)
+      {
+         if (HQ_TB_WAITING == hqP->tbInfo[tbCnt].state)
+         {
+            rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, tbCnt, 
+                  timingInfo, isAck[tbCnt], rlsHqBufs, err);
+         }
+      }
+      if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs)
+      {
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti;
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = 
+            (U8)procId;
+         rlsHqBufs->numUes++;
+      }
+      hqPCount--;
+   }
+
+   node = sf->ackNakRepQ.first;
+   while (node)
+   {
+      tbCb = (RgSchDlHqTbCb *)(node->node);
+      hqP = tbCb->hqP;
+
+      procId = hqP->procId;
+      rlsHqBufs = &(hqP->hqE->cell->rlsHqArr[hqP->hqE->cell->crntHqIdx]);
+      rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 0;
+      if (HQ_TB_WAITING == tbCb->state)
+      {
+         isAck[0] = fdbk->isAck[tbCb->tbIdx];
+         rgSCHDhmPrcFdbkForTb(cell, ue, hqP, sf, isMsg4, rnti, tbCb->tbIdx,
+               timingInfo, isAck[0], rlsHqBufs, err);
+      }
+      hqP->cwSwpEnabled = FALSE;
+      if(rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs)
+      {
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = rnti;
+         rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = 
+            (U8)procId;
+         rlsHqBufs->numUes++;
+      }
+      hqPCount--;
+      node = node->next;
+   }
+
+   RETVALUE(ret);
+}  /* rgSCHDhmHqFdbkInd */
+#endif /* LTE_FDD */
+
+
+/**
+ * @brief Handler for Harq related UE configuration.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmRgrUeCfg
+ *     
+ *     This function shall fetch the harq related information into the
+ *     respective ueCb from the UE configuration as provided by the 
+ *     upper layers. 
+ *           
+ *  @param[in]  RgSchCellCb   *cell 
+ *  @param[in]  RgSchUeCb     *ueCb 
+ *  @param[in]  RgrUeCfg      *ueCfg 
+ *  @param[out] RgSchErrInfo     *err
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmRgrUeCfg
+(
+RgSchCellCb       *cell,
+RgSchUeCb         *ueCb,
+RgrUeCfg          *ueCfg,
+RgSchErrInfo      *err
+)
+#else
+PUBLIC Void rgSCHDhmRgrUeCfg(cell, ueCb, ueCfg, err)
+RgSchCellCb       *cell;
+RgSchUeCb         *ueCb;
+RgrUeCfg          *ueCfg;
+RgSchErrInfo      *err;
+#endif
+{
+   TRC2(rgSCHDhmRgrUeCfg)
+
+   UNUSED(err);
+
+   /* Initialize the TA Timer */
+   cmInitTimers(&ueCb->taTmr, 1);
+
+   /* Setting these values irrespective of taTmr value */
+   ueCb->dl.taCb.state = RGSCH_TA_IDLE;
+   /* Corrected default value of TA as per 36.213, 4.2.3 */
+   ueCb->dl.taCb.ta = RGSCH_NO_TA_RQD;
+  
+   /*[ccpu00121813]-ADD-Initializing outstanding TA value */
+   ueCb->dl.taCb.outStndngTa = FALSE;
+   ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
+   
+   /* Start TA timer only if cfgd as FINITE value */
+   if (ueCfg->ueTaTmrCfg.pres)
+   {
+      /* Configuring taTmr with 30 deficit, to enable eNodeB sending
+       * TA command before the expiry of TA at UE. Also considering for 
+       * possible retx for this TA command */
+      /*[ccpu00121813]-ADD-Added chk if tatmr val > 30 */
+      if(ueCfg->ueTaTmrCfg.taTmr > 30)
+      {
+         ueCb->dl.taCb.cfgTaTmr = ueCfg->ueTaTmrCfg.taTmr - 30; 
+      }
+      rgSCHTmrStartTmr (cell, ueCb, RG_SCH_TMR_TA, ueCb->dl.taCb.cfgTaTmr);
+   }
+   RETVOID;
+}  /* rgSCHDhmRgrUeCfg */
+
+
+/**
+ * @brief Handler for HARQ related UE Reconfiguration
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmRgrCellCfg
+ *     
+ *     This function shall fetch the HARQ related information into the
+ *     respective ueCb from the UE configuration as provided by the 
+ *     upper layers. 
+ *           
+ *  @param[in]  RgSchCellCb     *cell 
+ *  @param[in]  RgrCellCfg   *cellCfg
+ *  @param[out] RgSchErrInfo    *err 
+ *
+ *  @return     S16
+ *                -# ROK 
+ *                -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmRgrCellCfg
+(
+RgSchCellCb    *cell,
+RgrCellCfg     *cellCfg,
+RgSchErrInfo   *err
+)
+#else
+PUBLIC Void rgSCHDhmRgrCellCfg(cell, cellCfg, err)
+RgSchCellCb    *cell;
+RgrCellCfg     *cellCfg;
+RgSchErrInfo   *err;
+#endif
+{
+   RgSchDlHqEnt         *hqE;
+   PTR         pUeCb;/* previous UE Control block */
+   PTR         nUeCb;/* next UE control block */
+   S16         ret;
+   U8          idx;
+
+   TRC2(rgSCHDhmRgrCellCfg)
+
+   UNUSED(err);
+
+   pUeCb = NULLP;
+   
+   cell->dlHqCfg = cellCfg->dlHqCfg;
+   for (;;)
+   {
+      ret = cmHashListGetNext(&(cell->ueLst), pUeCb, &nUeCb);
+      if (ret != ROK)
+      {
+         break;
+      }
+      else
+      {
+         pUeCb = nUeCb;
+         /* Update the DL Harq related information */
+         hqE   = RG_SCH_CMN_GET_UE_HQE(((RgSchUeCb*)nUeCb), cell);
+         hqE->maxHqTx = cell->dlHqCfg.maxDlHqTx;
+      }
+   }
+   /* Initializing the list for ueCbs that would have ta */
+   cmLListInit(&cell->taUeLst);
+#ifdef RGR_V1
+   cmLListInit(&cell->ccchSduUeLst);
+   cmLListInit(&cell->contResGrdTmrLst);
+   cmLListInit(&cell->contResTmrLst);
+#ifdef EMTC_ENABLE
+   if(cell->emtcEnable)
+   {
+      rgSCHDhmEmtcRgrCellCfg(cell);
+   }
+#endif
+#endif
+
+   /* Initializing the timer queue */
+   cell->tqCp.nxtEnt = 0;
+   cell->tqCp.tmrLen = RGSCH_UE_TQ_SIZE;
+
+   for (idx = 0; idx < RGSCH_UE_TQ_SIZE; idx++)
+   {
+     cell->tq[idx].first = NULLP;
+     cell->tq[idx].tail  = NULLP;
+   }
+   RETVOID;
+}  /* rgSCHDhmRgrCellCfg */
+
+/**
+ * @brief Handler for Updating HARQ Information from Cell Reconfiguration 
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmRgrCellRecfg
+ *     
+ *     This function shall fetch the HARQ related information into the
+ *     respective ueCb from the UE configuration as provided by the 
+ *     upper layers. 
+ *           
+ *  @param[in]  RgSchCellCb     *cell 
+ *  @param[in]  RgrCellRecfg *cellRecfg
+ *  @param[out] RgSchErrInfo    *err 
+ *
+ *  @return     S16
+ *                -# ROK 
+ *                -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmRgrCellRecfg
+(
+RgSchCellCb    *cell,
+RgrCellRecfg   *cellRecfg,
+RgSchErrInfo   *err
+)
+#else
+PUBLIC Void rgSCHDhmRgrCellRecfg(cell, cellRecfg, err)
+RgSchCellCb    *cell;
+RgrCellRecfg   *cellRecfg;
+RgSchErrInfo   *err;
+#endif
+{
+   RgSchDlHqEnt         *hqE;
+   PTR         pUeCb;/* previous UE Control block */
+   PTR         nUeCb;/* next UE control block */
+   S16         ret;
+
+   TRC2(rgSCHDhmRgrCellRecfg)
+
+   UNUSED(err);
+
+   pUeCb = NULLP;
+   
+   /* Update the cell with recieved configuration */
+   if (cellRecfg->recfgTypes & RGR_CELL_DL_HARQ_RECFG)
+   {
+      cell->dlHqCfg  =  cellRecfg->dlHqRecfg;
+
+      for (;;)
+      {
+         ret = cmHashListGetNext(&(cell->ueLst), pUeCb, &nUeCb);
+         if (ret != ROK)
+         {
+            break;
+         }
+         else
+         {
+            pUeCb = nUeCb;
+            /* Update the DL Harq related information */
+            hqE      = RG_SCH_CMN_GET_UE_HQE(((RgSchUeCb*)nUeCb), cell);
+            hqE->maxHqTx = cell->dlHqCfg.maxDlHqTx;
+         }
+      }
+   }
+   RETVOID;
+}  /* rgSCHDhmRgrCellRecfg */
+
+/**
+ * @brief Handler for freeing up the HARQ related information from ueCb
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmFreeUe
+ *     
+ *     This function shall free up the HARQ specific information from ueCb.
+ *           
+ *  @param[in]  RgSchUeCb     *ueCb 
+ *
+ *  @return     None.
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmFreeUe
+(
+RgSchUeCb          *ueCb
+)
+#else
+PUBLIC Void rgSCHDhmFreeUe(ueCb)
+RgSchUeCb          *ueCb;
+#endif
+{
+
+   TRC2(rgSCHDhmFreeUe)
+
+   /* If TA Timer is running. Stop it */
+   if (ueCb->taTmr.tmrEvnt != TMR_NONE)
+   {
+      rgSCHTmrStopTmr(ueCb->cell, ueCb->taTmr.tmrEvnt, ueCb);
+   }
+
+   /* ccpu00118357 - ADD - stop the periodic BSR timer so it 
+    * doesn't expire after UE is deleted */
+#ifdef RGR_V1
+   if (ueCb->bsrTmr.tmrEvnt != TMR_NONE)
+   {
+      rgSCHTmrStopTmr(ueCb->cell, ueCb->bsrTmr.tmrEvnt, ueCb);
+   }
+#endif /* ifdef RGR_V1*/
+
+   
+   if (RG_SCH_CMN_GET_UE_HQE(ueCb, ueCb->cell))
+   {
+      rgSCHDhmDelHqEnt(ueCb->cell, &(RG_SCH_CMN_GET_UE_HQE(ueCb, ueCb->cell)));
+   }
+
+   /* This UE needs to be removed from its entry into cell's taUeLst */
+   /*Fix for ccpu00113622 - Delete Only when taLnk Node exists*/
+   if(ueCb->taLnk.node)
+   {
+      cmLListDelFrm(&(ueCb->cell->taUeLst), &ueCb->taLnk);
+      ueCb->taLnk.node = NULLP; 
+   }
+
+   if (ueCb->dlTaLnk.node != NULLP)
+   {
+      /* Fix: syed Need to raise a CR for not calling CMN or specific scheduler
+       * function directly from other modules. APIs should be defined and/or used
+       * instead. Please check for other possible incorrect usage. */      
+      rgSCHCmnRmvFrmTaLst(ueCb->cell, ueCb);
+   }
+
+   RETVOID;
+
+}  /* rgSCHDhmFreeUe */
+
+/**
+ * @brief Handler for updating the TA.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmUpdTa
+ *     
+ *     This function shall update the TA received. 
+ *           
+ *  @param[in]  RgSchCellCb   *cell 
+ *  @param[in]  RgSchUeCb     *ueCb 
+ *  @param[in]  U8         ta
+ *
+ *  @return     None.
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmUpdTa
+(
+RgSchCellCb    *cell,
+RgSchUeCb      *ueCb,
+U8             ta
+)
+#else
+PUBLIC Void rgSCHDhmUpdTa(cell, ueCb, ta)
+RgSchCellCb    *cell;
+RgSchUeCb      *ueCb;
+U8             ta;
+#endif
+{
+   TRC2(rgSCHDhmUpdTa)
+
+   if (ueCb->dl.taCb.state == RGSCH_TA_IDLE)
+   {
+      ueCb->dl.taCb.state     =  RGSCH_TA_TOBE_SCHEDULED;
+      ueCb->dl.taCb.numRemSf  =  2;
+      rgSCHUtlDlTARpt(cell, ueCb);  
+      /* If TA Timer is running. Stop it */
+      if (ueCb->taTmr.tmrEvnt != TMR_NONE)
+      {
+         rgSCHTmrStopTmr(cell, ueCb->taTmr.tmrEvnt, ueCb);
+      }
+         
+         /* SR_RACH_STATS : TA MODIFIED */
+      if (ueCb->dl.taCb.ta != ta)
+      {
+         rgNumTAModified++;
+      }
+      ueCb->dl.taCb.ta        =  ta;
+   }
+   else
+   {
+      /* [ccpu00121813]-ADD-Updating outstanding values 
+      * TA which gets transmitted at N gets applied at UE at N+6,once TA
+      * has been scheduled,further TA values get stored in outstndngTaval.
+      * Once TA gets applied at UE or when NACK/DTX is rcvd for maxhqretx times
+      * then schedule the outstanding TA val if present */
+      ueCb->dl.taCb.outStndngTa    =  TRUE;
+      ueCb->dl.taCb.outStndngTaval =  ta;
+   }
+
+   RETVOID;
+}  /* rgSCHDhmUpdTa */
+
+ /** @brief This function handles the TA timer expiry.
+  *
+  * @details
+  *
+  *     Function: This function handled the TA Expiry.
+  *
+  *         Processing steps:
+  *         - 
+  *
+  *
+  * @param[in] RgSchUeCb  *ueCb  
+  *
+  * @return Void
+  *      -#None.
+  */
+#ifdef ANSI
+PUBLIC Void rgSCHDhmProcTAExp 
+(
+ RgSchUeCb  *ueCb
+ )
+#else
+PUBLIC Void rgSCHDhmProcTAExp (ueCb)
+ RgSchUeCb  *ueCb;
+#endif
+{
+   TRC2(rgSCHDhmProcTAExp);
+
+   /* Ask scheduler to schedule this UE */
+   ueCb->dl.taCb.state     =  RGSCH_TA_TOBE_SCHEDULED;
+   rgSCHUtlDlTARpt(ueCb->cell, ueCb);  
+   RETVOID;
+} /* end of rgSCHDhmProcTAExp */ 
+
+/* 3.1 MIMO: LC details at TB level rather than Hq Level */
+/**
+ * @brief Handler for Adding scheduled logical channel data information  
+ *        to harqProc.
+ *                    
+ * @details
+ *
+ *     Function : rgSCHDhmAddLcData
+ *     
+ *     This function shall add the scheduled logical channel data 
+ *     information to the HARQ process. 
+ *           
+ *  @param[in]  RgSchLchAllocInfo  *lchData
+ *  @param[in]  RgSchDlHqTbCb     *tbInfo
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmAddLcData
+(
+Inst               inst,
+RgSchLchAllocInfo  *lchData,
+RgSchDlHqTbCb      *tbInfo
+)
+#else
+PUBLIC S16 rgSCHDhmAddLcData(inst, lchData, tbInfo)
+Inst               inst;
+RgSchLchAllocInfo  *lchData;
+RgSchDlHqTbCb      *tbInfo;
+#endif
+{
+
+   TRC2(rgSCHDhmAddLcData)
+
+   if(tbInfo->numLch >= RGSCH_MAX_NUM_DED_LC)
+   {
+     RETVALUE(RFAILED);
+   } 
+
+   tbInfo->lchSchdDataArr[tbInfo->numLch]   = *lchData;
+
+   tbInfo->numLch++;
+
+   RETVALUE(ROK);
+
+}  /* rgSCHDhmAddLcData */
+
+#ifdef LTE_TDD
+/*
+ * @brief Handler for releaseing the subframe allocation.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmTddRlsSubFrm
+ *
+ *     This function shall be invoked to release the DL Sf 
+ *     allocations for which HARQ feedback time has expired.
+ *
+ *  @param[in]  RgSchCellCb      *cellCb
+ *  @param[in]  CmLteTimingInfo  uciTimingInfo;
+ *  @return     S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmTddRlsSubFrm
+(
+RgSchCellCb          *cellCb,
+CmLteTimingInfo      uciTimingInfo
+)
+#else
+PUBLIC S16 rgSCHDhmTddRlsSubFrm(cellCb, uciTimingInfo)
+RgSchCellCb          *cellCb;
+CmLteTimingInfo      uciTimingInfo;
+#endif
+{
+   CmLteTimingInfo         dlSfTime;
+   RgSchTddDlAscSetIdxK    ascIdx;
+   U8                      noFdbks;
+   U8                      i;
+
+   TRC2(rgSCHDhmTddRlsSubFrm)
+
+   ascIdx = 
+      rgSchTddDlAscSetIdxKTbl[cellCb->ulDlCfgIdx][uciTimingInfo.subframe];
+   noFdbks = ascIdx.numFdbkSubfrms;
+   for(i=0; i < noFdbks; i++)
+   {
+      /* Get the subframe and sfn for which HARQ Ack/Nack
+       * has to be sent */
+      /* ccpu00132341-MOD- optimized getting DLSF time using macro*/
+      /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper 
+       * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() 
+       * as it is serving the purpose */
+      RGSCHDECRFRMCRNTTIME(uciTimingInfo, dlSfTime, ascIdx.subfrmNum[i]);
+      rgSCHUtlDlRlsSubFrm(cellCb, dlSfTime);
+   }
+   RETVALUE(ROK);
+}/* rgSCHDhmTddRlsSubFrm */
+
+#ifdef TFU_TDD
+U32 macDtx = 0;
+#endif
+/**
+ * @brief Handler for Removing the HARQ process from a dlsf.
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmRlsDlsfHqProc
+ *
+ *     This function shall be invoked for every tti. It goes back to
+ *     to the sixth last subframe to check whether it still exists. If
+ *     that exists this function traverses through the entire harq
+ *     proc list associated and frees up all of them.
+ *
+ *  @param[in]  RgSchCellCb      *cellCb
+ *  @param[in]  CmLteTimingInfo  timingInfo
+ *  @return     S16
+ *      -# ROK
+ *      -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmRlsDlsfHqProc
+(
+RgSchCellCb          *cellCb,
+CmLteTimingInfo      uciTimingInfo
+)
+#else
+PUBLIC S16 rgSCHDhmRlsDlsfHqProc(cellCb, uciTimingInfo)
+RgSchCellCb          *cellCb;
+CmLteTimingInfo      uciTimingInfo;
+#endif
+{
+   RgSchDlSf               *dlSf;
+   CmLteTimingInfo         dlSfTime;
+   CmLteTimingInfo         nxtfrm = {0,0};
+   RgSchDlHqProcCb         *tmpHqProc;
+   RgSchTddDlAscSetIdxK    ascIdx;
+   U8                      noFdbks;
+   S16                     i;
+   RgSchDlSf               *nxtDlsf = NULLP;
+   CmLList                 *node;
+   CmLList                 *hqPNode;
+   U8                      idx;
+   /*ccpu00130018 -MOD -Initiatizing with FALSE*/ 
+   U8                      maxRetx=FALSE;
+   RgSchTddANInfo          *anInfo = NULLP;
+   RgSchDlHqTbCb           *tbCb;
+   RgSchUeCb               *ue = NULLP;
+   TRC2(rgSCHDhmRlsDlsfHqProc)
+
+   ascIdx = 
+      rgSchTddDlAscSetIdxKTbl[cellCb->ulDlCfgIdx][uciTimingInfo.subframe];
+   noFdbks = ascIdx.numFdbkSubfrms;
+   for(i=0; i < noFdbks; i++)
+   {
+      /* Get the subframe and sfn for which HARQ Ack/Nack
+       * has to be sent */
+      /* ccpu00132341-MOD- optimized getting DLSF time using macro*/
+      /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper 
+       * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() 
+       * as it is serving the purpose */
+      RGSCHDECRFRMCRNTTIME(uciTimingInfo, dlSfTime, ascIdx.subfrmNum[i]);
+
+      dlSf = rgSCHUtlSubFrmGet (cellCb, dlSfTime);
+      if(cellCb->ulDlCfgIdx != 5)
+      {
+         rgSCHUtlGetNxtDlSfInfo(dlSfTime, cellCb, dlSf, &nxtDlsf, &nxtfrm);
+      }
+      /* Subframe is present. Delete all the harq associations from 
+       * this subframe.
+       */
+
+      /*Handling for Msg4*/
+      node = dlSf->msg4HqPLst.first;
+      while (node)
+      {
+         tmpHqProc = (RgSchDlHqProcCb *)(node->node);
+         node = node->next;
+         tmpHqProc->cwSwpEnabled = FALSE;
+         if (HQ_TB_WAITING == tmpHqProc->tbInfo[0].state)
+         {
+            tbCb = &tmpHqProc->tbInfo[0];
+
+            /* Fix : syed MultiUe per TTI crash in TA List. */
+            maxRetx = FALSE;
+
+            tbCb->dtxCount++;
+            tbCb->isAckNackDtx = TFU_HQFDB_DTX;
+
+
+            rgSCHUtlDlHqPTbRmvFrmTx(dlSf, tmpHqProc, tbCb->tbIdx, FALSE);
+
+            /* Delete the Harq Association. Release the Harq Process */
+            rgSCHDhmHqTbTrnsFail(cellCb, tmpHqProc, tbCb->tbIdx, &maxRetx);
+
+            if (tbCb->taSnt == TRUE)
+            {
+               /* [ccpu00127148] Correcting the check */
+               if (TRUE == maxRetx)
+               {
+                  tbCb->taSnt                  =  FALSE;
+                  RGSCH_NULL_CHECK(cellCb->instIdx, ue)
+                     ue->dl.taCb.state = RGSCH_TA_IDLE;
+
+                  rgSCHUtlReTxTa(cellCb, ue);
+               }
+            }
+         }
+      } 
+
+      node = dlSf->ueLst.first;
+      while (node)
+      {
+#ifdef TFU_TDD
+         macDtx++;
+#endif
+         ue = (RgSchUeCb *)(node->node);
+         node = node->next;
+         if (NULLP != ue)
+         {
+            hqPNode = ue->dl.dlSfHqInfo[cellCb->cellId][dlSf->dlIdx].hqPLst.first;
+            while (hqPNode)
+            {
+               tmpHqProc = (RgSchDlHqProcCb *)hqPNode->node;
+               hqPNode = hqPNode->next;
+               for (idx = 0 ;idx < 2; idx++)
+               {
+                  if (HQ_TB_WAITING == tmpHqProc->tbInfo[idx].state)
+                  {
+                     tbCb = &tmpHqProc->tbInfo[idx];
+
+                     /* Fix : syed MultiUe per TTI crash in TA List. */
+                     maxRetx = FALSE;
+
+                     tbCb->dtxCount++;
+                     tbCb->isAckNackDtx = TFU_HQFDB_DTX;
+
+
+                     /* Update feedback time for this process so that 
+                      * next subframe its picked up */
+#ifdef LTE_ADV
+                     U8 servCellIdx = rgSchUtlGetServCellIdx(
+                           tmpHqProc->hqE->cell->instIdx,
+                           tmpHqProc->hqE->cell->cellId,
+                           ue);
+                     anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,servCellIdx);
+#else
+                     anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,RGSCH_PCELL_INDEX);
+#endif
+                     if(anInfo == NULLP)
+                     {
+                        RGSCHDBGERR(cellCb->instIdx, (rgSchPBuf(cellCb->instIdx), 
+                                 "Ack/Nack Info is NULL, Processing %dth feedback subframe for DTX" 
+                                 "received on SFN [%d] and SF [%d]\n",i, uciTimingInfo.sfn, 
+                                 uciTimingInfo.subframe));
+                     }
+                     else  if (tbCb->fbkRepCntr == 0)
+                     {
+                        /* Initialise the Ack/Nack feedback */
+                        anInfo->dlDai--;
+                        if(!(anInfo->dlDai))
+                        {
+                           rgSCHUtlInitUeANFdbkInfo(anInfo);
+                        }
+                     }
+                     else
+                     {
+                        /* Update feedback time for this process so that
+                         *              * next subframe its picked up */
+                        RGSCH_NULL_CHECK(cellCb->instIdx, nxtDlsf); 
+                        RGSCH_UPD_HQAN_FDBKTIME(tbCb, nxtDlsf, nxtfrm);
+                        RGSCH_UPD_ANINFO_WITH_HQ(anInfo, tbCb);
+                        rgSCHUtlDlHqPTbRmvFrmTx(dlSf, tmpHqProc, tbCb->tbIdx, TRUE);
+                        tbCb->fbkRepCntr--;
+                        continue;
+
+                     }
+                     rgSCHUtlDlHqPTbRmvFrmTx(dlSf, tmpHqProc, tbCb->tbIdx, FALSE);
+                     /*ccpu000119494-ADD- for SPS, call SPS specific DTX handler */
+
+                     {
+                        /* Delete the Harq Association. Release the Harq Process */
+                        rgSCHDhmHqTbTrnsFail(cellCb, tmpHqProc, tbCb->tbIdx, &maxRetx);
+                     }
+                     if (tbCb->taSnt == TRUE)
+                     {
+                        /* [ccpu00127148] Correcting the check */
+                        if (TRUE == maxRetx)
+                        {
+                           tbCb->taSnt                  =  FALSE;
+                           RGSCH_NULL_CHECK(cellCb->instIdx, ue)
+                              ue->dl.taCb.state = RGSCH_TA_IDLE;
+
+                           rgSCHUtlReTxTa(cellCb, ue);
+
+                           RLOG_ARG0(L_DEBUG,DBG_CELLID,cellCb->cellId,
+                                   "Nack/DTX Rcvd for TA. Max Tries Attempted");
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      node = dlSf->ackNakRepQ.first;
+      while (node)
+      {
+         tbCb = (RgSchDlHqTbCb *)(node->node);
+         tmpHqProc = tbCb->hqP;
+         /* [ccpu00121813]-ADD-Fetch ueCb */
+         ue = tmpHqProc->hqE->ue;
+         /* Fix : syed MultiUe per TTI crash in TA List. */
+         maxRetx = FALSE;
+         
+         tbCb->dtxCount++;
+#ifdef TENB_STATS
+         tmpHqProc->hqE->cell->tenbStats->sch.dlDtx[tbCb->tbIdx][tbCb->dlGrnt.rv]++;
+         ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(tmpHqProc->hqE->cell)].dlDtxCnt[tbCb->tbIdx] ++;
+#endif
+
+         node = node->next;
+         /* If This is not the last repetition */
+         if (tbCb->fbkRepCntr > 1)
+         {
+            /* Update feedback time for this process so that 
+             * next subframe its picked up */
+#ifdef LTE_ADV
+            U8 servCellIdx = rgSchUtlGetServCellIdx(
+                  tmpHqProc->hqE->cell->instIdx,
+                  tmpHqProc->hqE->cell->cellId,
+                  ue);
+            anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,servCellIdx);
+#else
+            anInfo = rgSCHUtlGetUeANFdbkInfo(ue, &tbCb->fdbkTime,0);
+#endif
+            if(anInfo == NULLP)
+            {
+               RETVALUE(RFAILED);
+            }
+            RGSCH_NULL_CHECK(cellCb->instIdx, nxtDlsf);
+            RGSCH_UPD_HQAN_FDBKTIME(tbCb, nxtDlsf, nxtfrm);
+            RGSCH_UPD_ANINFO_WITH_HQ(anInfo, tbCb);
+            rgSCHUtlDlHqPTbRmvFrmTx(dlSf,tmpHqProc,tbCb->tbIdx, TRUE);
+            tbCb->fbkRepCntr--;
+            continue;
+         }
+         else
+         {
+            rgSCHUtlDlHqPTbRmvFrmTx(dlSf,tmpHqProc,tbCb->tbIdx, TRUE);
+
+            if (((tbCb->nackCount + tbCb->dtxCount) >= tbCb->ackCount))
+            {
+               /*even if one NACK, we consider the feedback
+                * on a whole as NACk */
+               if ( tbCb->nackCount != 0 )
+               {
+                  tbCb->isAckNackDtx = TFU_HQFDB_NACK;
+               }
+               else
+               {
+                  tbCb->isAckNackDtx = TFU_HQFDB_DTX;
+               }
+              
+            {
+               /* Delete the Harq Association. Release the Harq Process */
+              rgSCHDhmHqTbTrnsFail(cellCb, tmpHqProc, tbCb->tbIdx, &maxRetx);
+            }
+           }/*if(((tbCb->nackCount+....*/
+         }/*else....*/
+
+         if (tbCb->taSnt == TRUE)
+         {
+            /* [ccpu00127148] Correcting the check */
+            if (TRUE == maxRetx)
+            {
+               tbCb->taSnt                  =  FALSE;
+               ue->dl.taCb.state = RGSCH_TA_IDLE;
+               
+               rgSCHUtlReTxTa(cellCb, ue); 
+               RLOG_ARG0(L_DEBUG,DBG_CELLID,cellCb->cellId,
+                     "Nack/DTX Rcvd for TA. Max Tries Attempted");
+               
+             }
+         }
+      }
+   }
+   RETVALUE(ROK);
+}/* rgSCHDhmRlsDlsfHqProc */
+#else /* ifdef LTE_TDD */
+/**
+ * @brief Handler for Removing the HARQ process from a dlsf.
+ *                    
+ * @details
+ *
+ *     Function : rgSCHDhmRlsDlsfHqProc
+ *     
+ *     This function shall be invoked for every tti. It goes back to
+ *     to the sixth last subframe to check whether it still exists. If
+ *     that exists this function traverses through the entire harq 
+ *     proc list associated and frees up all of them.  
+ *           
+ *  @param[in]  RgSchCellCb     *cell 
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmRlsDlsfHqProc
+(
+RgSchCellCb          *cell,
+CmLteTimingInfo      timingInfo
+)
+#else
+PUBLIC S16 rgSCHDhmRlsDlsfHqProc(cell, timingInfo)
+RgSchCellCb          *cell;
+CmLteTimingInfo      timingInfo;
+#endif
+{
+   RgSchDlSf         *sf;
+   CmLteTimingInfo   frm;
+   RgSchDlHqProcCb   *tmpHqProc;
+   Bool              maxRetx;
+   CmLList           *node;
+   CmLList           *hqPNode;
+   U8                idx;
+   RgSchDlHqTbCb     *tbCb;
+   RgSchUeCb         *ue;
+
+   TRC2(rgSCHDhmRlsDlsfHqProc)
+
+   /* Fetch the current timing info. Modify it to Last sf to be rlsd.*/
+   /* ccpu00133109: Removed RGSCHSUBFRMCRNTTIME as it is not giving proper 
+    * output if diff is more than 10. Instead using RGSCHDECRFRMCRNTTIME() 
+    * as it is serving the purpose */
+   RGSCHDECRFRMCRNTTIME(timingInfo, frm, RG_SCH_CMN_HARQ_INTERVAL); 
+   
+
+   /* Get the required Last subframe */
+   sf = rgSCHUtlSubFrmGet(cell, frm);
+
+   /*CA Dev Start*/
+   /*Handling for Msg4*/
+   node = sf->msg4HqPLst.first;
+   while (node)
+   {
+      tmpHqProc = (RgSchDlHqProcCb *)(node->node);
+      if (HQ_TB_WAITING == tmpHqProc->tbInfo[0].state)
+      {
+         tbCb = &tmpHqProc->tbInfo[0];
+         /* Fix : syed MultiUe per TTI crash in TA List. */
+         maxRetx = FALSE;
+
+         RGSCHDBGINFO(cell->instIdx, (rgSchPBuf(cell->instIdx),"\n rgSCHDhmRlsDlsfHqProc():\
+                  txCntr=%d tmpHqProc=%d",tbCb->txCntr,tmpHqProc->procId));
+
+         tbCb->dtxCount++;
+         if ((tmpHqProc->hqE->msg4Proc == tmpHqProc) || 
+               (tmpHqProc->hqE->ccchSduProc == tmpHqProc))
+         {
+            tbCb->isAckNackDtx = TFU_HQFDB_NACK;
+            rgNumMsg4Dtx++;
+         }
+
+         node = node->next;
+         if (tbCb->fbkRepCntr != 0)
+         {
+            /* Update timingInfo for this hqP so that next subframe its picked up */
+            RG_SCH_ADD_TO_CRNT_TIME(tbCb->timingInfo, tbCb->timingInfo, 1);
+            rgSCHUtlDlHqPTbRmvFrmTx(sf,tmpHqProc,tbCb->tbIdx, TRUE);
+            tbCb->fbkRepCntr--;
+            continue;
+         }
+         rgSCHUtlDlHqPTbRmvFrmTx(sf,tmpHqProc,tbCb->tbIdx, FALSE);
+
+         /* Delete the Harq Association. Release the Harq Process */
+         rgSCHDhmHqTbTrnsFail(cell, tmpHqProc, tbCb->tbIdx, &maxRetx);
+
+      }
+   } 
+   /* Subframe is present. Delete all the harq associations from 
+    * this subframe.
+    */
+   node = sf->ueLst.first;
+   while (node)
+   {
+      ue = (RgSchUeCb *)(node->node);
+      node = node->next;
+      if(ue != NULLP)
+      {
+         hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first;
+
+         while (hqPNode)
+         {
+            tmpHqProc = (RgSchDlHqProcCb *)hqPNode->node;
+            tmpHqProc->cwSwpEnabled = FALSE;
+            hqPNode = hqPNode->next;
+            for (idx = 0 ;idx < 2; idx++)
+            {
+               if (HQ_TB_WAITING == tmpHqProc->tbInfo[idx].state)
+               {
+                  tbCb = &tmpHqProc->tbInfo[idx];
+                  /* Fix : syed MultiUe per TTI crash in TA List. */
+                  maxRetx = FALSE;
+
+                  RGSCHDBGINFO(cell->instIdx, (rgSchPBuf(cell->instIdx),"\n rgSCHDhmRlsDlsfHqProc():\
+                           txCntr=%d tmpHqProc=%d",tbCb->txCntr,tmpHqProc->procId));
+
+                  tbCb->dtxCount++;
+                  if ((tmpHqProc->hqE->msg4Proc == tmpHqProc) || 
+                        (tmpHqProc->hqE->ccchSduProc == tmpHqProc))
+                  {
+                     tbCb->isAckNackDtx = TFU_HQFDB_NACK;
+                     rgNumMsg4Dtx++;
+                  }
+                  else
+                  {
+                     tbCb->isAckNackDtx = TFU_HQFDB_DTX;
+                  }
+
+                  rgSCHUtlDlHqPTbRmvFrmTx(sf,tmpHqProc,idx, FALSE);
+
+                  {
+                     /* Delete the Harq Association. Release the Harq Process */
+                     rgSCHDhmHqTbTrnsFail(cell, tmpHqProc, tbCb->tbIdx, &maxRetx);
+                  }
+                  if (tbCb->taSnt == TRUE)
+                  {
+                     /* [ccpu00127148] Correcting the check */
+                     if (TRUE == maxRetx)
+                     {
+                        tbCb->taSnt                  =  FALSE;
+                        ue->dl.taCb.state = RGSCH_TA_IDLE;
+
+                        rgSCHUtlReTxTa(cell, ue); 
+                        RGSCHDBGINFO(cell->instIdx, (rgSchPBuf(cell->instIdx), 
+                                 "Nack/DTX Rcvd for TA. Max Tries Attempted\n"));
+                     }
+                  }
+                  RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
+                  ueDl->mimoInfo.cwInfo[tbCb->tbIdx].dtxCnt++;
+               }
+            }
+         }
+      }
+   }
+   /*CA Dev End*/
+
+   RETVALUE(ROK);
+}  /* rgSCHDhmRlsDlsfHqProc */
+#endif
+#ifdef LTEMAC_SPS
+#ifdef RG_UNUSED
+/**
+ * @brief This function marks the HARQ process with a given ID as SPS HARQ
+ * proc
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmMarkSpsHqProc
+ *     Purpose:  This function returns the HARQ process with the given ID.
+ *     Invoked by: SPS Module
+ *     Processing steps: 
+ *     - Get the HARQ process by index from the UE
+ *     - Set isSpsHqProc = TRUE
+ *     
+ *  @param[in]  RgSchUeCb        *ue
+ *  @param[in]  U8            idx
+ *  @return  S16       
+ *         -#   ROK     if successful
+ *         -#   RFAILED otherwise
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmMarkSpsHqProc
+(
+RgSchUeCb               *ue,
+U8                      idx
+)
+#else
+PUBLIC S16 rgSCHDhmMarkSpsHqProc(ue, idx)
+RgSchUeCb               *ue;
+U8                      idx;
+#endif
+{
+   RgSchDlHqProcCb      *hqP;
+   TRC2(rgSCHDhmMarkSpsHqProc)
+
+   /* Pick the proc based on the index provided */
+   rgSCHDhmGetHqProcFrmId(ue->cell, ue, idx, &hqP);
+
+   RETVALUE(ROK);
+} /* rgSCHDhmMarkSpsHqProc */
+#endif /* RG_UNUSED */
+#endif /* LTEMAC_SPS */
+
+#ifndef LTE_TDD
+/** * @brief Handler for HARQ feedback received for DL AckNack rep enabled UE
+ *
+ * @details
+ *
+ *     Function : rgSCHDhmProcHqFdbkAckNackRep
+ *     
+ *     This function shall act on the feedback received from TOM for DL
+ *     transmission. 
+ *     
+ *           
+ *  @param[in]  RgSchDlHqProcCb     *hqP
+ *  @param[in]  RgSchDlSf           *sf                  
+ *  @param[in]  U8                  tbCnt
+ *  @param[in]  U8                  *isAck
+ *  @return     S16
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+#ifdef ANSI
+PRIVATE S16 rgSCHDhmProcHqFdbkAckNackRep
+(
+RgSchDlHqProcCb      *hqP,
+RgSchDlSf            *sf,
+U8                   tbCnt,
+U8                   *isAck
+)
+#else
+PRIVATE S16 rgSCHDhmProcHqFdbkAckNackRep(hqP,sf,tbCnt,isAck)
+RgSchDlHqProcCb      *hqP;
+RgSchDlSf            *sf;
+U8                   tbCnt;
+U8                   *isAck;
+#endif
+{
+    TRC2(rgSCHDhmProcHqFdbkAckNackRep)
+      /* Check if this is repeating UE */
+    rgSCHUtlDlHqPTbRmvFrmTx(sf, hqP, tbCnt, TRUE);
+    /* Check if last repetition */
+    if (--hqP->tbInfo[tbCnt].fbkRepCntr)
+    {
+        /* Update timingInfo for this hqP so that next subframe its picked up */
+        RG_SCH_ADD_TO_CRNT_TIME(hqP->tbInfo[tbCnt].timingInfo, \
+                               hqP->tbInfo[tbCnt].timingInfo, 1);
+        RETVALUE(RFAILED);
+    }
+    
+    /* Take decision here based on the number
+     * of DTX's,NACK's and ACK's received
+     */
+    if (((hqP->tbInfo[tbCnt].ackCount) > (hqP->tbInfo[tbCnt].nackCount) + 
+                (hqP->tbInfo[tbCnt].dtxCount)))
+    {
+        *isAck = TFU_HQFDB_ACK; 
+    }
+    /*even a single NACK indicates that UE received
+     * the transmission. 
+     */
+    else if ( hqP->tbInfo[tbCnt].nackCount != 0 )
+    {
+        *isAck = TFU_HQFDB_NACK;
+    }
+    else
+    {
+        *isAck = TFU_HQFDB_DTX;
+    }
+      
+       
+    hqP->tbInfo[tbCnt].isAckNackDtx = *isAck; 
+    RETVALUE(ROK);
+}
+#endif /* ifndef LTE_TDD */
+
+
+/* Freeing up the HARQ proc blocked for
+ * indefinite time in case of Retx */
+/**
+ * @brief This function handles the scenario in case Retx allocation is failed.
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmDlRetxAllocFail
+ *     Purpose:  
+ *                
+ *  @param[in]  RgSchUeCb             *ue
+ *  @param[in]  RgSchDlHqProcCb       *hqP
+ *  @return  Void 
+ *
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmDlRetxAllocFail 
+(
+RgSchUeCb               *ue,
+RgSchDlHqProcCb         *hqP
+)
+#else
+PUBLIC S16 rgSCHDhmDlRetxAllocFail(ue, hqP)
+RgSchUeCb               *ue;
+RgSchDlHqProcCb         *hqP;
+#endif
+{
+   RgSchCellCb      *cell;
+   RgInfRlsHqInfo   *rlsHqInfo;
+   Pst              pst;   
+   Bool             maxRetx = FALSE;
+   RgSchCmnCell           *cellSch;
+
+   TRC2(rgSCHDhmDlRetxAllocFail);
+
+   cell = hqP->hqE->cell;
+   cellSch = RG_SCH_CMN_GET_CELL(cell);
+   rlsHqInfo = &(cell->rlsHqArr[cell->crntHqIdx]);
+   /* If retx was attempted for 1st TB, increment its retx alloc fail counter */
+   if (hqP->tbInfo[0].state == HQ_TB_NACKED)
+   {
+      hqP->tbInfo[0].cntrRetxAllocFail++;
+   }
+
+   /* If retx was attempted for 2nd TB, increment its retx alloc fail counter */
+   if (hqP->tbInfo[1].state == HQ_TB_NACKED)
+   {
+      hqP->tbInfo[1].cntrRetxAllocFail++;
+   }
+
+   /* initialize MAC-SCH interface HARQ release info */
+   rlsHqInfo->numUes = 0;
+   rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs = 0;
+
+   /* Release HARQ proc for TB1 if Retx alloc failure count has reached max */
+   if (hqP->tbInfo[0].cntrRetxAllocFail == RG_SCH_MAX_RETX_ALLOC_FAIL)
+   {
+      if (hqP->hqE->msg4Proc == hqP)
+      {
+         hqP->tbInfo[0].txCntr = cell->dlHqCfg.maxMsg4HqTx;
+      }
+      else
+      {
+         hqP->tbInfo[0].txCntr = hqP->hqE->maxHqTx;
+      }
+
+      rgSCHDhmHqTbTrnsFail(cell, hqP, hqP->tbInfo[0].tbIdx, &maxRetx);
+
+#ifdef LTE_L2_MEAS
+      if (maxRetx)
+      {
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\
+               rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = 0xFF; /* RGU_NACK_LOSS */;
+      }
+      else
+      {
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\
+               rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = FALSE;
+      }
+#else
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\
+               rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = FALSE;
+#endif
+
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].tbId[\
+               rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = 1;
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs++;
+   }
+
+   /* Release HARQ proc for TB2 if Retx alloc failure count has reached max */
+   if (hqP->tbInfo[1].cntrRetxAllocFail == RG_SCH_MAX_RETX_ALLOC_FAIL)
+   {
+      if (hqP->hqE->msg4Proc == hqP)
+      {
+         hqP->tbInfo[1].txCntr = cell->dlHqCfg.maxMsg4HqTx;
+      }
+      else
+      {
+         hqP->tbInfo[1].txCntr = hqP->hqE->maxHqTx;
+      }
+
+      rgSCHDhmHqTbTrnsFail(cell, hqP, hqP->tbInfo[1].tbIdx, &maxRetx);
+
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].status[\
+               rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = FALSE;
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].tbId[\
+               rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs] = 2;
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs++;
+   }
+
+   /* MS_WORKAROUND for ccpu00122892 Temp fix for erroeneous RETX Harq release by rgSCHCmnDlAllocRetxRb */
+   
+   if ((hqP->tbInfo[0].state != HQ_TB_NACKED) &&
+       (hqP->tbInfo[1].state != HQ_TB_NACKED))    
+   {
+      cellSch->apisDl->rgSCHDlProcRmvFrmRetx(cell, ue, hqP);
+   }
+
+   /* send HARQ release to MAC */
+   if (rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].numOfTBs > 0)
+   {
+      /* Fix : syed HO UE does not have a valid ue->rntiLnk */    
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].rnti = ue->ueId;
+      rlsHqInfo->ueHqInfo[rlsHqInfo->numUes].hqProcId = hqP->procId;
+      rlsHqInfo->numUes = 1;
+
+      rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
+      RgSchMacRlsHq(&pst, rlsHqInfo);
+   }
+
+   RETVALUE(ROK);
+}
+
+#ifdef DL_LA
+#ifdef ANSI
+PRIVATE S16 rgSCHDhmUpdateAckNackHistory
+(
+RgSchCellCb             *cell,
+RgSchUeCb               *ueCb,
+U8                      hqfdbk,
+U8                      tbCnt
+)
+#else
+PRIVATE S16 rgSCHDhmUpdateAckNackHistory(cell, ueCb, hqfdbk, tbCnt)
+(
+RgSchCellCb             *cell;
+RgSchUeCb               *ueCb;
+U8                      hqfdbk;
+U8                      tbCnt;
+)
+#endif
+{
+   RgSchCmnDlUe  *ueDl;
+   
+   ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
+   
+   /*
+    * If fdbk is ack update totalNoOfAck and ackNackHistory for 
+    * current idx
+    */ 
+   if (hqfdbk == TFU_HQFDB_ACK)
+   {
+      ueDl->laCb[tbCnt].deltaiTbs += DL_LA_STEPUP; 
+   }
+   else   
+   {         
+      ueDl->laCb[tbCnt].deltaiTbs = ueDl->laCb[tbCnt].deltaiTbs - DL_LA_STEPDOWN; 
+   }
+   /*
+   printf("deltaiTbs[%d] cqibasediTbs[%d] iTbs[%d] tbCnt[%d]\n", 
+           ueDl->laCb[tbCnt].deltaiTbs, ueDl->laCb[tbCnt].cqiBasediTbs, 
+           (ueDl->laCb[tbCnt].deltaiTbs + ueDl->laCb[tbCnt].cqiBasediTbs)/100,
+           tbCnt);
+   */
+   rgSCHDhmUpdBlerBasediTbsEff(cell, ueCb, tbCnt); 
+
+   RETVALUE(ROK);
+}
+
+#ifdef ANSI
+PUBLIC S16 rgSCHDhmUpdBlerBasediTbsEff
+(
+RgSchCellCb             *cell,
+RgSchUeCb               *ueCb,
+U8                      tbCnt
+)
+#else
+PUBLIC S16 rgSCHDhmUpdBlerBasediTbsEff(cell, ueCb, tbCnt)
+(
+RgSchCellCb             *cell;
+RgSchUeCb               *ueCb;
+U8                      tbCnt;
+)
+#endif
+{
+   S32            iTbs;
+   RgSchCmnDlUe  *ueDl;
+   RgSchCmnCell  *cellSch = RG_SCH_CMN_GET_CELL(cell);
+   U8             cfi = cellSch->dl.currCfi;
+   U8             maxiTbs = (*(RgSchCmnCqiToTbs *)(cellSch->dl.cqiToTbsTbl[0][cfi]))[RG_SCH_CMN_MAX_CQI - 1];
+   maxiTbs                = RG_SCH_DL_MAX_ITBS;
+
+   ueDl = RG_SCH_CMN_GET_DL_UE(ueCb,cell);
+   iTbs =  (ueDl->laCb[tbCnt].deltaiTbs + ueDl->laCb[tbCnt].cqiBasediTbs)/100; 
+   if (iTbs > maxiTbs)
+   {
+      ueDl->laCb[tbCnt].deltaiTbs = (maxiTbs * 100) - ueDl->laCb[tbCnt].cqiBasediTbs;
+      ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0] = RGSCH_MIN(maxiTbs, ueCb->cell->thresholds.maxDlItbs); 
+   }
+   else if (iTbs < 0)
+   {
+      ueDl->laCb[tbCnt].deltaiTbs = -(ueDl->laCb[tbCnt].cqiBasediTbs);
+      ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0] = 0; 
+   }
+   else
+   {
+      ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0] = RGSCH_MIN(((ueDl->laCb[tbCnt].cqiBasediTbs +\
+                                                         ueDl->laCb[tbCnt].deltaiTbs)/100),  
+                                                      ueCb->cell->thresholds.maxDlItbs);
+   }
+#ifdef RG_5GTF
+   ueCb->ue5gtfCb.mcs = ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0];
+#endif
+   ueDl->mimoInfo.cwInfo[tbCnt].iTbs[1] = ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0];
+
+   /* Eff for CW for 1 Layer Tx */
+   ueDl->mimoInfo.cwInfo[tbCnt].eff[0] = 
+      (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[0][cfi]))\
+      [ueDl->mimoInfo.cwInfo[tbCnt].iTbs[0]];
+
+   /* Eff for CW for 2 Layer Tx */
+   ueDl->mimoInfo.cwInfo[tbCnt].eff[1] = 
+      (*(RgSchCmnTbSzEff *)(cellSch->dl.cqiToEffTbl[1][cfi]))\
+      [ueDl->mimoInfo.cwInfo[tbCnt].iTbs[1]];
+
+   RETVALUE(ROK);
+}
+#endif
+
+#ifdef LTE_TDD
+/**
+ * @brief This function Processes the Hq Fdbk in case of 
+ *        special Bundling in TDD (FAPIv1.1: Table 79)   
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmPrcSplBundlFdbk
+ *     Purpose: To Interpret the Harq Feedback according to
+ *              table 7.3-1: 36.213
+ *    
+ *          0 = 0 or None (UE detect at least one DL is missed)
+ *          1 = 1 or 4 or 7 ACKs reported
+ *          2 = 2 or 5 or 8 ACKs reported
+ *          3 = 3 or 6 or 9 ACKs reported
+ *          4 = DTX (UE did not transmit anything)
+ *                
+ *  @param[in]  TfuHqInfo    *fdbk
+ *  @param[in]  U8            hqCnt 
+ *  @return  Void 
+ *
+ **/
+#ifdef ANSI
+PRIVATE Void rgSCHDhmPrcSplBundlFdbk
+(
+RgSchCellCb  *cell,
+TfuHqInfo    *fdbk,
+U8            hqCnt
+)
+#else
+PRIVATE Void rgSCHDhmPrcSplBundlFdbk(cell, fdbk, hqCnt)
+(
+RgSchCellCb  *cell;
+TfuHqInfo    *fdbk;
+U8            hqCnt;
+)
+#endif
+{
+   U8       numOfAcks;
+   
+   TRC2(rgSCHDhmPrcSplBundlFdbk);
+
+   /* Num of ACKs reported by UE */
+   numOfAcks = fdbk->isAck[0];
+
+   if(fdbk->isAck[0] == TFU_HQFDB_NACK || 
+      fdbk->isAck[0] == TFU_HQFDB_DTX)
+   {
+      /* NACK/DTX CASE */
+   } 
+   else 
+   {
+      RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, 
+            rgSchNumOfAcksToAckNack[(hqCnt-1)], (numOfAcks - 1));
+
+      fdbk->isAck[0] = rgSchNumOfAcksToAckNack[(hqCnt-1)]
+                                                 [(numOfAcks-1)];  
+   }
+   /* The Hq Fdbk is a combined Ack/Nack for multiple Codewords within
+      the PDSCH trasnmission (spatial bundling). So we have 
+      to assume same feedback for both codewords */ 
+#ifdef LTE_ADV
+   for(U8 idx = 1 ; idx < TFU_MAX_HARQ_FDBKS; idx++)
+   {
+      fdbk->isAck[idx] = fdbk->isAck[0]; 
+   }
+#else
+   fdbk->isAck[1] = fdbk->isAck[0]; 
+#endif
+   
+   RETVOID;
+}
+#endif
+
+/**
+ * @brief This function adds HARQ process to FREE list
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmHqPAdd2FreeLst
+ *     Purpose:  
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[out] RgDlHqProc       *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqPAdd2FreeLst
+(
+RgSchDlHqProcCb         *hqP
+)
+#else
+PUBLIC Void rgSCHDhmHqPAdd2FreeLst(hqP)
+RgSchDlHqProcCb         *hqP;
+#endif
+{
+   TRC2(rgSCHDhmHqPAdd2FreeLst)
+
+#ifdef LAA_DBG
+   if (hqP->hqPLst)
+   {
+      int *p = NULL;
+      printf("Crashing already part of free lst\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+   cmLListAdd2Tail(&hqP->hqE->free, &hqP->lnk);
+   hqP->hqPLst = &hqP->hqE->free;
+
+
+#ifdef LAA_DBG
+   if (hqP->hqE->free.count > 8)
+   {
+      int *p = NULL;
+      printf("Crashing invalid hq count\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+
+#ifdef LTE_ADV
+   rgSCHLaaHndlHqProcFree(hqP);
+#endif
+
+   RETVOID;
+} /* rgSCHDhmHqPAdd2FreeLst */
+
+
+/**
+ * @brief This function adds HARQ process to inUse list
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmHqPAdd2InUseLst
+ *     Purpose:  
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[out] RgDlHqProc       *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqPAdd2InUseLst
+(
+RgSchDlHqProcCb         *hqP
+)
+#else
+PUBLIC Void rgSCHDhmHqPAdd2InUseLst(hqP)
+RgSchDlHqProcCb         *hqP;
+#endif
+{
+   TRC2(rgSCHDhmHqPAdd2InUseLst)
+
+#ifdef LAA_DBG
+   if (hqP->hqPLst)
+   {
+      int *p = NULL;
+      printf("Crashing already part of inuse lst\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+   cmLListAdd2Tail(&hqP->hqE->inUse, &hqP->lnk);
+   hqP->hqPLst = &hqP->hqE->inUse;
+
+
+#ifdef LAA_DBG
+   if (hqP->hqE->inUse.count > 8)
+   {
+      int *p = NULL;
+      printf("Crashing invalid hq count \n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+
+   RETVOID;
+} /* rgSCHDhmHqPAdd2InUseLst */
+
+/**
+ * @brief This function adds HARQ process to FREE list
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmHqPDelFrmFreeLst
+ *     Purpose:  
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[out] RgDlHqProc       *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqPDelFrmFreeLst
+(
+RgSchDlHqProcCb         *hqP
+)
+#else
+PUBLIC Void rgSCHDhmHqPDelFrmFreeLst(hqP)
+RgSchDlHqProcCb         *hqP;
+#endif
+{
+   TRC2(rgSCHDhmHqPDelFrmFreeLst)
+
+#ifdef LAA_DBG
+   if (!hqP->hqPLst)
+   {
+      int *p = NULL;
+      printf("Crashing not part of any lst\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+#ifdef LAA_DBG
+   if (hqP->hqPLst != &hqP->hqE->free)
+   {
+      int *p = NULL;
+      printf("Crashing del from wrong lst\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+
+   cmLListDelFrm(&hqP->hqE->free, &hqP->lnk);
+   hqP->hqPLst = NULLP;
+
+#ifdef LAA_DBG
+   if (hqP->hqE->free.count > 8)
+   {
+      int *p = NULL;
+      printf("Crashing invalid hq count\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+
+   RETVOID;
+} /* rgSCHDhmHqPDelFrmFreeLst */
+
+
+
+/**
+ * @brief This function adds HARQ process to FREE list
+ *
+ * @details
+ *
+ *     Function: rgSCHDhmHqPDelFrmInUseLst
+ *     Purpose:  
+ *     
+ *     Invoked by: scheduler
+ *     
+ *  @param[out] RgDlHqProc       *hqP
+ *  @return  Void      
+ *
+ **/
+#ifdef ANSI
+PUBLIC Void rgSCHDhmHqPDelFrmInUseLst
+(
+RgSchDlHqProcCb         *hqP
+)
+#else
+PUBLIC Void rgSCHDhmHqPDelFrmInUseLst(hqP)
+RgSchDlHqProcCb         *hqP;
+#endif
+{
+   TRC2(rgSCHDhmHqPDelFrmInUseLst)
+
+#ifdef LAA_DBG
+   if (!hqP->hqPLst)
+   {
+      int *p = NULL;
+      printf("Crashing not part of any lst\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+
+   }
+#endif
+#ifdef LAA_DBG
+   if (hqP->hqPLst != &hqP->hqE->inUse)
+   {
+      int *p = NULL;
+      printf("Crashing del from wrong lst\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+
+   cmLListDelFrm(&hqP->hqE->inUse, &hqP->lnk);
+   hqP->hqPLst = NULLP;
+
+#ifdef LAA_DBG
+   if (hqP->hqE->inUse.count > 8)
+   {
+      int *p = NULL;
+      printf("Crashing invalid hq count\n");
+      printf("Crashing %d \n", *p);
+      *p = 10;
+   }
+#endif
+
+   RETVOID;
+} /* rgSCHDhmHqPDelFrmInUseLst */
+
+\f
+/**********************************************************************
+         End of file
+**********************************************************************/