1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Entry point fucntions
29 **********************************************************************/
31 /** @file rg_sch_ram.c
32 @brief This file has APIs to handle the random access procedure functionality for the scheduler.
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_MODULE_ID=4096;
37 static int RLOG_FILE_ID=171;
39 /* header include files (.h) */
40 #include "common_def.h"
42 #include "rg_env.h" /* MAC Environment Defines */
43 #include "rgr.h" /* RGR Interface defines */
44 #include "rgm.h" /* RGR Interface defines */
45 #include "tfu.h" /* TFU Interface defines */
46 #include "lrg.h" /* LRG Interface defines */
47 #include "rg_env.h" /* Scheduler error defines */
48 #include "rg_sch_inf.h" /* Scheduler defines */
49 #include "rg_sch_err.h" /* Scheduler error defines */
50 #include "rg_sch.h" /* Scheduler defines */
51 #include "rg_sch_cmn.h"
52 #include "rl_interface.h"
53 #include "rl_common.h"
55 /* header/extern include files (.x) */
57 #include "rgr.x" /* RGR Interface includes */
58 #include "rgm.x" /* RGR Interface includes */
59 #include "tfu.x" /* TFU Interface includes */
60 #include "lrg.x" /* LRG Interface includes */
62 #include "rg_sch_inf.x" /* typedefs for Scheduler */
63 #include "rg_sch.x" /* Scheduler includes */
64 #include "rg_sch_cmn.x"
66 EXTERN Bool rgSCHRamVldtRgrEmtcUeCfg ARGS((
71 EXTERN S16 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst
75 EXTERN Void rgSCHEmtcUtlUpdCmnNb
79 EXTERN Void rgSCHEmtcHqPAlloc
87 PRIVATE Void rgSCHRamUlFreeAllocation ARGS((RgSchUlSf *sf,RgSchUlAlloc *alloc,
88 RgSchCellCb *cell,Bool isEmtc));
90 PRIVATE S16 rgSCHRamContResCrnti ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
91 RgSchRaCb *raCb, RgSchErrInfo *err));
92 PRIVATE S16 rgSCHRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
95 EXTERN S16 rgSCHEmtcRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
96 EXTERN S16 rgSCHRamEmtcContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
97 EXTERN Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell));
98 EXTERN Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell));
99 EXTERN Void rgSCHEmtcRaInfoFree ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
102 PRIVATE Void rgSCHChkContResGrdTmrExp ARGS((RgSchCellCb *cell));
103 PRIVATE Void rgSCHChkContResTmrExp ARGS((RgSchCellCb *cell));
104 PRIVATE Void rgSCHRamProcContResExp ARGS((RgSchCellCb *cell,
106 PRIVATE Void rgSCHRamProcContResGrdExp ARGS((RgSchCellCb *cell,
109 EXTERN Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell));
110 EXTERN Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell));
113 /* forward references */
116 * @brief Check configured preamble id not colliding with non dedicated or PDCCH
117 * order preamble sets. When valid preamble id given check that C-RNTI given
118 * in configuration is not amongst the C-RNTI'smanaged by scheduler
122 * Function : rgSCHRamVldtUeCfg
124 * Processing Steps: Check configured preamble id not colliding with non dedicated or PDCCH
125 * order preamble sets. When valid preamble id given check that C-RNTI given
126 * in configuration is not amongst the C-RNTI'smanaged by scheduler
128 * @param[in] RgSchCellCb *cell
129 * @param[in] RgrUeCfg *ueCfg
135 S16 rgSCHRamVldtUeCfg
141 S16 rgSCHRamVldtUeCfg(cell, ueCfg)
146 if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
148 if ((ueCfg->dedPreambleId.val < cell->rachCfg.numRaPreamble) ||
149 (ueCfg->dedPreambleId.val >= RGSCH_MAX_NUM_RA_PREAMBLE) ||
150 ((ueCfg->dedPreambleId.val >= cell->macPreambleSet.start) &&
151 (ueCfg->dedPreambleId.val <= cell->macPreambleSet.start +
152 cell->macPreambleSet.size - 1)) ||
153 ((ueCfg->crnti >= cell->rntiDb.rntiStart) &&
154 (ueCfg->crnti < cell->rntiDb.rntiStart + cell->rntiDb.maxRntis-1))
156 || (rgSCHRamVldtRgrEmtcUeCfg(cell,ueCfg))
167 * @brief Handler for Random Access Request
171 * Function : rgSCHRamProcRaReq
173 * -# Create a node for each TfuRaReqInfo element received
174 * -# Initialize the list with the above elements at the raRnti index
178 * @param[in] RgSchCellCb *cell
179 * @param[in] CmLteRnti raRnti
180 * @param[in] RgTfuRaReqInd *raReqInd
181 * @param[out] RgSchErrInfo *err
187 S16 rgSCHRamProcRaReq
192 TfuRachInfo *raReqInd,
193 CmLteTimingInfo timingInfo,
198 S16 rgSCHRamProcRaReq(raReqCnt, cell, raRnti, raReqInd, timingInfo, ue, err)
202 TfuRachInfo *raReqInd;
203 CmLteTimingInfo timingInfo;
208 RgSchRaReqInfo *raReqInfo;
217 /* SR_RACH_STATS : RACH REQ */
218 rgNumPrachRecvd += raReqInd->numRaReqInfo;
220 /* ccpu00132523- Moved out this from for loop as updating of raIndex is
221 * relates to only raRnti and all preambles having same raRnti*/
223 /* UL subframes do not occupy all the subframes in a radio frame.
224 * So RA Rnti index to be calculated based on actual UL subframe index. */
225 /* Get the actual subframe number */
226 tid = (raRnti-1)%RGSCH_NUM_SUB_FRAMES;
227 /* Get the frequency index in the subframe */
228 fid = ((raRnti-1) / RGSCH_NUM_SUB_FRAMES)* RGSCH_NUM_SUB_FRAMES;
229 /* Get the index of RA RNTI in the array */
230 raIndex = ((timingInfo.sfn % cell->raInfo.maxRaSize) \
231 * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES) + \
233 /* Fixes for RACH handling in TDD: Removed deletion of queued RaReq */
235 /* ccpu00132523- Placing the raReq into array based on RA SFN */
236 raIndex = (timingInfo.sfn & 1) * RGSCH_MAX_RA_RNTI + raRnti-1;
239 /* allocate new raReqInfos and enqueue them */
240 if (raReqInd->raReqInfoArr[raReqCnt].rapId >= RGSCH_MAX_NUM_RA_PREAMBLE)
242 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
243 "RARNTI:%d rgSCHTomRaReqInd(): RAM processing failed errType(%d) ",
248 /* SR_RACH_STATS : DED PREAMB*/
249 if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
256 if (raReqInd->raReqInfoArr[raReqCnt].rapId < cell->rachCfg.sizeRaPreambleGrpA)
258 cell->raPrmbs.preamGrpA++;
260 else if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
262 cell->raPrmbs.dedPream++;
266 cell->raPrmbs.preamGrpB++;
270 if((rgSCHUtlAllocSBuf(cell->instIdx, (Data **)(&raReqInfo),
271 sizeof(RgSchRaReqInfo))) == RFAILED)
273 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamProcRaReq(): Allocation"
274 " of RaReq failed RARNTI:%d",raRnti);
275 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
279 /* Insert the given raReqInfo */
281 raReqInfo->timingInfo = timingInfo;
282 raReqInfo->raReq = raReqInd->raReqInfoArr[raReqCnt];
283 raReqInfo->raReqLstEnt.next = NULLP;
284 raReqInfo->raReqLstEnt.prev = NULLP;
285 raReqInfo->raReqLstEnt.node = (PTR)raReqInfo;
290 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->raInfo.raReqLst, raIndex);
292 /* RACHO: If dedicated preamble, then give preference by appending at front */
293 if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
295 cmLListFirst(&cell->raInfo.raReqLst[raIndex]);
296 cmLListInsCrnt(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
300 cmLListAdd2Tail(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
304 } /* rgSCHRamProcRaReq */
307 * @brief Handler for Random Access control block creation
311 * Function : rgSCHRamCreateRaCb
312 * Creates a raCb and gives the same to scheduler for its updation
315 * @param[in] RgSchCellCb *cell
316 * @param[in, out] RgSchRaCb **raCb
317 * @param[out] RgSchErrInfo *err
323 S16 rgSCHRamCreateRaCb
330 S16 rgSCHRamCreateRaCb(cell, raCb, err)
336 RgSchRntiLnk *rntiLnk;
337 Inst inst = cell->instIdx;
340 if((rgSCHUtlAllocSBuf(inst, (Data **)(raCb),
341 sizeof(RgSchRaCb))) == RFAILED)
343 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
345 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
349 rntiLnk = rgSCHDbmGetRnti(cell);
352 (*raCb)->rntiLnk = rntiLnk;
353 (*raCb)->tmpCrnti = rntiLnk->rnti;
358 /* SR_RACH_STATS: RNTI POOL Exhaution */
359 rgNumRarFailDuetoRntiExhaustion++;
361 /* No rnti available! */
362 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
363 "temporary RNTI failed at MAC(CRNTI exhausted)");
364 /* ccpu00117052 - MOD - Passing double pointer
365 for proper NULLP assignment*/
366 rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
367 err->errCause = RGSCHERR_RAM_RNTI_EXHAUST;
371 /* Allocate and initialize the DL HARQ portion of the RACB */
372 (*raCb)->dlHqE = rgSCHDhmHqEntInit(cell);
373 if ((*raCb)->dlHqE == NULLP)
375 /* No memory available! */
376 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Creation of"
378 /* ccpu00117052 - MOD - Passing double pointer
379 for proper NULLP assignment*/
380 rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
381 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
385 (*raCb)->isEmtcRaCb = FALSE;
386 rgSCHEmtcHqPAlloc(cell, (*raCb)->dlHqE);
388 (*raCb)->dlHqE->raCb = (*raCb);
389 /* Initialize RaCb's contents */
390 (*raCb)->timingInfo = cell->crntTime;
391 (*raCb)->raState = RGSCH_RA_MSG3_PENDING;
392 (*raCb)->toDel = FALSE;
393 (*raCb)->phr.pres = FALSE;
395 /* Insert the created raCb into raCb list of cell */
396 (*raCb)->raCbLnk.node = (PTR)(*raCb);
397 cmLListAdd2Tail(&cell->raInfo.raCbLst, &(*raCb)->raCbLnk);
400 } /* rgSCHRamCreateRaCb */
403 * @brief Handler for Ue Configuration Request
407 * Function : rgSCHRamRgrUeCfg
409 * This function handles the UE config received based on the state of the
411 * -# If raCb is in RGSCH_RA_MSG4_PENDING state, it shall update the harq
412 * information to UeCb and update the references.
413 * -# If raCb is in RGSCH_RA_MSG4_DONE, then it shall free the raCb
416 * @param[in] RgSchCellCb *cell
417 * @param[in,out] RgSchUeCb *ue
418 * @param[in,out] RgSchRaCb *raCb
419 * @param[out] RgSchErrInfo *err
433 S16 rgSCHRamRgrUeCfg(cell, ue, raCb, err)
440 /* Releasing HARQ processes of old UE when ue
441 * reconfig with new crnti */
443 RgSchDlHqEnt **hqEnt = &(RG_SCH_CMN_GET_UE_HQE(ue, cell));
444 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
447 /* Fix : set UE inactive in DL until UE is reinitialization completed */
448 ue->dl.dlInactvMask |= RG_HQENT_INACTIVE;
449 ue->ul.ulInactvMask |= RG_HQENT_INACTIVE;
451 if(raCb->raState == RGSCH_RA_MSG4_PENDING)
454 ue->rntiLnk = raCb->rntiLnk;
455 /* Update UL Harq process information */
456 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
457 ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
459 else if(raCb->raState == RGSCH_RA_MSG4_DONE)
461 ue->rntiLnk = raCb->rntiLnk;
462 /* Update UL Harq process information */
463 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
464 ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
465 /* Fix : syed Assign hqEnt to UE only if msg4 is done */
466 rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb);
470 err->errCause = RGSCHERR_RAM_NO_MSG3_RCVD;
472 raCb->dlHqE->ue = NULLP;
477 } /* rgSCHRamRgrUeCfg */
481 * @brief Handler for C-RNTI based contention resolution
485 * Function : rgSCHRamContResCrnti
487 * This function shall be invoked once Msg3 indicates C-RNTI based
488 * contention resolution.This shall indicate the scheduler regarding
489 * C-RNTI based uplink grant.
492 * @param[in,out] RgSchCellCb *cell
493 * @param[in,out] RgSchUeCb *ue
494 * @param[in,out] RgSchRaCb *raCb
499 PRIVATE S16 rgSCHRamContResCrnti
507 PRIVATE S16 rgSCHRamContResCrnti(cell, ue, raCb, err)
514 TfuUlCqiRpt ulCqiRpt;
515 RgSchCmnCell *cellSch= (RgSchCmnCell *)(cell->sc.sch);
518 /* Fix: syed It is incorrect to copy over msg3HqProc to ueCb's
519 * UL harq proc. In case of Crnti based RACH, ueCb has valid context which
520 * cannot be over written. It was leading to a crash. */
522 rgSCHUtlRecMsg3Alloc(cell, ue, raCb);
524 /* Fix for ccpu00123908: Reset the UL CQI to the cell default value here */
525 ulCqiRpt.isTxPort0 = TRUE;
526 ulCqiRpt.numSubband = 0;
527 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
528 ulCqiRpt.rnti = ue->ueId;
529 /* rg002.301:[ccpu00124018]-MOD- Avoiding hard coding of CQI and retriving from cell config*/
530 ulCqiRpt.wideCqi = cellSch->ul.dfltUlCqi;
531 rgSCHUtlUlCqiInd(cell, ue, &ulCqiRpt);
534 /* Invoke scheduler to indicate UL grant req for contention resolution */
535 rgSCHUtlContResUlGrant(cell, ue, err);
537 if (raCb->phr.pres == TRUE)
539 rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, err);
541 /* No need of raCb any more */
542 rgSCHRamDelRaCb(cell, raCb, TRUE);
545 } /* rgSCHRamContResCrnti */
549 * @brief Handler for CCCH SDU based contention resolution
553 * Function : rgSCHRamContResCcchsdu
555 * This function shall be invoked once Msg3 indicates contention resolution
556 * based on CCCH sdu. This shall update the raCb state to
557 * RGSCH_RA_MSG4_PENDING.
560 * @param[in,out] RgSchRaCb *raCb
565 PRIVATE S16 rgSCHRamContResCcchsdu
571 PRIVATE S16 rgSCHRamContResCcchsdu(cell, raCb)
577 CmLteTimingInfo expTime = {0};
578 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
580 if(raCb->raState != RGSCH_RA_MSG3_PENDING)
582 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
583 "RNTI:%d RaCb in wrong State %d Drop Msg 3",
589 raCb->raState = RGSCH_RA_MSG4_PENDING;
592 if(cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay > 0)
594 /* Set the contension resolution guard timer =
595 Cont Res Timer - Max msg4 Tx Delay */
596 RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime,
597 (cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay));
601 /* Schedule the CRI CE in the next Sf itself */
602 RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime, 1);
604 raCb->expiryTime = expTime;
605 raCb->contResTmrLnk.node = (PTR)(raCb);
606 cmLListAdd2Tail(&(cell->contResGrdTmrLst), &(raCb->contResTmrLnk));
609 } /* rgSCHRamContResCcchsdu */
613 * @brief Handler for Msg3
617 * Function : rgSCHRamProcMsg3
619 * This function processes the received Msg3 and identifies the type of
620 * contention resolution and act accordingly.
623 * @param[in,out] RgSchCellCb *cell
624 * @param[in,out] RgSchUeCb *ue
625 * @param[in,out] RgSchRaCb *raCb
639 S16 rgSCHRamProcMsg3(cell, ue, raCb, pdu, err)
649 /* Update raCb with PHR if received along with Msg3 */
650 if (pdu->ceInfo.bitMask & RGSCH_PHR_CE_PRSNT)
653 raCb->phr.pres = TRUE;
654 raCb->phr.val = pdu->ceInfo.ces.phr;
658 rgSCHRamContResCrnti(cell, ue, raCb, err);
663 if(TRUE == raCb->isEmtcRaCb)
665 /* starting the emtc Contention resolution timer */
666 rgSCHRamEmtcContResCcchsdu(cell,raCb);
671 rgSCHRamContResCcchsdu(cell, raCb);
676 } /* rgSCHRamProcMsg3 */
680 * @brief Handler for Updating Bo received in StaRsp
684 * Function : rgSCHRamUpdtBo
686 * This function shall be invoked by RAM once it receives staRsp on CCCH
688 * @param[in] RgSchCellCb *cell
689 * @param[in,out] RgSchRaCb *raCb
690 * @param[in] RgRguCmnStaRsp *staRsp
699 RgInfCmnBoRpt *staRsp
702 S16 rgSCHRamUpdtBo(cell, raCb, staRsp)
705 RgInfCmnBoRpt *staRsp;
709 /* Update Bo in RaCb */
710 raCb->dlCcchInfo.bo = (uint32_t)(staRsp->bo);
711 /* SR_RACH_STATS : MSG4 WITH CCCH SDU */
712 rgNumMsg4WithCCCHSdu++;
714 /* add this to the "tobeSchdLst" */
716 rgSCHRamAddToRaInfoSchdLst(cell, raCb);
720 } /* rgSCHRamUpdtBo */
723 * @brief Handler for Msg3 Feedback indication
727 * Function : rgSCHRamMsg3DatInd
729 * This function shall be invoked by TOM once the transmission of Msg4 is
731 * This shall invoke UHM to set ACK for Msg3 reception.
733 * @param[in,out] RgSchRaCb *raCb
738 S16 rgSCHRamMsg3DatInd
743 S16 rgSCHRamMsg3DatInd(raCb)
748 /* SR_RACH_STATS : MSG3 ACK*/
749 rgNumMsg3CrcPassed++;
750 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
751 rgSCHUhmProcMsg3DatInd(&(raCb->msg3HqProc));
754 } /* rgSCHRamMsg3DatInd */
757 * @brief Handler for Msg3 Feedback indication
761 * Function : rgSCHRamMsg3FailureInd
763 * This function shall be invoked by TOM once the transmission of Msg4 is
765 * This shall invoke UHM to set ACK for Msg3 reception.
767 * @param[in,out] RgSchRaCb *raCb
772 S16 rgSCHRamMsg3FailureInd
777 S16 rgSCHRamMsg3FailureInd(raCb)
782 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
783 rgSCHUhmProcMsg3Failure(&(raCb->msg3HqProc));
786 } /* rgSCHRamMsg3FailureInd */
789 * @brief Handler for Msg4 Feedback indication
793 * Function : rgSCHRamMsg4FdbkInd
795 * This function shall be invoked by TOM once the transmission of Msg4 is
797 * This shall invoke UHM to set ACK for Msg3 reception.
799 * @param[in,out] RgSchRaCb *raCb
804 S16 rgSCHRamMsg4FdbkInd
809 S16 rgSCHRamMsg4FdbkInd(raCb)
815 } /* rgSCHRamMsg4FdbkInd */
819 * @brief Handler for Msg4 state updation
823 * Function : rgSCHRamMsg4Done
825 * This function shall be invoked by DHM once the transmission of Msg4 is
826 * done. This shall delete the raCb if there is a valid Ue or if this is to
827 * be deleted. If not this shall update the state of the raCb.
830 * @param[in] RgSchCellCb *cell
831 * @param[in,out] RgSchRaCb *raCb
842 S16 rgSCHRamMsg4Done(cell, raCb)
848 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
849 "rgSCHRamMsg4Done(): tmpCRNTI = %u",
852 if(raCb->ue != NULLP)
854 /* Fix : syed Let this funtion decide on releasing
855 * hqP than the caller of this function otherwise sometimes it
856 * might lead to incorrec NDI setting. */
857 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
858 /* Fix : syed Assign hqEnt to UE only if msg4 is done */
859 rgSCHDhmAssgnUeHqEntFrmRaCb(raCb->ue, raCb);
861 if(TRUE == raCb->isEmtcRaCb)
863 rgSCHEmtcUtlUpdCmnNb(raCb);
866 /* MS_FIX :Proceed to CCCH scheduling irrespective of
868 if (raCb->ue->dlCcchInfo.bo)
871 /*if CR-ID Ack has been received ,Add emtc Ue to cchSduUeLst*/
872 if(TRUE == raCb->isEmtcRaCb)
874 rgSCHUtlAddUeToEmtcCcchSduLst(cell, raCb->ue);
879 rgSCHUtlAddUeToCcchSduLst(cell, raCb->ue);
882 /* Rnti shall not be released as Ue exists with this rnti */
883 rgSCHRamDelRaCb(cell, raCb, FALSE);
885 else if(raCb->toDel == TRUE)
887 #ifdef XEON_SPECIFIC_CHANGES
888 CM_LOG_DEBUG(CM_LOG_ID_SCH, "Deleting RacB:%d\n", raCb->tmpCrnti);
890 /* Delete RACB and release RNTI */
891 rgSCHRamDelRaCb(cell, raCb, TRUE);
895 #ifdef XEON_SPECIFIC_CHANGES
896 CM_LOG_DEBUG(CM_LOG_ID_SCH, "Releasing Harq of RacB:%d\n", raCb->tmpCrnti);
898 raCb->raState = RGSCH_RA_MSG4_DONE;
899 /* Release harq process as final feedback is received for Msg4. In other
900 * cases, delRaCb will take care of releasing the harq process */
901 printf("=======Harq process released \n");
902 RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
903 "Harq process released ");
904 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
908 } /* rgSCHRamMsg4Done */
912 * @brief Handler for deletion
916 * Function : rgSCHRamDelRaCb
918 * This function shall be invoked whenever a raCb needs to be deleted.
919 * Invoked by both RAM and downlink scheduler
921 * @param[in] RgSchCellCb *cell
922 * @param[in,out] RgSchRaCb *raCb
923 * @param[in] Bool rlsRnti
936 S16 rgSCHRamDelRaCb(cell, raCb, rlsRnti)
942 Inst inst = cell->instIdx;
945 /* Delete from all the lists it is enqueued */
946 cmLListDelFrm(&(cell->raInfo.raCbLst),&(raCb->raCbLnk));
948 /*ue Type is EMTC, then Delete the toBeSchedLst and stop the Guard Timer */
949 if(TRUE == raCb->isEmtcRaCb)
951 rgSCHRamEmtcDelRaCb(cell,raCb);
957 if (raCb->schdLnk.node == (PTR)raCb)
959 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
962 else if(raCb->contResTmrLnk.node != NULLP)
964 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
965 raCb->contResTmrLnk.node = NULLP;
972 rgSCHUtlRlsRnti(cell, raCb->rntiLnk, FALSE, 0);
975 /* Check if msg4 Hq Proc has been released. If not, release it */
978 if (raCb->dlHqE->msg4Proc != NULLP)
980 /* Fix: syed Remove the msg4Proc if it waiting in sf->tbs list for
982 if ((raCb->dlHqE->msg4Proc->subFrm != NULLP) &&
983 (raCb->dlHqE->msg4Proc->hqPSfLnk.node != NULLP))
985 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"TMP CRNTI:%d RACH FAILURE!! "
986 "msg4proc removed from SF", raCb->tmpCrnti);
987 rgSCHUtlDlHqPTbRmvFrmTx(raCb->dlHqE->msg4Proc->subFrm,
988 raCb->dlHqE->msg4Proc, 0, FALSE);
990 /* Fix: syed Remove the msg4Proc from cell
991 * msg4Retx Queue. I have used CMN scheduler function
992 * directly. Please define a new API and call this
993 * function through that. */
994 rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, raCb->dlHqE->msg4Proc);
995 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
998 /* Mark the raCb pointer in dlHqE to NULLP */
999 raCb->dlHqE->raCb = NULLP;
1001 rgSCHDhmDelHqEnt(cell, &raCb->dlHqE);
1003 /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
1004 * from adaptive retx List. Free the alloc if it exists. */
1005 if (raCb->msg3HqProc.reTxLnk.node)
1007 //TODO_SID: Need to take care of retxLst
1008 //cmLListDelFrm(raCb->msg3HqProc.reTxAlloc.reTxLst, &raCb->msg3HqProc.reTxLnk);
1009 raCb->msg3HqProc.reTxLnk.node = (PTR)NULLP;
1012 if (raCb->msg3HqProc.alloc)
1014 /* Fix: syed During GPR, please write an API instead of direct
1015 * call to cmn scheduler function */
1016 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
1017 /*ccpu00130356 - MOD- To avoid segmentation problem because of double
1018 free due to recursive calling of rgSCHRamDelRaCb*/
1019 rgSCHRamUlFreeAllocation(&cellUl->ulSfArr[raCb->msg3HqProc.ulSfIdx],
1020 raCb->msg3HqProc.alloc,
1025 if(TRUE == raCb->isEmtcRaCb)
1027 rgSCHEmtcRaInfoFree(cell, raCb);
1030 rgSCHUtlFreeSBuf(inst, (Data **)&raCb, sizeof(RgSchRaCb));
1033 } /* rgSCHRamDelRaCb */
1037 * @brief TTI Handler for RAM module
1041 * Function : rgSCHRamTtiHndlr
1043 * This function shall be invoked upon TtiInd by TOM
1045 * - remove RaReqs added to the queue for a raRnti for which PHY may
1046 * give the requests in the next subframe
1047 * - remove raCbs which are not yet processed once the
1048 * counter for raCb processing expires.
1051 * @param[in,out] RgSchCellCb *cell
1056 S16 rgSCHRamTtiHndlr
1061 S16 rgSCHRamTtiHndlr(cell)
1068 uint16_t dist; /* Number of frames between raCb's creation and crnt
1075 RgSchRaReqInfo *raReqInfo;
1077 CmLteTimingInfo frm;
1082 crntSfn = cell->crntTime.sfn;
1085 /*Check if Contention resolution guard timer expiring in the TTI*/
1086 rgSCHChkContResGrdTmrExp(cell);
1087 /*Check if Contention resolution timer expiring in the TTI*/
1088 rgSCHChkContResTmrExp(cell);
1090 /*Check if EMTC Contention resolution guard timer expiring in the TTI*/
1091 rgSCHChkEmtcContResGrdTmrExp(cell);
1092 /*Check if EMTC Contention resolution timer expiring in the TTI*/
1093 rgSCHChkEmtcContResTmrExp(cell);
1098 /* Delete the RA requests for which RAR window expired in this subframe
1099 * And were not considered for RAR scheduling*/
1100 winGap = (rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat]-1)+
1101 (cell->rachCfg.raWinSize -1 ) + RGSCH_RARSP_WAIT_PERIOD;
1103 raIdx = (((crntSfn & 1) * RGSCH_MAX_RA_RNTI+ cell->crntTime.slot
1104 + RG_SCH_CMN_DL_DELTA - winGap)+ RGSCH_RAREQ_ARRAY_SIZE )
1105 % RGSCH_RAREQ_ARRAY_SIZE;
1107 /* Flush the already existing raReqs against the given raRnti */
1109 maxCnt = cell->raInfo.raReqLst[raIdx].count;
1110 for (idx = 0; idx < maxCnt; idx++)
1112 raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raIdx].first->node);
1113 cmLListDelFrm(&(cell->raInfo.raReqLst[raIdx]),&(raReqInfo->raReqLstEnt));
1114 /* ccpu00117052 - MOD - Passing double pointer
1115 for proper NULLP assignment*/
1116 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReqInfo,
1117 sizeof(RgSchRaReqInfo));
1120 /* Fixes for RACH handling: Added deletion of queued RaReq */
1121 frm = cell->crntTime;
1122 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
1123 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot] !=
1124 RG_SCH_TDD_UL_SUBFRAME)
1126 raIdx = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot]-1;
1127 rgSCHRamDelRaReq(cell, cell->crntTime, raIdx);
1131 /* Remove the RACBs which are timed out */
1132 /* ccpu00132536:MOD- racb timeout will be verified in each SFN such that
1133 * the RACB whose processing is not completed in RG_MAX_RA_PRC_FRM
1135 if (cell->crntTime.slot == 0)
1137 maxCnt = cell->raInfo.raCbLst.count;
1138 for (idx = 0; idx < maxCnt; idx++)
1140 raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
1141 /* Calculate number of frames between raCb's creation and crnt frame */
1142 raSfn = raCb->timingInfo.sfn;
1143 dist = (crntSfn + (RGSCH_MAX_SFN - raSfn)) % RGSCH_MAX_SFN;
1144 /* Delete RaCbs whose processing is not complete within
1145 * "cell->t300TmrVal" frames */
1146 /* raCb not to be deleted if msg4 is not completed */
1147 /* raCb should not be deleted(RNTI should not be released) if UE is present
1148 * as it means the application still holds the RNTI. raCb will get deleted
1149 * as part of UE deletion. raCb will anyway get deleted without releasing RNTI on success/failure of MSG4*/
1151 if (dist >= cell->t300TmrVal)
1153 if ((raCb->dlHqE->msg4Proc == NULLP) && (raCb->dlHqE->ue == NULLP))
1155 rgSCHRamDelRaCb(cell, raCb, TRUE);
1166 } /* rgSCHRamTtiHndlr */
1170 * @brief Function for handling cell delete
1174 * Function : rgSCHRamFreeCell
1176 * This function shall be invoked whenever a cell needs to be deleted.
1177 * This shall remove raCbs and raReqs stored in cell.
1180 * @param[in,out] RgSchCellCb *cell
1185 S16 rgSCHRamFreeCell
1190 S16 rgSCHRamFreeCell(cell)
1194 RgSchRaReqInfo *raReqInfo;
1198 Inst inst = cell->instIdx;
1201 uint8_t maxUlSubframes;
1202 uint8_t maxDlSubframes;
1210 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1212 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1213 lstSz = cell->raInfo.maxRaSize * RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
1216 /* ccpu00133557- MEM LEAK FIX- Need to free all the nodes in RA Array list */
1217 lstSz = RGSCH_RAREQ_ARRAY_SIZE;
1220 for (idx = 0; idx < lstSz; idx++)
1222 /* Delete and free raReqs stored */
1223 /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
1224 while(cell->raInfo.raReqLst[idx].count)
1226 raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[idx].first->node);
1227 cmLListDelFrm(&(cell->raInfo.raReqLst[idx]),&(raReqInfo->raReqLstEnt));
1228 /* ccpu00117052 - MOD - Passing double pointer
1229 for proper NULLP assignment*/
1230 rgSCHUtlFreeSBuf(inst, (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
1235 /* Delete the RACH response list*/
1236 /* ccpu00117052 - MOD - Passing double pointer
1237 for proper NULLP assignment*/
1238 rgSCHUtlFreeSBuf(inst,
1239 (Data **)(&(cell->rachRspLst)), sizeof(RgSchTddRachRspLst) * \
1243 /* Delete raCbs in the "to be scheduled" list */
1244 /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
1245 while(cell->raInfo.toBeSchdLst.count)
1247 raCb = (RgSchRaCb *)(cell->raInfo.toBeSchdLst.first->node);
1248 /* MSG4 Fix Start */
1250 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
1254 /* Delete raCbs in the "Emtc to be scheduled" list */
1255 if(cell->emtcEnable)
1257 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst(cell);
1261 raCbCnt = cell->raInfo.raCbLst.count;
1263 /* Delete and free raCbs stored */
1264 for (idx = 0; idx < raCbCnt; idx++)
1266 raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
1267 rgSCHRamDelRaCb(cell, raCb, TRUE);
1271 } /* rgSCHRamFreeCell */
1274 PRIVATE Void rgSCHRamProcContResExp
1280 PRIVATE Void rgSCHRamProcContResExp (cell, raCb)
1285 raCb->expiryTime.sfn = RGSCH_CONTRES_EXP;
1289 /* UE exists and RNTI will be released as part of UE DEL */
1290 rgSCHRamDelRaCb(cell, raCb, FALSE);
1294 /* Calling Release RNTI, which would perform Racb deletion
1295 * RNTI removal and RNTI release indication to MAC. */
1296 /* Delete RACB and release RNTI */
1297 rgSCHRamDelRaCb(cell, raCb, TRUE);
1303 PRIVATE Void rgSCHRamProcContResGrdExp
1309 PRIVATE Void rgSCHRamProcContResGrdExp (cell, raCb)
1316 /*Guard timer has expired, schedule only the contention REsolution CE with
1318 raCb->dlCcchInfo.bo = 0;
1319 /* SR_RACH_STATS : MSG4 WO CCCH SDU */
1320 rgNumMsg4WoCCCHSdu++;
1322 /* add this to the "tobeSchdLst" */
1323 raCb->schdLnk.node = (PTR)(raCb);
1325 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
1326 raCb->contResTmrLnk.node = NULLP;
1328 /* MSG4 Fix Start */
1329 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
1330 "Con Res Grd Tmr exp RNTI:%d",
1331 raCb->rntiLnk->rnti);
1332 rgSCHRamAddToRaInfoSchdLst(cell, raCb);
1338 * @brief Check the Contention Resolution Guard Timer Expiry.
1342 * Function: rgSCHChkContResTmrExp
1345 * Invoked by: Scheduler
1346 * @param[in] RgSchCellCb *cell
1352 PRIVATE Void rgSCHChkContResTmrExp
1357 PRIVATE Void rgSCHChkContResTmrExp(cell)
1361 CmLList *chkLnk = NULLP;
1362 RgSchRaCb *raCb = NULLP;
1365 chkLnk = cmLListFirst(&(cell->contResTmrLst));
1367 for (; chkLnk; chkLnk = chkLnk->next)
1369 raCb = (RgSchRaCb *)(chkLnk->node);
1371 if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
1373 /*If timer expired, call the handler function*/
1374 rgSCHRamProcContResExp(cell, raCb);
1376 /*Fix: Need to traverse till end of list as the entries may not be in ascending order*/
1384 * @brief Check the Contention Resolution Guard Timer Expiry.
1388 * Function: rgSCHChkContResGrdTmrExp
1391 * Invoked by: Scheduler
1392 * @param[in] RgSchCellCb *cell
1398 PRIVATE Void rgSCHChkContResGrdTmrExp
1403 PRIVATE Void rgSCHChkContResGrdTmrExp(cell)
1407 CmLList *chkLnk = NULLP;
1408 RgSchRaCb *raCb = NULLP;
1411 chkLnk = cmLListFirst(&(cell->contResGrdTmrLst));
1413 /*[ccpu00131941]-MOD-List traversal should be done using the listCp */
1414 for (; chkLnk; chkLnk = cmLListNext(&cell->contResGrdTmrLst))
1416 raCb = (RgSchRaCb *)(chkLnk->node);
1418 if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
1420 /*If timer expired, call the handler function*/
1421 rgSCHRamProcContResGrdExp(cell, raCb);
1432 * @brief Function for handling RACH Request deletion
1436 * Function : rgSCHRamDelRaReq
1438 * This function shall be invoked to delete the RACH Requests
1439 * that is not scheduled within the RA window size.
1442 * @param[in,out] RgSchCellCb *cell
1443 * @param[in] CmLteTimingInfo timingInfo
1444 * @param[in] uint8_t raIdx
1449 S16 rgSCHRamDelRaReq
1452 CmLteTimingInfo timingInfo,
1456 S16 rgSCHRamDelRaReq(cell, timingInfo, raIdx)
1458 CmLteTimingInfo timingInfo;
1463 RgSchTddRachRspLst *rachRsp;
1467 RgSchRaReqInfo *raReqInfo;
1475 rachRsp = &cell->rachRspLst[raIdx];
1476 /* Get the SFN Index to be deleted */
1477 calcSfn = timingInfo.sfn - rachRsp->delInfo.sfnOffset;
1480 sfnIdx = (calcSfn + RGSCH_MAX_SFN) % cell->raInfo.maxRaSize;
1487 /* Iterate through all the subframes to be delted in the SFN */
1488 for(subfrmIdx=0; subfrmIdx < rachRsp->delInfo.numSubfrms; subfrmIdx++)
1490 subfrm = rachRsp->delInfo.subframe[subfrmIdx];
1491 /* Get the subframe Index to be deleted */
1492 /* Fixes for RACH handling in TDD:
1493 * Corrected the computation of raRntiIdx
1495 raRntiIdx = ((sfnIdx % cell->raInfo.maxRaSize) * \
1496 RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
1497 RGSCH_NUM_SUB_FRAMES) + subfrm;
1499 /* Iterate through all the RNTIs in the subframe */
1500 for(i=0; i < RGSCH_MAX_RA_RNTI_PER_SUBFRM; i++)
1502 raRnti = raRntiIdx + (i*RGSCH_NUM_SUB_FRAMES);
1503 for (idx = 0; idx < cell->raInfo.raReqLst[raRnti].count; idx++)
1506 (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raRnti].first->node);
1507 cmLListDelFrm(&(cell->raInfo.raReqLst[raRnti]),
1508 &(raReqInfo->raReqLstEnt));
1509 /* ccpu00117052 - MOD - Passing double pointer
1510 for proper NULLP assignment*/
1511 rgSCHUtlFreeSBuf(cell->instIdx,
1512 (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
1523 S16 rgSCHRamAddToRaInfoSchdLst
1529 S16 rgSCHRamAddToRaInfoSchdLst(cell, raCb)
1534 CmLteTimingInfo expTime ={0};
1535 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1538 /*Fix: This can be called even when guard timer is not expired.
1539 * In this case CR timer expiry should be guard timer expiry time + Guard timer time*/
1540 RG_SCH_ADD_TO_CRNT_TIME(raCb->expiryTime, expTime, cellSch->dl.msg4TxDelay);
1541 raCb->expiryTime = expTime;
1542 raCb->schdLnk.node = (PTR)(raCb);
1543 cmLListAdd2Tail(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
1544 raCb->contResTmrLnk.node = (PTR)(raCb);
1545 cmLListAdd2Tail(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
1547 } /* rgSCHRamAddToRaInfoSchdLst */
1552 S16 rgSCHRamRmvFrmRaInfoSchdLst
1558 S16 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb)
1564 cmLListDelFrm(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
1565 raCb->schdLnk.node = NULLP;
1566 cmLListDelFrm(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
1567 raCb->contResTmrLnk.node = NULLP;
1569 } /* rgSCHRamRmvFrmRaInfoSchdLst */
1573 /***********************************************************
1575 * Func : rgSCHRamUlFreeAllocation
1577 * Desc : Free an allocation - invokes UHM and releases
1586 **********************************************************/
1588 PRIVATE Void rgSCHRamUlFreeAllocation
1591 RgSchUlAlloc *alloc,
1597 PRIVATE Void rgSCHRamUlFreeAllocation(sf, alloc, cell,isEmtc)
1599 RgSchUlAlloc *alloc;
1605 rgSCHUhmFreeProc(alloc->hqProc, cell);
1608 rgSCHUtlUlAllocRls(sf, alloc);
1613 /**********************************************************************
1616 **********************************************************************/