--- /dev/null
+/*******************************************************************************
+################################################################################
+# 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_ram.c
+
+**********************************************************************/
+
+/** @file rg_sch_ram.c
+@brief This file has APIs to handle the random access procedure functionality for the scheduler.
+*/
+
+static const char* RLOG_MODULE_NAME="MAC";
+static int RLOG_MODULE_ID=4096;
+static int RLOG_FILE_ID=171;
+
+/* header include files (.h) */
+#include "envopt.h" /* environment options */
+#include "envdep.h" /* environment dependent */
+#include "envind.h" /* environment independent */
+
+#include "gen.h" /* general */
+#include "ssi.h" /* system services */
+
+#include "cm_tkns.h" /* Common Token Defines */
+#include "cm_llist.h" /* Common Link List Defines */
+#include "cm_hash.h" /* Common Hash List Defines */
+#include "cm_mblk.h" /* common memory link list library */
+#include "cm_lte.h" /* Common LTE */
+
+#include "rg_env.h" /* MAC Environment Defines */
+#include "rgr.h" /* RGR Interface defines */
+#include "rgm.h" /* RGR Interface defines */
+#include "tfu.h" /* TFU Interface defines */
+#include "lrg.h" /* LRG Interface defines */
+#include "rg_env.h" /* Scheduler error defines */
+#include "rg_sch_inf.h" /* Scheduler defines */
+#include "rg_sch_err.h" /* Scheduler error defines */
+#include "rg_sch.h" /* Scheduler defines */
+#include "rg_sch_cmn.h"
+#include "rl_interface.h"
+#include "rl_common.h"
+
+/* header/extern include files (.x) */
+#include "gen.x" /* general */
+#include "ssi.x" /* system services */
+#include "cm5.x" /* Timer */
+#include "cm_tkns.x" /* Common Token Definitions */
+#include "cm_llist.x" /* Common Link List Definitions */
+#include "cm_lib.x" /* Common Library Definitions */
+#include "cm_hash.x" /* Common Hash List Definitions */
+#include "cm_mblk.x" /* common memory link list library */
+#include "cm_lte.x" /* Common LTE */
+
+#include "rgr.x" /* RGR Interface includes */
+#include "rgm.x" /* RGR Interface includes */
+#include "tfu.x" /* TFU Interface includes */
+#include "lrg.x" /* LRG Interface includes */
+
+#include "rg_sch_inf.x" /* typedefs for Scheduler */
+#include "rg_sch.x" /* Scheduler includes */
+#include "rg_sch_cmn.x"
+#ifdef EMTC_ENABLE
+EXTERN Bool rgSCHRamVldtRgrEmtcUeCfg ARGS((
+RgSchCellCb *cell,
+RgrUeCfg *ueCfg
+));
+
+EXTERN S16 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst
+(
+RgSchCellCb *cell
+);
+EXTERN Void rgSCHEmtcUtlUpdCmnNb
+(
+RgSchRaCb *raCb
+);
+EXTERN Void rgSCHEmtcHqPAlloc
+(
+RgSchCellCb *cell,
+RgSchDlHqEnt *hqEnt
+);
+#endif
+/* local defines */
+/* local typedefs */
+PRIVATE Void rgSCHRamUlFreeAllocation ARGS((RgSchUlSf *sf,RgSchUlAlloc *alloc,
+ RgSchCellCb *cell,Bool isEmtc));
+
+PRIVATE S16 rgSCHRamContResCrnti ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
+ RgSchRaCb *raCb, RgSchErrInfo *err));
+PRIVATE S16 rgSCHRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
+#ifdef EMTC_ENABLE
+
+EXTERN S16 rgSCHEmtcRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
+EXTERN S16 rgSCHRamEmtcContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
+EXTERN Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell));
+EXTERN Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell));
+EXTERN Void rgSCHEmtcRaInfoFree ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
+#endif
+#ifdef RGR_V1
+PRIVATE Void rgSCHChkContResGrdTmrExp ARGS((RgSchCellCb *cell));
+PRIVATE Void rgSCHChkContResTmrExp ARGS((RgSchCellCb *cell));
+PRIVATE Void rgSCHRamProcContResExp ARGS((RgSchCellCb *cell,
+ RgSchRaCb *raCb));
+PRIVATE Void rgSCHRamProcContResGrdExp ARGS((RgSchCellCb *cell,
+ RgSchRaCb *raCb));
+#ifdef EMTC_ENABLE
+EXTERN Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell));
+EXTERN Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell));
+#endif
+#endif
+/* forward references */
+
+/**
+ * @brief Check configured preamble id not colliding with non dedicated or PDCCH
+ * order preamble sets. When valid preamble id given check that C-RNTI given
+ * in configuration is not amongst the C-RNTI'smanaged by scheduler
+ *
+ * @details
+ *
+ * Function : rgSCHRamVldtUeCfg
+ *
+ * Processing Steps: Check configured preamble id not colliding with non dedicated or PDCCH
+ * order preamble sets. When valid preamble id given check that C-RNTI given
+ * in configuration is not amongst the C-RNTI'smanaged by scheduler
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in] RgrUeCfg *ueCfg
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamVldtUeCfg
+(
+RgSchCellCb *cell,
+RgrUeCfg *ueCfg
+)
+#else
+PUBLIC S16 rgSCHRamVldtUeCfg(cell, ueCfg)
+RgSchCellCb *cell;
+RgrUeCfg *ueCfg;
+#endif
+{
+ TRC2(rgSCHRamVldtUeCfg);
+ if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
+ {
+ if ((ueCfg->dedPreambleId.val < cell->rachCfg.numRaPreamble) ||
+ (ueCfg->dedPreambleId.val >= RGSCH_MAX_NUM_RA_PREAMBLE) ||
+ ((ueCfg->dedPreambleId.val >= cell->macPreambleSet.start) &&
+ (ueCfg->dedPreambleId.val <= cell->macPreambleSet.start +
+ cell->macPreambleSet.size - 1)) ||
+ ((ueCfg->crnti >= cell->rntiDb.rntiStart) &&
+ (ueCfg->crnti < cell->rntiDb.rntiStart + cell->rntiDb.maxRntis-1))
+#ifdef EMTC_ENABLE
+ || (rgSCHRamVldtRgrEmtcUeCfg(cell,ueCfg))
+#endif
+ )
+ {
+ RETVALUE(RFAILED);
+ }
+ }
+ RETVALUE(ROK);
+}
+
+/**
+ * @brief Handler for Random Access Request
+ *
+ * @details
+ *
+ * Function : rgSCHRamProcRaReq
+ *
+ * -# Create a node for each TfuRaReqInfo element received
+ * -# Initialize the list with the above elements at the raRnti index
+ * in the cell.
+ *
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in] CmLteRnti raRnti
+ * @param[in] RgTfuRaReqInd *raReqInd
+ * @param[out] RgSchErrInfo *err
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamProcRaReq
+(
+U8 raReqCnt,
+RgSchCellCb *cell,
+CmLteRnti raRnti,
+TfuRachInfo *raReqInd,
+CmLteTimingInfo timingInfo,
+RgSchUeCb *ue,
+RgSchErrInfo *err
+)
+#else
+PUBLIC S16 rgSCHRamProcRaReq(raReqCnt, cell, raRnti, raReqInd, timingInfo, ue, err)
+U8 raReqCnt;
+RgSchCellCb *cell;
+CmLteRnti raRnti;
+TfuRachInfo *raReqInd;
+CmLteTimingInfo timingInfo;
+RgSchUeCb *ue;
+RgSchErrInfo *err;
+#endif
+{
+ RgSchRaReqInfo *raReqInfo;
+ U16 raIndex;
+#ifdef LTE_TDD
+ U8 fid;
+ U8 tid;
+#endif
+
+ TRC2(rgSCHRamProcRaReq)
+
+
+ /* SR_RACH_STATS : RACH REQ */
+ rgNumPrachRecvd += raReqInd->numRaReqInfo;
+
+ /* ccpu00132523- Moved out this from for loop as updating of raIndex is
+ * relates to only raRnti and all preambles having same raRnti*/
+#ifdef LTE_TDD
+ /* UL subframes do not occupy all the subframes in a radio frame.
+ * So RA Rnti index to be calculated based on actual UL subframe index. */
+ /* Get the actual subframe number */
+ tid = (raRnti-1)%RGSCH_NUM_SUB_FRAMES;
+ /* Get the frequency index in the subframe */
+ fid = ((raRnti-1) / RGSCH_NUM_SUB_FRAMES)* RGSCH_NUM_SUB_FRAMES;
+ /* Get the index of RA RNTI in the array */
+ raIndex = ((timingInfo.sfn % cell->raInfo.maxRaSize) \
+ * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES) + \
+ tid + fid;
+ /* Fixes for RACH handling in TDD: Removed deletion of queued RaReq */
+#else
+ /* ccpu00132523- Placing the raReq into array based on RA SFN */
+ raIndex = (timingInfo.sfn & 1) * RGSCH_MAX_RA_RNTI + raRnti-1;
+#endif
+
+ /* allocate new raReqInfos and enqueue them */
+ if (raReqInd->raReqInfoArr[raReqCnt].rapId >= RGSCH_MAX_NUM_RA_PREAMBLE)
+ {
+ RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
+ "RARNTI:%d rgSCHTomRaReqInd(): RAM processing failed errType(%d) ",
+ raReqInd->raRnti);
+ RETVALUE(RFAILED);
+ }
+
+ /* SR_RACH_STATS : DED PREAMB*/
+ if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
+ {
+ rgNumDedPream++;
+ }
+
+
+#ifdef LTE_L2_MEAS
+ if (raReqInd->raReqInfoArr[raReqCnt].rapId < cell->rachCfg.sizeRaPreambleGrpA)
+ {
+ cell->raPrmbs.preamGrpA++;
+ }
+ else if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
+ {
+ cell->raPrmbs.dedPream++;
+ }
+ else
+ {
+ cell->raPrmbs.preamGrpB++;
+ }
+#endif
+
+ if((rgSCHUtlAllocSBuf(cell->instIdx, (Data **)(&raReqInfo),
+ sizeof(RgSchRaReqInfo))) == RFAILED)
+ {
+ RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamProcRaReq(): Allocation"
+ " of RaReq failed RARNTI:%d",raRnti);
+ err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
+ RETVALUE(RFAILED);
+ }
+
+ /* Insert the given raReqInfo */
+ /* RACHO */
+ raReqInfo->timingInfo = timingInfo;
+ raReqInfo->raReq = raReqInd->raReqInfoArr[raReqCnt];
+ raReqInfo->raReqLstEnt.next = NULLP;
+ raReqInfo->raReqLstEnt.prev = NULLP;
+ raReqInfo->raReqLstEnt.node = (PTR)raReqInfo;
+ /* ccpu00133504 */
+ raReqInfo->ue = ue;
+
+#ifndef LTE_TDD
+ RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->raInfo.raReqLst, raIndex);
+#endif
+ /* RACHO: If dedicated preamble, then give preference by appending at front */
+ if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
+ {
+ cmLListFirst(&cell->raInfo.raReqLst[raIndex]);
+ cmLListInsCrnt(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
+ }
+ else
+ {
+ cmLListAdd2Tail(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
+ }
+
+ RETVALUE(ROK);
+} /* rgSCHRamProcRaReq */
+
+/**
+ * @brief Handler for Random Access control block creation
+ *
+ * @details
+ *
+ * Function : rgSCHRamCreateRaCb
+ * Creates a raCb and gives the same to scheduler for its updation
+ *
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in, out] RgSchRaCb **raCb
+ * @param[out] RgSchErrInfo *err
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamCreateRaCb
+(
+RgSchCellCb *cell,
+RgSchRaCb **raCb,
+RgSchErrInfo *err
+)
+#else
+PUBLIC S16 rgSCHRamCreateRaCb(cell, raCb, err)
+RgSchCellCb *cell;
+RgSchRaCb **raCb;
+RgSchErrInfo *err;
+#endif
+{
+ RgSchRntiLnk *rntiLnk;
+ Inst inst = cell->instIdx;
+
+ TRC2(rgSCHRamCreateRaCb)
+
+ if((rgSCHUtlAllocSBuf(inst, (Data **)(raCb),
+ sizeof(RgSchRaCb))) == RFAILED)
+ {
+ RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
+ "RaCb failed");
+ err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
+ RETVALUE(RFAILED);
+ }
+
+ rntiLnk = rgSCHDbmGetRnti(cell);
+ if(rntiLnk != NULLP)
+ {
+ (*raCb)->rntiLnk = rntiLnk;
+ (*raCb)->tmpCrnti = rntiLnk->rnti;
+ }
+ else
+ {
+
+ /* SR_RACH_STATS: RNTI POOL Exhaution */
+ rgNumRarFailDuetoRntiExhaustion++;
+
+ /* No rnti available! */
+ RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
+ "temporary RNTI failed at MAC(CRNTI exhausted)");
+ /* ccpu00117052 - MOD - Passing double pointer
+ for proper NULLP assignment*/
+ rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
+ err->errCause = RGSCHERR_RAM_RNTI_EXHAUST;
+ RETVALUE(RFAILED);
+ }
+
+ /* Allocate and initialize the DL HARQ portion of the RACB */
+ (*raCb)->dlHqE = rgSCHDhmHqEntInit(cell);
+ if ((*raCb)->dlHqE == NULLP)
+ {
+ /* No memory available! */
+ RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Creation of"
+ " DL HARQ failed");
+ /* ccpu00117052 - MOD - Passing double pointer
+ for proper NULLP assignment*/
+ rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
+ err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
+ RETVALUE(RFAILED);
+ }
+#ifdef EMTC_ENABLE
+ (*raCb)->isEmtcRaCb = FALSE;
+ rgSCHEmtcHqPAlloc(cell, (*raCb)->dlHqE);
+#endif
+ (*raCb)->dlHqE->raCb = (*raCb);
+ /* Initialize RaCb's contents */
+ (*raCb)->timingInfo = cell->crntTime;
+ (*raCb)->raState = RGSCH_RA_MSG3_PENDING;
+ (*raCb)->toDel = FALSE;
+ (*raCb)->phr.pres = FALSE;
+
+ /* Insert the created raCb into raCb list of cell */
+ (*raCb)->raCbLnk.node = (PTR)(*raCb);
+ cmLListAdd2Tail(&cell->raInfo.raCbLst, &(*raCb)->raCbLnk);
+
+ RETVALUE(ROK);
+} /* rgSCHRamCreateRaCb */
+
+/**
+ * @brief Handler for Ue Configuration Request
+ *
+ * @details
+ *
+ * Function : rgSCHRamRgrUeCfg
+ *
+ * This function handles the UE config received based on the state of the
+ * raCb.
+ * -# If raCb is in RGSCH_RA_MSG4_PENDING state, it shall update the harq
+ * information to UeCb and update the references.
+ * -# If raCb is in RGSCH_RA_MSG4_DONE, then it shall free the raCb
+ *
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in,out] RgSchUeCb *ue
+ * @param[in,out] RgSchRaCb *raCb
+ * @param[out] RgSchErrInfo *err
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamRgrUeCfg
+(
+RgSchCellCb *cell,
+RgSchUeCb *ue,
+RgSchRaCb *raCb,
+RgSchErrInfo *err
+)
+#else
+PUBLIC S16 rgSCHRamRgrUeCfg(cell, ue, raCb, err)
+RgSchCellCb *cell;
+RgSchUeCb *ue;
+RgSchRaCb *raCb;
+RgSchErrInfo *err;
+#endif
+{
+ /* Releasing HARQ processes of old UE when ue
+ * reconfig with new crnti */
+ /* U32 cnt; */
+ RgSchDlHqEnt **hqEnt = &(RG_SCH_CMN_GET_UE_HQE(ue, cell));
+ RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
+ TRC2(rgSCHRamRgrUeCfg)
+
+
+ /* Fix : set UE inactive in DL until UE is reinitialization completed */
+ ue->dl.dlInactvMask |= RG_HQENT_INACTIVE;
+ ue->ul.ulInactvMask |= RG_HQENT_INACTIVE;
+
+ if(raCb->raState == RGSCH_RA_MSG4_PENDING)
+ {
+ raCb->ue = ue;
+ ue->rntiLnk = raCb->rntiLnk;
+ /* Update UL Harq process information */
+ /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
+ ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
+ }
+ else if(raCb->raState == RGSCH_RA_MSG4_DONE)
+ {
+ ue->rntiLnk = raCb->rntiLnk;
+ /* Update UL Harq process information */
+ /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
+ ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
+ /* Fix : syed Assign hqEnt to UE only if msg4 is done */
+ rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb);
+ }
+ else
+ {
+ err->errCause = RGSCHERR_RAM_NO_MSG3_RCVD;
+ *hqEnt = NULLP;
+ raCb->dlHqE->ue = NULLP;
+ RETVALUE(RFAILED);
+ }
+
+ RETVALUE(ROK);
+} /* rgSCHRamRgrUeCfg */
+
+
+/**
+ * @brief Handler for C-RNTI based contention resolution
+ *
+ * @details
+ *
+ * Function : rgSCHRamContResCrnti
+ *
+ * This function shall be invoked once Msg3 indicates C-RNTI based
+ * contention resolution.This shall indicate the scheduler regarding
+ * C-RNTI based uplink grant.
+ *
+ *
+ * @param[in,out] RgSchCellCb *cell
+ * @param[in,out] RgSchUeCb *ue
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PRIVATE S16 rgSCHRamContResCrnti
+(
+RgSchCellCb *cell,
+RgSchUeCb *ue,
+RgSchRaCb *raCb,
+RgSchErrInfo *err
+)
+#else
+PRIVATE S16 rgSCHRamContResCrnti(cell, ue, raCb, err)
+RgSchCellCb *cell;
+RgSchUeCb *ue;
+RgSchRaCb *raCb;
+RgSchErrInfo *err;
+#endif
+{
+ TfuUlCqiRpt ulCqiRpt;
+ RgSchCmnCell *cellSch= (RgSchCmnCell *)(cell->sc.sch);
+ TRC2(rgSCHRamContResCrnti)
+
+
+ /* Fix: syed It is incorrect to copy over msg3HqProc to ueCb's
+ * UL harq proc. In case of Crnti based RACH, ueCb has valid context which
+ * cannot be over written. It was leading to a crash. */
+
+ rgSCHUtlRecMsg3Alloc(cell, ue, raCb);
+
+ /* Fix for ccpu00123908: Reset the UL CQI to the cell default value here */
+ ulCqiRpt.isTxPort0 = TRUE;
+ ulCqiRpt.numSubband = 0;
+ /* Fix : syed HO UE does not have a valid ue->rntiLnk */
+ ulCqiRpt.rnti = ue->ueId;
+ /* rg002.301:[ccpu00124018]-MOD- Avoiding hard coding of CQI and retriving from cell config*/
+ ulCqiRpt.wideCqi = cellSch->ul.dfltUlCqi;
+ rgSCHUtlUlCqiInd(cell, ue, &ulCqiRpt);
+
+
+ /* Invoke scheduler to indicate UL grant req for contention resolution */
+ rgSCHUtlContResUlGrant(cell, ue, err);
+
+ if (raCb->phr.pres == TRUE)
+ {
+ rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, err);
+ }
+ /* No need of raCb any more */
+ rgSCHRamDelRaCb(cell, raCb, TRUE);
+
+ RETVALUE(ROK);
+} /* rgSCHRamContResCrnti */
+
+
+/**
+ * @brief Handler for CCCH SDU based contention resolution
+ *
+ * @details
+ *
+ * Function : rgSCHRamContResCcchsdu
+ *
+ * This function shall be invoked once Msg3 indicates contention resolution
+ * based on CCCH sdu. This shall update the raCb state to
+ * RGSCH_RA_MSG4_PENDING.
+ *
+ *
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PRIVATE S16 rgSCHRamContResCcchsdu
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb
+)
+#else
+PRIVATE S16 rgSCHRamContResCcchsdu(cell, raCb)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+#endif
+{
+#ifdef RGR_V1
+ CmLteTimingInfo expTime = {0};
+ RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
+#endif
+ TRC2(rgSCHRamContResCcchsdu)
+ if(raCb->raState != RGSCH_RA_MSG3_PENDING)
+ {
+ RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
+ "RNTI:%d RaCb in wrong State %d Drop Msg 3",
+ raCb->rntiLnk->rnti,
+ raCb->raState);
+ RETVALUE(ROK);
+ }
+
+ raCb->raState = RGSCH_RA_MSG4_PENDING;
+
+#ifdef RGR_V1
+ if(cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay > 0)
+ {
+ /* Set the contension resolution guard timer =
+ Cont Res Timer - Max msg4 Tx Delay */
+ RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime,
+ (cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay));
+ }
+ else
+ {
+ /* Schedule the CRI CE in the next Sf itself */
+ RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime, 1);
+ }
+ raCb->expiryTime = expTime;
+ raCb->contResTmrLnk.node = (PTR)(raCb);
+ cmLListAdd2Tail(&(cell->contResGrdTmrLst), &(raCb->contResTmrLnk));
+#endif
+ RETVALUE(ROK);
+} /* rgSCHRamContResCcchsdu */
+
+
+/**
+ * @brief Handler for Msg3
+ *
+ * @details
+ *
+ * Function : rgSCHRamProcMsg3
+ *
+ * This function processes the received Msg3 and identifies the type of
+ * contention resolution and act accordingly.
+ *
+ *
+ * @param[in,out] RgSchCellCb *cell
+ * @param[in,out] RgSchUeCb *ue
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamProcMsg3
+(
+RgSchCellCb *cell,
+RgSchUeCb *ue,
+RgSchRaCb *raCb,
+RgInfUeDatInd *pdu,
+RgSchErrInfo *err
+)
+#else
+PUBLIC S16 rgSCHRamProcMsg3(cell, ue, raCb, pdu, err)
+RgSchCellCb *cell;
+RgSchUeCb *ue;
+RgSchRaCb *raCb;
+RgInfUeDatInd *pdu;
+RgSchErrInfo *err;
+#endif
+{
+ TRC2(rgSCHRamProcMsg3)
+
+
+ /* Update raCb with PHR if received along with Msg3 */
+ if (pdu->ceInfo.bitMask & RGSCH_PHR_CE_PRSNT)
+ {
+ /* PHR present */
+ raCb->phr.pres = TRUE;
+ raCb->phr.val = pdu->ceInfo.ces.phr;
+ }
+ if (ue)
+ {
+ rgSCHRamContResCrnti(cell, ue, raCb, err);
+ }
+ else
+ {
+#ifdef EMTC_ENABLE
+ if(TRUE == raCb->isEmtcRaCb)
+ {
+ /* starting the emtc Contention resolution timer */
+ rgSCHRamEmtcContResCcchsdu(cell,raCb);
+ }
+ else
+#endif
+ {
+ rgSCHRamContResCcchsdu(cell, raCb);
+ }
+ }
+
+ RETVALUE(ROK);
+} /* rgSCHRamProcMsg3 */
+
+
+/**
+ * @brief Handler for Updating Bo received in StaRsp
+ *
+ * @details
+ *
+ * Function : rgSCHRamUpdtBo
+ *
+ * This function shall be invoked by RAM once it receives staRsp on CCCH
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in,out] RgSchRaCb *raCb
+ * @param[in] RgRguCmnStaRsp *staRsp
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamUpdtBo
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb,
+RgInfCmnBoRpt *staRsp
+)
+#else
+PUBLIC S16 rgSCHRamUpdtBo(cell, raCb, staRsp)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+RgInfCmnBoRpt *staRsp;
+#endif
+{
+ TRC2(rgSCHRamUpdtBo)
+
+ /* Update Bo in RaCb */
+ raCb->dlCcchInfo.bo = (U32)(staRsp->bo);
+ /* SR_RACH_STATS : MSG4 WITH CCCH SDU */
+ rgNumMsg4WithCCCHSdu++;
+
+ /* add this to the "tobeSchdLst" */
+ /* MSG4 Fix Start */
+ rgSCHRamAddToRaInfoSchdLst(cell, raCb);
+ /* MSG4 Fix End */
+
+ RETVALUE(ROK);
+} /* rgSCHRamUpdtBo */
+
+/**
+ * @brief Handler for Msg3 Feedback indication
+ *
+ * @details
+ *
+ * Function : rgSCHRamMsg3DatInd
+ *
+ * This function shall be invoked by TOM once the transmission of Msg4 is
+ * ACKed/NACKed.
+ * This shall invoke UHM to set ACK for Msg3 reception.
+ *
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamMsg3DatInd
+(
+RgSchRaCb *raCb
+)
+#else
+PUBLIC S16 rgSCHRamMsg3DatInd(raCb)
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamMsg3DatInd)
+
+ /* SR_RACH_STATS : MSG3 ACK*/
+ rgNumMsg3CrcPassed++;
+ /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
+ rgSCHUhmProcMsg3DatInd(&(raCb->msg3HqProc));
+
+ RETVALUE(ROK);
+} /* rgSCHRamMsg3DatInd */
+
+/**
+ * @brief Handler for Msg3 Feedback indication
+ *
+ * @details
+ *
+ * Function : rgSCHRamMsg3FailureInd
+ *
+ * This function shall be invoked by TOM once the transmission of Msg4 is
+ * ACKed/NACKed.
+ * This shall invoke UHM to set ACK for Msg3 reception.
+ *
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamMsg3FailureInd
+(
+RgSchRaCb *raCb
+)
+#else
+PUBLIC S16 rgSCHRamMsg3FailureInd(raCb)
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamMsg3FailureInd)
+
+ /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
+ rgSCHUhmProcMsg3Failure(&(raCb->msg3HqProc));
+
+ RETVALUE(ROK);
+} /* rgSCHRamMsg3FailureInd */
+
+/**
+ * @brief Handler for Msg4 Feedback indication
+ *
+ * @details
+ *
+ * Function : rgSCHRamMsg4FdbkInd
+ *
+ * This function shall be invoked by TOM once the transmission of Msg4 is
+ * ACKed/NACKed.
+ * This shall invoke UHM to set ACK for Msg3 reception.
+ *
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamMsg4FdbkInd
+(
+RgSchRaCb *raCb
+)
+#else
+PUBLIC S16 rgSCHRamMsg4FdbkInd(raCb)
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamMsg4FdbkInd)
+
+ RETVALUE(ROK);
+} /* rgSCHRamMsg4FdbkInd */
+
+
+/**
+ * @brief Handler for Msg4 state updation
+ *
+ * @details
+ *
+ * Function : rgSCHRamMsg4Done
+ *
+ * This function shall be invoked by DHM once the transmission of Msg4 is
+ * done. This shall delete the raCb if there is a valid Ue or if this is to
+ * be deleted. If not this shall update the state of the raCb.
+ *
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in,out] RgSchRaCb *raCb
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamMsg4Done
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb
+)
+#else
+PUBLIC S16 rgSCHRamMsg4Done(cell, raCb)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamMsg4Done)
+
+ RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
+ "rgSCHRamMsg4Done(): tmpCRNTI = %u",
+ raCb->tmpCrnti);
+
+ if(raCb->ue != NULLP)
+ {
+ /* Fix : syed Let this funtion decide on releasing
+ * hqP than the caller of this function otherwise sometimes it
+ * might lead to incorrec NDI setting. */
+ rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
+ /* Fix : syed Assign hqEnt to UE only if msg4 is done */
+ rgSCHDhmAssgnUeHqEntFrmRaCb(raCb->ue, raCb);
+#ifdef EMTC_ENABLE
+ if(TRUE == raCb->isEmtcRaCb)
+ {
+ rgSCHEmtcUtlUpdCmnNb(raCb);
+ }
+#endif
+ /* MS_FIX :Proceed to CCCH scheduling irrespective of
+ * MSG4 result */
+ if (raCb->ue->dlCcchInfo.bo)
+ {
+#ifdef EMTC_ENABLE
+ /*if CR-ID Ack has been received ,Add emtc Ue to cchSduUeLst*/
+ if(TRUE == raCb->isEmtcRaCb)
+ {
+ rgSCHUtlAddUeToEmtcCcchSduLst(cell, raCb->ue);
+ }
+ else
+#endif
+ {
+ rgSCHUtlAddUeToCcchSduLst(cell, raCb->ue);
+ }
+ }
+ /* Rnti shall not be released as Ue exists with this rnti */
+ rgSCHRamDelRaCb(cell, raCb, FALSE);
+ }
+ else if(raCb->toDel == TRUE)
+ {
+#ifdef XEON_SPECIFIC_CHANGES
+ CM_LOG_DEBUG(CM_LOG_ID_SCH, "Deleting RacB:%d\n", raCb->tmpCrnti);
+#endif
+ /* Delete RACB and release RNTI */
+ rgSCHRamDelRaCb(cell, raCb, TRUE);
+ }
+ else
+ {
+#ifdef XEON_SPECIFIC_CHANGES
+ CM_LOG_DEBUG(CM_LOG_ID_SCH, "Releasing Harq of RacB:%d\n", raCb->tmpCrnti);
+#endif
+ raCb->raState = RGSCH_RA_MSG4_DONE;
+ /* Release harq process as final feedback is received for Msg4. In other
+ * cases, delRaCb will take care of releasing the harq process */
+ printf("=======Harq process released \n");
+ RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
+ "Harq process released ");
+ rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
+ }
+
+ RETVALUE(ROK);
+} /* rgSCHRamMsg4Done */
+
+
+/**
+ * @brief Handler for deletion
+ *
+ * @details
+ *
+ * Function : rgSCHRamDelRaCb
+ *
+ * This function shall be invoked whenever a raCb needs to be deleted.
+ * Invoked by both RAM and downlink scheduler
+ *
+ * @param[in] RgSchCellCb *cell
+ * @param[in,out] RgSchRaCb *raCb
+ * @param[in] Bool rlsRnti
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamDelRaCb
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb,
+Bool rlsRnti
+)
+#else
+PUBLIC S16 rgSCHRamDelRaCb(cell, raCb, rlsRnti)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+Bool rlsRnti;
+#endif
+{
+ Inst inst = cell->instIdx;
+ Bool isEmtc = FALSE;
+ TRC2(rgSCHRamDelRaCb)
+
+ /* Delete from all the lists it is enqueued */
+ cmLListDelFrm(&(cell->raInfo.raCbLst),&(raCb->raCbLnk));
+#ifdef EMTC_ENABLE
+ /*ue Type is EMTC, then Delete the toBeSchedLst and stop the Guard Timer */
+ if(TRUE == raCb->isEmtcRaCb)
+ {
+ rgSCHRamEmtcDelRaCb(cell,raCb);
+ isEmtc = TRUE;
+ }
+ else
+#endif
+ {
+ if (raCb->schdLnk.node == (PTR)raCb)
+ {
+ rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
+ }
+#ifdef RGR_V1
+ else if(raCb->contResTmrLnk.node != NULLP)
+ {
+ cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
+ raCb->contResTmrLnk.node = NULLP;
+ }
+#endif
+ }
+
+ if(rlsRnti == TRUE)
+ {
+ rgSCHUtlRlsRnti(cell, raCb->rntiLnk, FALSE, 0);
+ }
+
+ /* Check if msg4 Hq Proc has been released. If not, release it */
+ if (raCb->dlHqE )
+ {
+ if (raCb->dlHqE->msg4Proc != NULLP)
+ {
+ /* Fix: syed Remove the msg4Proc if it waiting in sf->tbs list for
+ * harq feedback */
+ if ((raCb->dlHqE->msg4Proc->subFrm != NULLP) &&
+ (raCb->dlHqE->msg4Proc->hqPSfLnk.node != NULLP))
+ {
+ RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"TMP CRNTI:%d RACH FAILURE!! "
+ "msg4proc removed from SF", raCb->tmpCrnti);
+ rgSCHUtlDlHqPTbRmvFrmTx(raCb->dlHqE->msg4Proc->subFrm,
+ raCb->dlHqE->msg4Proc, 0, FALSE);
+ }
+ /* Fix: syed Remove the msg4Proc from cell
+ * msg4Retx Queue. I have used CMN scheduler function
+ * directly. Please define a new API and call this
+ * function through that. */
+ rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, raCb->dlHqE->msg4Proc);
+ rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
+ }
+
+ /* Mark the raCb pointer in dlHqE to NULLP */
+ raCb->dlHqE->raCb = NULLP;
+
+ rgSCHDhmDelHqEnt(cell, &raCb->dlHqE);
+ }
+ /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
+ * from adaptive retx List. Free the alloc if it exists. */
+ if (raCb->msg3HqProc.reTxLnk.node)
+ {
+ //TODO_SID: Need to take care of retxLst
+ //cmLListDelFrm(raCb->msg3HqProc.reTxAlloc.reTxLst, &raCb->msg3HqProc.reTxLnk);
+ raCb->msg3HqProc.reTxLnk.node = (PTR)NULLP;
+ }
+
+ if (raCb->msg3HqProc.alloc)
+ {
+ /* Fix: syed During GPR, please write an API instead of direct
+ * call to cmn scheduler function */
+ RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
+ /*ccpu00130356 - MOD- To avoid segmentation problem because of double
+ free due to recursive calling of rgSCHRamDelRaCb*/
+ rgSCHRamUlFreeAllocation(&cellUl->ulSfArr[raCb->msg3HqProc.ulSfIdx],
+ raCb->msg3HqProc.alloc,
+ cell,isEmtc);
+ }
+
+#ifdef EMTC_ENABLE
+ if(TRUE == raCb->isEmtcRaCb)
+ {
+ rgSCHEmtcRaInfoFree(cell, raCb);
+ }
+#endif
+ rgSCHUtlFreeSBuf(inst, (Data **)&raCb, sizeof(RgSchRaCb));
+
+ RETVALUE(ROK);
+} /* rgSCHRamDelRaCb */
+
+
+/**
+ * @brief TTI Handler for RAM module
+ *
+ * @details
+ *
+ * Function : rgSCHRamTtiHndlr
+ *
+ * This function shall be invoked upon TtiInd by TOM
+ * This shall
+ * - remove RaReqs added to the queue for a raRnti for which PHY may
+ * give the requests in the next subframe
+ * - remove raCbs which are not yet processed once the
+ * counter for raCb processing expires.
+ *
+ *
+ * @param[in,out] RgSchCellCb *cell
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamTtiHndlr
+(
+RgSchCellCb *cell
+)
+#else
+PUBLIC S16 rgSCHRamTtiHndlr(cell)
+RgSchCellCb *cell;
+#endif
+{
+ RgSchRaCb *raCb;
+ U16 raSfn;
+ U16 crntSfn;
+ U16 dist; /* Number of frames between raCb's creation and crnt
+ frame */
+ U8 idx;
+ U32 maxCnt;
+#ifndef LTE_TDD
+ U8 winGap;
+ U8 raIdx;
+ RgSchRaReqInfo *raReqInfo;
+#else
+ CmLteTimingInfo frm;
+ U8 raIdx;
+#endif
+
+ TRC2(rgSCHRamTtiHndlr)
+
+ crntSfn = cell->crntTime.sfn;
+
+#ifdef RGR_V1
+ /*Check if Contention resolution guard timer expiring in the TTI*/
+ rgSCHChkContResGrdTmrExp(cell);
+ /*Check if Contention resolution timer expiring in the TTI*/
+ rgSCHChkContResTmrExp(cell);
+#ifdef EMTC_ENABLE
+ /*Check if EMTC Contention resolution guard timer expiring in the TTI*/
+ rgSCHChkEmtcContResGrdTmrExp(cell);
+ /*Check if EMTC Contention resolution timer expiring in the TTI*/
+ rgSCHChkEmtcContResTmrExp(cell);
+#endif
+#endif
+#ifndef LTE_TDD
+
+ /* Delete the RA requests for which RAR window expired in this subframe
+ * And were not considered for RAR scheduling*/
+ winGap = (rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat]-1)+
+ (cell->rachCfg.raWinSize -1 ) + RGSCH_RARSP_WAIT_PERIOD;
+
+ raIdx = (((crntSfn & 1) * RGSCH_MAX_RA_RNTI+ cell->crntTime.subframe
+ + RG_SCH_CMN_DL_DELTA - winGap)+ RGSCH_RAREQ_ARRAY_SIZE )
+ % RGSCH_RAREQ_ARRAY_SIZE;
+
+ /* Flush the already existing raReqs against the given raRnti */
+
+ maxCnt = cell->raInfo.raReqLst[raIdx].count;
+ for (idx = 0; idx < maxCnt; idx++)
+ {
+ raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raIdx].first->node);
+ cmLListDelFrm(&(cell->raInfo.raReqLst[raIdx]),&(raReqInfo->raReqLstEnt));
+ /* ccpu00117052 - MOD - Passing double pointer
+ for proper NULLP assignment*/
+ rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReqInfo,
+ sizeof(RgSchRaReqInfo));
+ }
+#else
+ /* Fixes for RACH handling: Added deletion of queued RaReq */
+ frm = cell->crntTime;
+ RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
+ if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe] !=
+ RG_SCH_TDD_UL_SUBFRAME)
+ {
+ raIdx = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe]-1;
+ rgSCHRamDelRaReq(cell, cell->crntTime, raIdx);
+ }
+#endif
+
+ /* Remove the RACBs which are timed out */
+ /* ccpu00132536:MOD- racb timeout will be verified in each SFN such that
+ * the RACB whose processing is not completed in RG_MAX_RA_PRC_FRM
+ * will be deleted*/
+ if (cell->crntTime.subframe == 0)
+ {
+ maxCnt = cell->raInfo.raCbLst.count;
+ for (idx = 0; idx < maxCnt; idx++)
+ {
+ raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
+ /* Calculate number of frames between raCb's creation and crnt frame */
+ raSfn = raCb->timingInfo.sfn;
+ dist = (crntSfn + (RGSCH_MAX_SFN - raSfn)) % RGSCH_MAX_SFN;
+ /* Delete RaCbs whose processing is not complete within
+ * "cell->t300TmrVal" frames */
+ /* raCb not to be deleted if msg4 is not completed */
+ /* raCb should not be deleted(RNTI should not be released) if UE is present
+ * as it means the application still holds the RNTI. raCb will get deleted
+ * as part of UE deletion. raCb will anyway get deleted without releasing RNTI on success/failure of MSG4*/
+
+ if (dist >= cell->t300TmrVal)
+ {
+ if ((raCb->dlHqE->msg4Proc == NULLP) && (raCb->dlHqE->ue == NULLP))
+ {
+ rgSCHRamDelRaCb(cell, raCb, TRUE);
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ RETVALUE(ROK);
+} /* rgSCHRamTtiHndlr */
+
+
+/**
+ * @brief Function for handling cell delete
+ *
+ * @details
+ *
+ * Function : rgSCHRamFreeCell
+ *
+ * This function shall be invoked whenever a cell needs to be deleted.
+ * This shall remove raCbs and raReqs stored in cell.
+ *
+ *
+ * @param[in,out] RgSchCellCb *cell
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamFreeCell
+(
+RgSchCellCb *cell
+)
+#else
+PUBLIC S16 rgSCHRamFreeCell(cell)
+RgSchCellCb *cell;
+#endif
+{
+ RgSchRaReqInfo *raReqInfo;
+ RgSchRaCb *raCb;
+ U8 idx;
+ U8 raCbCnt;
+ Inst inst = cell->instIdx;
+ U8 lstSz;
+#ifdef LTE_TDD
+ U8 maxUlSubframes;
+ U8 maxDlSubframes;
+#endif
+
+
+ TRC2(rgSCHRamFreeCell)
+
+
+#ifdef LTE_TDD
+ maxUlSubframes =
+ rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
+ maxDlSubframes =
+ rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
+ lstSz = cell->raInfo.maxRaSize * RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
+ maxUlSubframes;
+#else
+ /* ccpu00133557- MEM LEAK FIX- Need to free all the nodes in RA Array list */
+ lstSz = RGSCH_RAREQ_ARRAY_SIZE;
+#endif
+
+ for (idx = 0; idx < lstSz; idx++)
+ {
+ /* Delete and free raReqs stored */
+ /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
+ while(cell->raInfo.raReqLst[idx].count)
+ {
+ raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[idx].first->node);
+ cmLListDelFrm(&(cell->raInfo.raReqLst[idx]),&(raReqInfo->raReqLstEnt));
+ /* ccpu00117052 - MOD - Passing double pointer
+ for proper NULLP assignment*/
+ rgSCHUtlFreeSBuf(inst, (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
+ }
+ }
+
+#ifdef LTE_TDD
+ /* Delete the RACH response list*/
+ /* ccpu00117052 - MOD - Passing double pointer
+ for proper NULLP assignment*/
+ rgSCHUtlFreeSBuf(inst,
+ (Data **)(&(cell->rachRspLst)), sizeof(RgSchTddRachRspLst) * \
+ maxDlSubframes);
+#endif
+
+ /* Delete raCbs in the "to be scheduled" list */
+ /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
+ while(cell->raInfo.toBeSchdLst.count)
+ {
+ raCb = (RgSchRaCb *)(cell->raInfo.toBeSchdLst.first->node);
+ /* MSG4 Fix Start */
+
+ rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
+ /* MSG4 Fix End */
+ }
+#ifdef EMTC_ENABLE
+ /* Delete raCbs in the "Emtc to be scheduled" list */
+ if(cell->emtcEnable)
+ {
+ rgSCHRamRmvAllFrmEmtcRaInfoSchdLst(cell);
+ }
+#endif
+
+ raCbCnt = cell->raInfo.raCbLst.count;
+
+ /* Delete and free raCbs stored */
+ for (idx = 0; idx < raCbCnt; idx++)
+ {
+ raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
+ rgSCHRamDelRaCb(cell, raCb, TRUE);
+ }
+
+ RETVALUE(ROK);
+} /* rgSCHRamFreeCell */
+#ifdef RGR_V1
+#ifdef ANSI
+PRIVATE Void rgSCHRamProcContResExp
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb
+)
+#else
+PRIVATE Void rgSCHRamProcContResExp (cell, raCb)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamProcContResExp);
+ raCb->expiryTime.sfn = RGSCH_CONTRES_EXP;
+ /*MSG4 Fix*/
+ if (raCb->ue)
+ {
+ /* UE exists and RNTI will be released as part of UE DEL */
+ rgSCHRamDelRaCb(cell, raCb, FALSE);
+ }
+ else
+ {
+ /* Calling Release RNTI, which would perform Racb deletion
+ * RNTI removal and RNTI release indication to MAC. */
+ /* Delete RACB and release RNTI */
+ rgSCHRamDelRaCb(cell, raCb, TRUE);
+ }
+ RETVOID;
+}
+
+#ifdef ANSI
+PRIVATE Void rgSCHRamProcContResGrdExp
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb
+)
+#else
+PRIVATE Void rgSCHRamProcContResGrdExp (cell, raCb)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamProcContResGrdExp)
+
+
+/*Guard timer has expired, schedule only the contention REsolution CE with
+ * zero bo*/
+ raCb->dlCcchInfo.bo = 0;
+ /* SR_RACH_STATS : MSG4 WO CCCH SDU */
+ rgNumMsg4WoCCCHSdu++;
+
+ /* add this to the "tobeSchdLst" */
+ raCb->schdLnk.node = (PTR)(raCb);
+
+ cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
+ raCb->contResTmrLnk.node = NULLP;
+
+ /* MSG4 Fix Start */
+ RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
+ "Con Res Grd Tmr exp RNTI:%d",
+ raCb->rntiLnk->rnti);
+ rgSCHRamAddToRaInfoSchdLst(cell, raCb);
+ /* MSG4 Fix End */
+ RETVOID;
+
+}
+/**
+ * @brief Check the Contention Resolution Guard Timer Expiry.
+ *
+ * @details
+ *
+ * Function: rgSCHChkContResTmrExp
+ *
+ *
+ * Invoked by: Scheduler
+ * @param[in] RgSchCellCb *cell
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PRIVATE Void rgSCHChkContResTmrExp
+(
+RgSchCellCb *cell
+)
+#else
+PRIVATE Void rgSCHChkContResTmrExp(cell)
+RgSchCellCb *cell;
+#endif
+{
+ CmLList *chkLnk = NULLP;
+ RgSchRaCb *raCb = NULLP;
+
+ TRC2(rgSCHChkContResTmrExp)
+
+ chkLnk = cmLListFirst(&(cell->contResTmrLst));
+
+ for (; chkLnk; chkLnk = chkLnk->next)
+ {
+ raCb = (RgSchRaCb *)(chkLnk->node);
+
+ if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
+ {
+ /*If timer expired, call the handler function*/
+ rgSCHRamProcContResExp(cell, raCb);
+ }
+ /*Fix: Need to traverse till end of list as the entries may not be in ascending order*/
+ /* else
+ {
+ break;
+ }*/
+ }
+}
+/**
+ * @brief Check the Contention Resolution Guard Timer Expiry.
+ *
+ * @details
+ *
+ * Function: rgSCHChkContResGrdTmrExp
+ *
+ *
+ * Invoked by: Scheduler
+ * @param[in] RgSchCellCb *cell
+ * @return S16
+ * -# ROK
+ * -# RFAILED
+ **/
+#ifdef ANSI
+PRIVATE Void rgSCHChkContResGrdTmrExp
+(
+RgSchCellCb *cell
+)
+#else
+PRIVATE Void rgSCHChkContResGrdTmrExp(cell)
+RgSchCellCb *cell;
+#endif
+{
+ CmLList *chkLnk = NULLP;
+ RgSchRaCb *raCb = NULLP;
+
+ TRC2(rgSCHChkContResGrdTmrExp)
+
+ chkLnk = cmLListFirst(&(cell->contResGrdTmrLst));
+
+ /*[ccpu00131941]-MOD-List traversal should be done using the listCp */
+ for (; chkLnk; chkLnk = cmLListNext(&cell->contResGrdTmrLst))
+ {
+ raCb = (RgSchRaCb *)(chkLnk->node);
+
+ if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
+ {
+ /*If timer expired, call the handler function*/
+ rgSCHRamProcContResGrdExp(cell, raCb);
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+#endif
+#ifdef LTE_TDD
+/**
+ * @brief Function for handling RACH Request deletion
+ *
+ * @details
+ *
+ * Function : rgSCHRamDelRaReq
+ *
+ * This function shall be invoked to delete the RACH Requests
+ * that is not scheduled within the RA window size.
+ *
+ *
+ * @param[in,out] RgSchCellCb *cell
+ * @param[in] CmLteTimingInfo timingInfo
+ * @param[in] U8 raIdx
+ * @return S16
+ * -# ROK
+ **/
+#ifdef ANSI
+PUBLIC S16 rgSCHRamDelRaReq
+(
+RgSchCellCb *cell,
+CmLteTimingInfo timingInfo,
+U8 raIdx
+)
+#else
+PUBLIC S16 rgSCHRamDelRaReq(cell, timingInfo, raIdx)
+RgSchCellCb *cell;
+CmLteTimingInfo timingInfo;
+U8 raIdx;
+#endif
+{
+ U8 subfrmIdx;
+ RgSchTddRachRspLst *rachRsp;
+ U16 sfnIdx;
+ S16 calcSfn;
+ U8 subfrm;
+ RgSchRaReqInfo *raReqInfo;
+ U8 idx;
+ U8 i;
+ U8 raRntiIdx;
+ CmLteRnti raRnti;
+
+ TRC2(rgSCHRamDelRaReq)
+
+
+ rachRsp = &cell->rachRspLst[raIdx];
+ /* Get the SFN Index to be deleted */
+ calcSfn = timingInfo.sfn - rachRsp->delInfo.sfnOffset;
+ if(calcSfn < 0)
+ {
+ sfnIdx = (calcSfn + RGSCH_MAX_SFN) % cell->raInfo.maxRaSize;
+ }
+ else
+ {
+ sfnIdx = calcSfn;
+ }
+
+ /* Iterate through all the subframes to be delted in the SFN */
+ for(subfrmIdx=0; subfrmIdx < rachRsp->delInfo.numSubfrms; subfrmIdx++)
+ {
+ subfrm = rachRsp->delInfo.subframe[subfrmIdx];
+ /* Get the subframe Index to be deleted */
+ /* Fixes for RACH handling in TDD:
+ * Corrected the computation of raRntiIdx
+ * */
+ raRntiIdx = ((sfnIdx % cell->raInfo.maxRaSize) * \
+ RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
+ RGSCH_NUM_SUB_FRAMES) + subfrm;
+
+ /* Iterate through all the RNTIs in the subframe */
+ for(i=0; i < RGSCH_MAX_RA_RNTI_PER_SUBFRM; i++)
+ {
+ raRnti = raRntiIdx + (i*RGSCH_NUM_SUB_FRAMES);
+ for (idx = 0; idx < cell->raInfo.raReqLst[raRnti].count; idx++)
+ {
+ raReqInfo =
+ (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raRnti].first->node);
+ cmLListDelFrm(&(cell->raInfo.raReqLst[raRnti]),
+ &(raReqInfo->raReqLstEnt));
+ /* ccpu00117052 - MOD - Passing double pointer
+ for proper NULLP assignment*/
+ rgSCHUtlFreeSBuf(cell->instIdx,
+ (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
+ }
+ }
+ }
+
+ RETVALUE(ROK);
+}
+#endif
+
+/*MSG4 Fix Start */
+#ifdef ANSI
+PUBLIC S16 rgSCHRamAddToRaInfoSchdLst
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb
+)
+#else
+PUBLIC S16 rgSCHRamAddToRaInfoSchdLst(cell, raCb)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+#endif
+{
+ CmLteTimingInfo expTime ={0};
+ RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
+
+ TRC2(rgSCHRamAddToRaInfoSchdLst)
+
+ /*Fix: This can be called even when guard timer is not expired.
+ * In this case CR timer expiry should be guard timer expiry time + Guard timer time*/
+ RG_SCH_ADD_TO_CRNT_TIME(raCb->expiryTime, expTime, cellSch->dl.msg4TxDelay);
+ raCb->expiryTime = expTime;
+ raCb->schdLnk.node = (PTR)(raCb);
+ cmLListAdd2Tail(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
+ raCb->contResTmrLnk.node = (PTR)(raCb);
+ cmLListAdd2Tail(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
+ RETVALUE(ROK);
+} /* rgSCHRamAddToRaInfoSchdLst */
+
+
+
+#ifdef ANSI
+PUBLIC S16 rgSCHRamRmvFrmRaInfoSchdLst
+(
+RgSchCellCb *cell,
+RgSchRaCb *raCb
+)
+#else
+PUBLIC S16 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb)
+RgSchCellCb *cell;
+RgSchRaCb *raCb;
+#endif
+{
+ TRC2(rgSCHRamRmvFrmRaInfoSchdLst)
+
+ cmLListDelFrm(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
+ raCb->schdLnk.node = NULLP;
+ cmLListDelFrm(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
+ raCb->contResTmrLnk.node = NULLP;
+ RETVALUE(ROK);
+} /* rgSCHRamRmvFrmRaInfoSchdLst */
+
+/*MSG4 Fix End*/
+
+/***********************************************************
+ *
+ * Func : rgSCHRamUlFreeAllocation
+ *
+ * Desc : Free an allocation - invokes UHM and releases
+ * alloc
+ *
+ * Ret :
+ *
+ * Notes:
+ *
+ * File :
+ *
+ **********************************************************/
+#ifdef ANSI
+PRIVATE Void rgSCHRamUlFreeAllocation
+(
+RgSchUlSf *sf,
+RgSchUlAlloc *alloc,
+RgSchCellCb *cell,
+Bool isEmtc
+
+)
+#else
+PRIVATE Void rgSCHRamUlFreeAllocation(sf, alloc, cell,isEmtc)
+RgSchUlSf *sf;
+RgSchUlAlloc *alloc;
+RgSchCellCb *cell;
+Bool isEmtc;
+#endif
+{
+ TRC2(rgSCHRamUlFreeAllocation);
+
+ rgSCHUhmFreeProc(alloc->hqProc, cell);
+ if(!isEmtc)
+ {
+ rgSCHUtlUlAllocRls(sf, alloc);
+ }
+ RETVOID;
+}
+
+/**********************************************************************
+
+ End of file
+**********************************************************************/