X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrsch%2Frg_sch_ram.c;fp=src%2F5gnrsch%2Frg_sch_ram.c;h=ad27fe08c0fe8d452dcb7757d269f8f95b3d4db3;hb=3235ecfc7414aa0b72d0ad50db63ae8b5626045b;hp=0000000000000000000000000000000000000000;hpb=997e3f26d55352586a1d4d0c46c41a98452af88a;p=o-du%2Fl2.git diff --git a/src/5gnrsch/rg_sch_ram.c b/src/5gnrsch/rg_sch_ram.c new file mode 100755 index 000000000..ad27fe08c --- /dev/null +++ b/src/5gnrsch/rg_sch_ram.c @@ -0,0 +1,1659 @@ +/******************************************************************************* +################################################################################ +# 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 +**********************************************************************/