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 PUBLIC S16 rgSCHRamVldtUeCfg
141 PUBLIC S16 rgSCHRamVldtUeCfg(cell, ueCfg)
146 TRC2(rgSCHRamVldtUeCfg);
147 if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
149 if ((ueCfg->dedPreambleId.val < cell->rachCfg.numRaPreamble) ||
150 (ueCfg->dedPreambleId.val >= RGSCH_MAX_NUM_RA_PREAMBLE) ||
151 ((ueCfg->dedPreambleId.val >= cell->macPreambleSet.start) &&
152 (ueCfg->dedPreambleId.val <= cell->macPreambleSet.start +
153 cell->macPreambleSet.size - 1)) ||
154 ((ueCfg->crnti >= cell->rntiDb.rntiStart) &&
155 (ueCfg->crnti < cell->rntiDb.rntiStart + cell->rntiDb.maxRntis-1))
157 || (rgSCHRamVldtRgrEmtcUeCfg(cell,ueCfg))
168 * @brief Handler for Random Access Request
172 * Function : rgSCHRamProcRaReq
174 * -# Create a node for each TfuRaReqInfo element received
175 * -# Initialize the list with the above elements at the raRnti index
179 * @param[in] RgSchCellCb *cell
180 * @param[in] CmLteRnti raRnti
181 * @param[in] RgTfuRaReqInd *raReqInd
182 * @param[out] RgSchErrInfo *err
188 PUBLIC S16 rgSCHRamProcRaReq
193 TfuRachInfo *raReqInd,
194 CmLteTimingInfo timingInfo,
199 PUBLIC S16 rgSCHRamProcRaReq(raReqCnt, cell, raRnti, raReqInd, timingInfo, ue, err)
203 TfuRachInfo *raReqInd;
204 CmLteTimingInfo timingInfo;
209 RgSchRaReqInfo *raReqInfo;
216 TRC2(rgSCHRamProcRaReq)
219 /* SR_RACH_STATS : RACH REQ */
220 rgNumPrachRecvd += raReqInd->numRaReqInfo;
222 /* ccpu00132523- Moved out this from for loop as updating of raIndex is
223 * relates to only raRnti and all preambles having same raRnti*/
225 /* UL subframes do not occupy all the subframes in a radio frame.
226 * So RA Rnti index to be calculated based on actual UL subframe index. */
227 /* Get the actual subframe number */
228 tid = (raRnti-1)%RGSCH_NUM_SUB_FRAMES;
229 /* Get the frequency index in the subframe */
230 fid = ((raRnti-1) / RGSCH_NUM_SUB_FRAMES)* RGSCH_NUM_SUB_FRAMES;
231 /* Get the index of RA RNTI in the array */
232 raIndex = ((timingInfo.sfn % cell->raInfo.maxRaSize) \
233 * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES) + \
235 /* Fixes for RACH handling in TDD: Removed deletion of queued RaReq */
237 /* ccpu00132523- Placing the raReq into array based on RA SFN */
238 raIndex = (timingInfo.sfn & 1) * RGSCH_MAX_RA_RNTI + raRnti-1;
241 /* allocate new raReqInfos and enqueue them */
242 if (raReqInd->raReqInfoArr[raReqCnt].rapId >= RGSCH_MAX_NUM_RA_PREAMBLE)
244 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
245 "RARNTI:%d rgSCHTomRaReqInd(): RAM processing failed errType(%d) ",
250 /* SR_RACH_STATS : DED PREAMB*/
251 if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
258 if (raReqInd->raReqInfoArr[raReqCnt].rapId < cell->rachCfg.sizeRaPreambleGrpA)
260 cell->raPrmbs.preamGrpA++;
262 else if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
264 cell->raPrmbs.dedPream++;
268 cell->raPrmbs.preamGrpB++;
272 if((rgSCHUtlAllocSBuf(cell->instIdx, (Data **)(&raReqInfo),
273 sizeof(RgSchRaReqInfo))) == RFAILED)
275 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamProcRaReq(): Allocation"
276 " of RaReq failed RARNTI:%d",raRnti);
277 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
281 /* Insert the given raReqInfo */
283 raReqInfo->timingInfo = timingInfo;
284 raReqInfo->raReq = raReqInd->raReqInfoArr[raReqCnt];
285 raReqInfo->raReqLstEnt.next = NULLP;
286 raReqInfo->raReqLstEnt.prev = NULLP;
287 raReqInfo->raReqLstEnt.node = (PTR)raReqInfo;
292 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->raInfo.raReqLst, raIndex);
294 /* RACHO: If dedicated preamble, then give preference by appending at front */
295 if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
297 cmLListFirst(&cell->raInfo.raReqLst[raIndex]);
298 cmLListInsCrnt(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
302 cmLListAdd2Tail(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
306 } /* rgSCHRamProcRaReq */
309 * @brief Handler for Random Access control block creation
313 * Function : rgSCHRamCreateRaCb
314 * Creates a raCb and gives the same to scheduler for its updation
317 * @param[in] RgSchCellCb *cell
318 * @param[in, out] RgSchRaCb **raCb
319 * @param[out] RgSchErrInfo *err
325 PUBLIC S16 rgSCHRamCreateRaCb
332 PUBLIC S16 rgSCHRamCreateRaCb(cell, raCb, err)
338 RgSchRntiLnk *rntiLnk;
339 Inst inst = cell->instIdx;
341 TRC2(rgSCHRamCreateRaCb)
343 if((rgSCHUtlAllocSBuf(inst, (Data **)(raCb),
344 sizeof(RgSchRaCb))) == RFAILED)
346 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
348 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
352 rntiLnk = rgSCHDbmGetRnti(cell);
355 (*raCb)->rntiLnk = rntiLnk;
356 (*raCb)->tmpCrnti = rntiLnk->rnti;
361 /* SR_RACH_STATS: RNTI POOL Exhaution */
362 rgNumRarFailDuetoRntiExhaustion++;
364 /* No rnti available! */
365 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
366 "temporary RNTI failed at MAC(CRNTI exhausted)");
367 /* ccpu00117052 - MOD - Passing double pointer
368 for proper NULLP assignment*/
369 rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
370 err->errCause = RGSCHERR_RAM_RNTI_EXHAUST;
374 /* Allocate and initialize the DL HARQ portion of the RACB */
375 (*raCb)->dlHqE = rgSCHDhmHqEntInit(cell);
376 if ((*raCb)->dlHqE == NULLP)
378 /* No memory available! */
379 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Creation of"
381 /* ccpu00117052 - MOD - Passing double pointer
382 for proper NULLP assignment*/
383 rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
384 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
388 (*raCb)->isEmtcRaCb = FALSE;
389 rgSCHEmtcHqPAlloc(cell, (*raCb)->dlHqE);
391 (*raCb)->dlHqE->raCb = (*raCb);
392 /* Initialize RaCb's contents */
393 (*raCb)->timingInfo = cell->crntTime;
394 (*raCb)->raState = RGSCH_RA_MSG3_PENDING;
395 (*raCb)->toDel = FALSE;
396 (*raCb)->phr.pres = FALSE;
398 /* Insert the created raCb into raCb list of cell */
399 (*raCb)->raCbLnk.node = (PTR)(*raCb);
400 cmLListAdd2Tail(&cell->raInfo.raCbLst, &(*raCb)->raCbLnk);
403 } /* rgSCHRamCreateRaCb */
406 * @brief Handler for Ue Configuration Request
410 * Function : rgSCHRamRgrUeCfg
412 * This function handles the UE config received based on the state of the
414 * -# If raCb is in RGSCH_RA_MSG4_PENDING state, it shall update the harq
415 * information to UeCb and update the references.
416 * -# If raCb is in RGSCH_RA_MSG4_DONE, then it shall free the raCb
419 * @param[in] RgSchCellCb *cell
420 * @param[in,out] RgSchUeCb *ue
421 * @param[in,out] RgSchRaCb *raCb
422 * @param[out] RgSchErrInfo *err
428 PUBLIC S16 rgSCHRamRgrUeCfg
436 PUBLIC S16 rgSCHRamRgrUeCfg(cell, ue, raCb, err)
443 /* Releasing HARQ processes of old UE when ue
444 * reconfig with new crnti */
446 RgSchDlHqEnt **hqEnt = &(RG_SCH_CMN_GET_UE_HQE(ue, cell));
447 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
448 TRC2(rgSCHRamRgrUeCfg)
451 /* Fix : set UE inactive in DL until UE is reinitialization completed */
452 ue->dl.dlInactvMask |= RG_HQENT_INACTIVE;
453 ue->ul.ulInactvMask |= RG_HQENT_INACTIVE;
455 if(raCb->raState == RGSCH_RA_MSG4_PENDING)
458 ue->rntiLnk = raCb->rntiLnk;
459 /* Update UL Harq process information */
460 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
461 ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
463 else if(raCb->raState == RGSCH_RA_MSG4_DONE)
465 ue->rntiLnk = raCb->rntiLnk;
466 /* Update UL Harq process information */
467 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
468 ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
469 /* Fix : syed Assign hqEnt to UE only if msg4 is done */
470 rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb);
474 err->errCause = RGSCHERR_RAM_NO_MSG3_RCVD;
476 raCb->dlHqE->ue = NULLP;
481 } /* rgSCHRamRgrUeCfg */
485 * @brief Handler for C-RNTI based contention resolution
489 * Function : rgSCHRamContResCrnti
491 * This function shall be invoked once Msg3 indicates C-RNTI based
492 * contention resolution.This shall indicate the scheduler regarding
493 * C-RNTI based uplink grant.
496 * @param[in,out] RgSchCellCb *cell
497 * @param[in,out] RgSchUeCb *ue
498 * @param[in,out] RgSchRaCb *raCb
503 PRIVATE S16 rgSCHRamContResCrnti
511 PRIVATE S16 rgSCHRamContResCrnti(cell, ue, raCb, err)
518 TfuUlCqiRpt ulCqiRpt;
519 RgSchCmnCell *cellSch= (RgSchCmnCell *)(cell->sc.sch);
520 TRC2(rgSCHRamContResCrnti)
523 /* Fix: syed It is incorrect to copy over msg3HqProc to ueCb's
524 * UL harq proc. In case of Crnti based RACH, ueCb has valid context which
525 * cannot be over written. It was leading to a crash. */
527 rgSCHUtlRecMsg3Alloc(cell, ue, raCb);
529 /* Fix for ccpu00123908: Reset the UL CQI to the cell default value here */
530 ulCqiRpt.isTxPort0 = TRUE;
531 ulCqiRpt.numSubband = 0;
532 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
533 ulCqiRpt.rnti = ue->ueId;
534 /* rg002.301:[ccpu00124018]-MOD- Avoiding hard coding of CQI and retriving from cell config*/
535 ulCqiRpt.wideCqi = cellSch->ul.dfltUlCqi;
536 rgSCHUtlUlCqiInd(cell, ue, &ulCqiRpt);
539 /* Invoke scheduler to indicate UL grant req for contention resolution */
540 rgSCHUtlContResUlGrant(cell, ue, err);
542 if (raCb->phr.pres == TRUE)
544 rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, err);
546 /* No need of raCb any more */
547 rgSCHRamDelRaCb(cell, raCb, TRUE);
550 } /* rgSCHRamContResCrnti */
554 * @brief Handler for CCCH SDU based contention resolution
558 * Function : rgSCHRamContResCcchsdu
560 * This function shall be invoked once Msg3 indicates contention resolution
561 * based on CCCH sdu. This shall update the raCb state to
562 * RGSCH_RA_MSG4_PENDING.
565 * @param[in,out] RgSchRaCb *raCb
570 PRIVATE S16 rgSCHRamContResCcchsdu
576 PRIVATE S16 rgSCHRamContResCcchsdu(cell, raCb)
582 CmLteTimingInfo expTime = {0};
583 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
585 TRC2(rgSCHRamContResCcchsdu)
586 if(raCb->raState != RGSCH_RA_MSG3_PENDING)
588 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
589 "RNTI:%d RaCb in wrong State %d Drop Msg 3",
595 raCb->raState = RGSCH_RA_MSG4_PENDING;
598 if(cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay > 0)
600 /* Set the contension resolution guard timer =
601 Cont Res Timer - Max msg4 Tx Delay */
602 RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime,
603 (cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay));
607 /* Schedule the CRI CE in the next Sf itself */
608 RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime, 1);
610 raCb->expiryTime = expTime;
611 raCb->contResTmrLnk.node = (PTR)(raCb);
612 cmLListAdd2Tail(&(cell->contResGrdTmrLst), &(raCb->contResTmrLnk));
615 } /* rgSCHRamContResCcchsdu */
619 * @brief Handler for Msg3
623 * Function : rgSCHRamProcMsg3
625 * This function processes the received Msg3 and identifies the type of
626 * contention resolution and act accordingly.
629 * @param[in,out] RgSchCellCb *cell
630 * @param[in,out] RgSchUeCb *ue
631 * @param[in,out] RgSchRaCb *raCb
636 PUBLIC S16 rgSCHRamProcMsg3
645 PUBLIC S16 rgSCHRamProcMsg3(cell, ue, raCb, pdu, err)
653 TRC2(rgSCHRamProcMsg3)
656 /* Update raCb with PHR if received along with Msg3 */
657 if (pdu->ceInfo.bitMask & RGSCH_PHR_CE_PRSNT)
660 raCb->phr.pres = TRUE;
661 raCb->phr.val = pdu->ceInfo.ces.phr;
665 rgSCHRamContResCrnti(cell, ue, raCb, err);
670 if(TRUE == raCb->isEmtcRaCb)
672 /* starting the emtc Contention resolution timer */
673 rgSCHRamEmtcContResCcchsdu(cell,raCb);
678 rgSCHRamContResCcchsdu(cell, raCb);
683 } /* rgSCHRamProcMsg3 */
687 * @brief Handler for Updating Bo received in StaRsp
691 * Function : rgSCHRamUpdtBo
693 * This function shall be invoked by RAM once it receives staRsp on CCCH
695 * @param[in] RgSchCellCb *cell
696 * @param[in,out] RgSchRaCb *raCb
697 * @param[in] RgRguCmnStaRsp *staRsp
702 PUBLIC S16 rgSCHRamUpdtBo
706 RgInfCmnBoRpt *staRsp
709 PUBLIC S16 rgSCHRamUpdtBo(cell, raCb, staRsp)
712 RgInfCmnBoRpt *staRsp;
717 /* Update Bo in RaCb */
718 raCb->dlCcchInfo.bo = (U32)(staRsp->bo);
719 /* SR_RACH_STATS : MSG4 WITH CCCH SDU */
720 rgNumMsg4WithCCCHSdu++;
722 /* add this to the "tobeSchdLst" */
724 rgSCHRamAddToRaInfoSchdLst(cell, raCb);
728 } /* rgSCHRamUpdtBo */
731 * @brief Handler for Msg3 Feedback indication
735 * Function : rgSCHRamMsg3DatInd
737 * This function shall be invoked by TOM once the transmission of Msg4 is
739 * This shall invoke UHM to set ACK for Msg3 reception.
741 * @param[in,out] RgSchRaCb *raCb
746 PUBLIC S16 rgSCHRamMsg3DatInd
751 PUBLIC S16 rgSCHRamMsg3DatInd(raCb)
755 TRC2(rgSCHRamMsg3DatInd)
757 /* SR_RACH_STATS : MSG3 ACK*/
758 rgNumMsg3CrcPassed++;
759 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
760 rgSCHUhmProcMsg3DatInd(&(raCb->msg3HqProc));
763 } /* rgSCHRamMsg3DatInd */
766 * @brief Handler for Msg3 Feedback indication
770 * Function : rgSCHRamMsg3FailureInd
772 * This function shall be invoked by TOM once the transmission of Msg4 is
774 * This shall invoke UHM to set ACK for Msg3 reception.
776 * @param[in,out] RgSchRaCb *raCb
781 PUBLIC S16 rgSCHRamMsg3FailureInd
786 PUBLIC S16 rgSCHRamMsg3FailureInd(raCb)
790 TRC2(rgSCHRamMsg3FailureInd)
792 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
793 rgSCHUhmProcMsg3Failure(&(raCb->msg3HqProc));
796 } /* rgSCHRamMsg3FailureInd */
799 * @brief Handler for Msg4 Feedback indication
803 * Function : rgSCHRamMsg4FdbkInd
805 * This function shall be invoked by TOM once the transmission of Msg4 is
807 * This shall invoke UHM to set ACK for Msg3 reception.
809 * @param[in,out] RgSchRaCb *raCb
814 PUBLIC S16 rgSCHRamMsg4FdbkInd
819 PUBLIC S16 rgSCHRamMsg4FdbkInd(raCb)
823 TRC2(rgSCHRamMsg4FdbkInd)
826 } /* rgSCHRamMsg4FdbkInd */
830 * @brief Handler for Msg4 state updation
834 * Function : rgSCHRamMsg4Done
836 * This function shall be invoked by DHM once the transmission of Msg4 is
837 * done. This shall delete the raCb if there is a valid Ue or if this is to
838 * be deleted. If not this shall update the state of the raCb.
841 * @param[in] RgSchCellCb *cell
842 * @param[in,out] RgSchRaCb *raCb
847 PUBLIC S16 rgSCHRamMsg4Done
853 PUBLIC S16 rgSCHRamMsg4Done(cell, raCb)
858 TRC2(rgSCHRamMsg4Done)
860 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
861 "rgSCHRamMsg4Done(): tmpCRNTI = %u",
864 if(raCb->ue != NULLP)
866 /* Fix : syed Let this funtion decide on releasing
867 * hqP than the caller of this function otherwise sometimes it
868 * might lead to incorrec NDI setting. */
869 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
870 /* Fix : syed Assign hqEnt to UE only if msg4 is done */
871 rgSCHDhmAssgnUeHqEntFrmRaCb(raCb->ue, raCb);
873 if(TRUE == raCb->isEmtcRaCb)
875 rgSCHEmtcUtlUpdCmnNb(raCb);
878 /* MS_FIX :Proceed to CCCH scheduling irrespective of
880 if (raCb->ue->dlCcchInfo.bo)
883 /*if CR-ID Ack has been received ,Add emtc Ue to cchSduUeLst*/
884 if(TRUE == raCb->isEmtcRaCb)
886 rgSCHUtlAddUeToEmtcCcchSduLst(cell, raCb->ue);
891 rgSCHUtlAddUeToCcchSduLst(cell, raCb->ue);
894 /* Rnti shall not be released as Ue exists with this rnti */
895 rgSCHRamDelRaCb(cell, raCb, FALSE);
897 else if(raCb->toDel == TRUE)
899 #ifdef XEON_SPECIFIC_CHANGES
900 CM_LOG_DEBUG(CM_LOG_ID_SCH, "Deleting RacB:%d\n", raCb->tmpCrnti);
902 /* Delete RACB and release RNTI */
903 rgSCHRamDelRaCb(cell, raCb, TRUE);
907 #ifdef XEON_SPECIFIC_CHANGES
908 CM_LOG_DEBUG(CM_LOG_ID_SCH, "Releasing Harq of RacB:%d\n", raCb->tmpCrnti);
910 raCb->raState = RGSCH_RA_MSG4_DONE;
911 /* Release harq process as final feedback is received for Msg4. In other
912 * cases, delRaCb will take care of releasing the harq process */
913 printf("=======Harq process released \n");
914 RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
915 "Harq process released ");
916 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
920 } /* rgSCHRamMsg4Done */
924 * @brief Handler for deletion
928 * Function : rgSCHRamDelRaCb
930 * This function shall be invoked whenever a raCb needs to be deleted.
931 * Invoked by both RAM and downlink scheduler
933 * @param[in] RgSchCellCb *cell
934 * @param[in,out] RgSchRaCb *raCb
935 * @param[in] Bool rlsRnti
941 PUBLIC S16 rgSCHRamDelRaCb
948 PUBLIC S16 rgSCHRamDelRaCb(cell, raCb, rlsRnti)
954 Inst inst = cell->instIdx;
956 TRC2(rgSCHRamDelRaCb)
958 /* Delete from all the lists it is enqueued */
959 cmLListDelFrm(&(cell->raInfo.raCbLst),&(raCb->raCbLnk));
961 /*ue Type is EMTC, then Delete the toBeSchedLst and stop the Guard Timer */
962 if(TRUE == raCb->isEmtcRaCb)
964 rgSCHRamEmtcDelRaCb(cell,raCb);
970 if (raCb->schdLnk.node == (PTR)raCb)
972 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
975 else if(raCb->contResTmrLnk.node != NULLP)
977 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
978 raCb->contResTmrLnk.node = NULLP;
985 rgSCHUtlRlsRnti(cell, raCb->rntiLnk, FALSE, 0);
988 /* Check if msg4 Hq Proc has been released. If not, release it */
991 if (raCb->dlHqE->msg4Proc != NULLP)
993 /* Fix: syed Remove the msg4Proc if it waiting in sf->tbs list for
995 if ((raCb->dlHqE->msg4Proc->subFrm != NULLP) &&
996 (raCb->dlHqE->msg4Proc->hqPSfLnk.node != NULLP))
998 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"TMP CRNTI:%d RACH FAILURE!! "
999 "msg4proc removed from SF", raCb->tmpCrnti);
1000 rgSCHUtlDlHqPTbRmvFrmTx(raCb->dlHqE->msg4Proc->subFrm,
1001 raCb->dlHqE->msg4Proc, 0, FALSE);
1003 /* Fix: syed Remove the msg4Proc from cell
1004 * msg4Retx Queue. I have used CMN scheduler function
1005 * directly. Please define a new API and call this
1006 * function through that. */
1007 rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, raCb->dlHqE->msg4Proc);
1008 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
1011 /* Mark the raCb pointer in dlHqE to NULLP */
1012 raCb->dlHqE->raCb = NULLP;
1014 rgSCHDhmDelHqEnt(cell, &raCb->dlHqE);
1016 /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
1017 * from adaptive retx List. Free the alloc if it exists. */
1018 if (raCb->msg3HqProc.reTxLnk.node)
1020 //TODO_SID: Need to take care of retxLst
1021 //cmLListDelFrm(raCb->msg3HqProc.reTxAlloc.reTxLst, &raCb->msg3HqProc.reTxLnk);
1022 raCb->msg3HqProc.reTxLnk.node = (PTR)NULLP;
1025 if (raCb->msg3HqProc.alloc)
1027 /* Fix: syed During GPR, please write an API instead of direct
1028 * call to cmn scheduler function */
1029 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
1030 /*ccpu00130356 - MOD- To avoid segmentation problem because of double
1031 free due to recursive calling of rgSCHRamDelRaCb*/
1032 rgSCHRamUlFreeAllocation(&cellUl->ulSfArr[raCb->msg3HqProc.ulSfIdx],
1033 raCb->msg3HqProc.alloc,
1038 if(TRUE == raCb->isEmtcRaCb)
1040 rgSCHEmtcRaInfoFree(cell, raCb);
1043 rgSCHUtlFreeSBuf(inst, (Data **)&raCb, sizeof(RgSchRaCb));
1046 } /* rgSCHRamDelRaCb */
1050 * @brief TTI Handler for RAM module
1054 * Function : rgSCHRamTtiHndlr
1056 * This function shall be invoked upon TtiInd by TOM
1058 * - remove RaReqs added to the queue for a raRnti for which PHY may
1059 * give the requests in the next subframe
1060 * - remove raCbs which are not yet processed once the
1061 * counter for raCb processing expires.
1064 * @param[in,out] RgSchCellCb *cell
1069 PUBLIC S16 rgSCHRamTtiHndlr
1074 PUBLIC S16 rgSCHRamTtiHndlr(cell)
1081 U16 dist; /* Number of frames between raCb's creation and crnt
1088 RgSchRaReqInfo *raReqInfo;
1090 CmLteTimingInfo frm;
1094 TRC2(rgSCHRamTtiHndlr)
1096 crntSfn = cell->crntTime.sfn;
1099 /*Check if Contention resolution guard timer expiring in the TTI*/
1100 rgSCHChkContResGrdTmrExp(cell);
1101 /*Check if Contention resolution timer expiring in the TTI*/
1102 rgSCHChkContResTmrExp(cell);
1104 /*Check if EMTC Contention resolution guard timer expiring in the TTI*/
1105 rgSCHChkEmtcContResGrdTmrExp(cell);
1106 /*Check if EMTC Contention resolution timer expiring in the TTI*/
1107 rgSCHChkEmtcContResTmrExp(cell);
1112 /* Delete the RA requests for which RAR window expired in this subframe
1113 * And were not considered for RAR scheduling*/
1114 winGap = (rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat]-1)+
1115 (cell->rachCfg.raWinSize -1 ) + RGSCH_RARSP_WAIT_PERIOD;
1117 raIdx = (((crntSfn & 1) * RGSCH_MAX_RA_RNTI+ cell->crntTime.slot
1118 + RG_SCH_CMN_DL_DELTA - winGap)+ RGSCH_RAREQ_ARRAY_SIZE )
1119 % RGSCH_RAREQ_ARRAY_SIZE;
1121 /* Flush the already existing raReqs against the given raRnti */
1123 maxCnt = cell->raInfo.raReqLst[raIdx].count;
1124 for (idx = 0; idx < maxCnt; idx++)
1126 raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raIdx].first->node);
1127 cmLListDelFrm(&(cell->raInfo.raReqLst[raIdx]),&(raReqInfo->raReqLstEnt));
1128 /* ccpu00117052 - MOD - Passing double pointer
1129 for proper NULLP assignment*/
1130 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReqInfo,
1131 sizeof(RgSchRaReqInfo));
1134 /* Fixes for RACH handling: Added deletion of queued RaReq */
1135 frm = cell->crntTime;
1136 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
1137 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot] !=
1138 RG_SCH_TDD_UL_SUBFRAME)
1140 raIdx = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot]-1;
1141 rgSCHRamDelRaReq(cell, cell->crntTime, raIdx);
1145 /* Remove the RACBs which are timed out */
1146 /* ccpu00132536:MOD- racb timeout will be verified in each SFN such that
1147 * the RACB whose processing is not completed in RG_MAX_RA_PRC_FRM
1149 if (cell->crntTime.slot == 0)
1151 maxCnt = cell->raInfo.raCbLst.count;
1152 for (idx = 0; idx < maxCnt; idx++)
1154 raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
1155 /* Calculate number of frames between raCb's creation and crnt frame */
1156 raSfn = raCb->timingInfo.sfn;
1157 dist = (crntSfn + (RGSCH_MAX_SFN - raSfn)) % RGSCH_MAX_SFN;
1158 /* Delete RaCbs whose processing is not complete within
1159 * "cell->t300TmrVal" frames */
1160 /* raCb not to be deleted if msg4 is not completed */
1161 /* raCb should not be deleted(RNTI should not be released) if UE is present
1162 * as it means the application still holds the RNTI. raCb will get deleted
1163 * as part of UE deletion. raCb will anyway get deleted without releasing RNTI on success/failure of MSG4*/
1165 if (dist >= cell->t300TmrVal)
1167 if ((raCb->dlHqE->msg4Proc == NULLP) && (raCb->dlHqE->ue == NULLP))
1169 rgSCHRamDelRaCb(cell, raCb, TRUE);
1180 } /* rgSCHRamTtiHndlr */
1184 * @brief Function for handling cell delete
1188 * Function : rgSCHRamFreeCell
1190 * This function shall be invoked whenever a cell needs to be deleted.
1191 * This shall remove raCbs and raReqs stored in cell.
1194 * @param[in,out] RgSchCellCb *cell
1199 PUBLIC S16 rgSCHRamFreeCell
1204 PUBLIC S16 rgSCHRamFreeCell(cell)
1208 RgSchRaReqInfo *raReqInfo;
1212 Inst inst = cell->instIdx;
1220 TRC2(rgSCHRamFreeCell)
1225 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1227 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1228 lstSz = cell->raInfo.maxRaSize * RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
1231 /* ccpu00133557- MEM LEAK FIX- Need to free all the nodes in RA Array list */
1232 lstSz = RGSCH_RAREQ_ARRAY_SIZE;
1235 for (idx = 0; idx < lstSz; idx++)
1237 /* Delete and free raReqs stored */
1238 /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
1239 while(cell->raInfo.raReqLst[idx].count)
1241 raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[idx].first->node);
1242 cmLListDelFrm(&(cell->raInfo.raReqLst[idx]),&(raReqInfo->raReqLstEnt));
1243 /* ccpu00117052 - MOD - Passing double pointer
1244 for proper NULLP assignment*/
1245 rgSCHUtlFreeSBuf(inst, (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
1250 /* Delete the RACH response list*/
1251 /* ccpu00117052 - MOD - Passing double pointer
1252 for proper NULLP assignment*/
1253 rgSCHUtlFreeSBuf(inst,
1254 (Data **)(&(cell->rachRspLst)), sizeof(RgSchTddRachRspLst) * \
1258 /* Delete raCbs in the "to be scheduled" list */
1259 /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
1260 while(cell->raInfo.toBeSchdLst.count)
1262 raCb = (RgSchRaCb *)(cell->raInfo.toBeSchdLst.first->node);
1263 /* MSG4 Fix Start */
1265 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
1269 /* Delete raCbs in the "Emtc to be scheduled" list */
1270 if(cell->emtcEnable)
1272 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst(cell);
1276 raCbCnt = cell->raInfo.raCbLst.count;
1278 /* Delete and free raCbs stored */
1279 for (idx = 0; idx < raCbCnt; idx++)
1281 raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
1282 rgSCHRamDelRaCb(cell, raCb, TRUE);
1286 } /* rgSCHRamFreeCell */
1289 PRIVATE Void rgSCHRamProcContResExp
1295 PRIVATE Void rgSCHRamProcContResExp (cell, raCb)
1300 TRC2(rgSCHRamProcContResExp);
1301 raCb->expiryTime.sfn = RGSCH_CONTRES_EXP;
1305 /* UE exists and RNTI will be released as part of UE DEL */
1306 rgSCHRamDelRaCb(cell, raCb, FALSE);
1310 /* Calling Release RNTI, which would perform Racb deletion
1311 * RNTI removal and RNTI release indication to MAC. */
1312 /* Delete RACB and release RNTI */
1313 rgSCHRamDelRaCb(cell, raCb, TRUE);
1319 PRIVATE Void rgSCHRamProcContResGrdExp
1325 PRIVATE Void rgSCHRamProcContResGrdExp (cell, raCb)
1330 TRC2(rgSCHRamProcContResGrdExp)
1333 /*Guard timer has expired, schedule only the contention REsolution CE with
1335 raCb->dlCcchInfo.bo = 0;
1336 /* SR_RACH_STATS : MSG4 WO CCCH SDU */
1337 rgNumMsg4WoCCCHSdu++;
1339 /* add this to the "tobeSchdLst" */
1340 raCb->schdLnk.node = (PTR)(raCb);
1342 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
1343 raCb->contResTmrLnk.node = NULLP;
1345 /* MSG4 Fix Start */
1346 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
1347 "Con Res Grd Tmr exp RNTI:%d",
1348 raCb->rntiLnk->rnti);
1349 rgSCHRamAddToRaInfoSchdLst(cell, raCb);
1355 * @brief Check the Contention Resolution Guard Timer Expiry.
1359 * Function: rgSCHChkContResTmrExp
1362 * Invoked by: Scheduler
1363 * @param[in] RgSchCellCb *cell
1369 PRIVATE Void rgSCHChkContResTmrExp
1374 PRIVATE Void rgSCHChkContResTmrExp(cell)
1378 CmLList *chkLnk = NULLP;
1379 RgSchRaCb *raCb = NULLP;
1381 TRC2(rgSCHChkContResTmrExp)
1383 chkLnk = cmLListFirst(&(cell->contResTmrLst));
1385 for (; chkLnk; chkLnk = chkLnk->next)
1387 raCb = (RgSchRaCb *)(chkLnk->node);
1389 if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
1391 /*If timer expired, call the handler function*/
1392 rgSCHRamProcContResExp(cell, raCb);
1394 /*Fix: Need to traverse till end of list as the entries may not be in ascending order*/
1402 * @brief Check the Contention Resolution Guard Timer Expiry.
1406 * Function: rgSCHChkContResGrdTmrExp
1409 * Invoked by: Scheduler
1410 * @param[in] RgSchCellCb *cell
1416 PRIVATE Void rgSCHChkContResGrdTmrExp
1421 PRIVATE Void rgSCHChkContResGrdTmrExp(cell)
1425 CmLList *chkLnk = NULLP;
1426 RgSchRaCb *raCb = NULLP;
1428 TRC2(rgSCHChkContResGrdTmrExp)
1430 chkLnk = cmLListFirst(&(cell->contResGrdTmrLst));
1432 /*[ccpu00131941]-MOD-List traversal should be done using the listCp */
1433 for (; chkLnk; chkLnk = cmLListNext(&cell->contResGrdTmrLst))
1435 raCb = (RgSchRaCb *)(chkLnk->node);
1437 if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
1439 /*If timer expired, call the handler function*/
1440 rgSCHRamProcContResGrdExp(cell, raCb);
1451 * @brief Function for handling RACH Request deletion
1455 * Function : rgSCHRamDelRaReq
1457 * This function shall be invoked to delete the RACH Requests
1458 * that is not scheduled within the RA window size.
1461 * @param[in,out] RgSchCellCb *cell
1462 * @param[in] CmLteTimingInfo timingInfo
1463 * @param[in] U8 raIdx
1468 PUBLIC S16 rgSCHRamDelRaReq
1471 CmLteTimingInfo timingInfo,
1475 PUBLIC S16 rgSCHRamDelRaReq(cell, timingInfo, raIdx)
1477 CmLteTimingInfo timingInfo;
1482 RgSchTddRachRspLst *rachRsp;
1486 RgSchRaReqInfo *raReqInfo;
1492 TRC2(rgSCHRamDelRaReq)
1495 rachRsp = &cell->rachRspLst[raIdx];
1496 /* Get the SFN Index to be deleted */
1497 calcSfn = timingInfo.sfn - rachRsp->delInfo.sfnOffset;
1500 sfnIdx = (calcSfn + RGSCH_MAX_SFN) % cell->raInfo.maxRaSize;
1507 /* Iterate through all the subframes to be delted in the SFN */
1508 for(subfrmIdx=0; subfrmIdx < rachRsp->delInfo.numSubfrms; subfrmIdx++)
1510 subfrm = rachRsp->delInfo.subframe[subfrmIdx];
1511 /* Get the subframe Index to be deleted */
1512 /* Fixes for RACH handling in TDD:
1513 * Corrected the computation of raRntiIdx
1515 raRntiIdx = ((sfnIdx % cell->raInfo.maxRaSize) * \
1516 RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
1517 RGSCH_NUM_SUB_FRAMES) + subfrm;
1519 /* Iterate through all the RNTIs in the subframe */
1520 for(i=0; i < RGSCH_MAX_RA_RNTI_PER_SUBFRM; i++)
1522 raRnti = raRntiIdx + (i*RGSCH_NUM_SUB_FRAMES);
1523 for (idx = 0; idx < cell->raInfo.raReqLst[raRnti].count; idx++)
1526 (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raRnti].first->node);
1527 cmLListDelFrm(&(cell->raInfo.raReqLst[raRnti]),
1528 &(raReqInfo->raReqLstEnt));
1529 /* ccpu00117052 - MOD - Passing double pointer
1530 for proper NULLP assignment*/
1531 rgSCHUtlFreeSBuf(cell->instIdx,
1532 (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
1543 PUBLIC S16 rgSCHRamAddToRaInfoSchdLst
1549 PUBLIC S16 rgSCHRamAddToRaInfoSchdLst(cell, raCb)
1554 CmLteTimingInfo expTime ={0};
1555 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1557 TRC2(rgSCHRamAddToRaInfoSchdLst)
1559 /*Fix: This can be called even when guard timer is not expired.
1560 * In this case CR timer expiry should be guard timer expiry time + Guard timer time*/
1561 RG_SCH_ADD_TO_CRNT_TIME(raCb->expiryTime, expTime, cellSch->dl.msg4TxDelay);
1562 raCb->expiryTime = expTime;
1563 raCb->schdLnk.node = (PTR)(raCb);
1564 cmLListAdd2Tail(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
1565 raCb->contResTmrLnk.node = (PTR)(raCb);
1566 cmLListAdd2Tail(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
1568 } /* rgSCHRamAddToRaInfoSchdLst */
1573 PUBLIC S16 rgSCHRamRmvFrmRaInfoSchdLst
1579 PUBLIC S16 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb)
1584 TRC2(rgSCHRamRmvFrmRaInfoSchdLst)
1586 cmLListDelFrm(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
1587 raCb->schdLnk.node = NULLP;
1588 cmLListDelFrm(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
1589 raCb->contResTmrLnk.node = NULLP;
1591 } /* rgSCHRamRmvFrmRaInfoSchdLst */
1595 /***********************************************************
1597 * Func : rgSCHRamUlFreeAllocation
1599 * Desc : Free an allocation - invokes UHM and releases
1608 **********************************************************/
1610 PRIVATE Void rgSCHRamUlFreeAllocation
1613 RgSchUlAlloc *alloc,
1619 PRIVATE Void rgSCHRamUlFreeAllocation(sf, alloc, cell,isEmtc)
1621 RgSchUlAlloc *alloc;
1626 TRC2(rgSCHRamUlFreeAllocation);
1628 rgSCHUhmFreeProc(alloc->hqProc, cell);
1631 rgSCHUtlUlAllocRls(sf, alloc);
1636 /**********************************************************************
1639 **********************************************************************/