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 Bool rgSCHRamVldtRgrEmtcUeCfg ARGS((
71 S16 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst
75 Void rgSCHEmtcUtlUpdCmnNb
79 Void rgSCHEmtcHqPAlloc
87 static Void rgSCHRamUlFreeAllocation ARGS((RgSchUlSf *sf,RgSchUlAlloc *alloc,
88 RgSchCellCb *cell,Bool isEmtc));
90 static S16 rgSCHRamContResCrnti ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
91 RgSchRaCb *raCb, RgSchErrInfo *err));
92 static S16 rgSCHRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
95 S16 rgSCHEmtcRamContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
96 S16 rgSCHRamEmtcContResCcchsdu ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
97 Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell));
98 Void rgSCHChkEmtcContResTmrExp ARGS((RgSchCellCb *cell));
99 Void rgSCHEmtcRaInfoFree ARGS((RgSchCellCb *cell, RgSchRaCb *raCb));
102 static Void rgSCHChkContResGrdTmrExp ARGS((RgSchCellCb *cell));
103 static Void rgSCHChkContResTmrExp ARGS((RgSchCellCb *cell));
104 static Void rgSCHRamProcContResExp ARGS((RgSchCellCb *cell,
106 static Void rgSCHRamProcContResGrdExp ARGS((RgSchCellCb *cell,
109 Void rgSCHChkEmtcContResGrdTmrExp ARGS((RgSchCellCb *cell));
110 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
134 S16 rgSCHRamVldtUeCfg(RgSchCellCb *cell,RgrUeCfg *ueCfg)
136 if (ueCfg->dedPreambleId.pres == PRSNT_NODEF)
138 if ((ueCfg->dedPreambleId.val < cell->rachCfg.numRaPreamble) ||
139 (ueCfg->dedPreambleId.val >= RGSCH_MAX_NUM_RA_PREAMBLE) ||
140 ((ueCfg->dedPreambleId.val >= cell->macPreambleSet.start) &&
141 (ueCfg->dedPreambleId.val <= cell->macPreambleSet.start +
142 cell->macPreambleSet.size - 1)) ||
143 ((ueCfg->crnti >= cell->rntiDb.rntiStart) &&
144 (ueCfg->crnti < cell->rntiDb.rntiStart + cell->rntiDb.maxRntis-1))
146 || (rgSCHRamVldtRgrEmtcUeCfg(cell,ueCfg))
157 * @brief Handler for Random Access Request
161 * Function : rgSCHRamProcRaReq
163 * -# Create a node for each TfuRaReqInfo element received
164 * -# Initialize the list with the above elements at the raRnti index
168 * @param[in] RgSchCellCb *cell
169 * @param[in] CmLteRnti raRnti
170 * @param[in] RgTfuRaReqInd *raReqInd
171 * @param[out] RgSchErrInfo *err
176 S16 rgSCHRamProcRaReq
181 TfuRachInfo *raReqInd,
182 CmLteTimingInfo timingInfo,
187 RgSchRaReqInfo *raReqInfo;
196 /* SR_RACH_STATS : RACH REQ */
197 rgNumPrachRecvd += raReqInd->numRaReqInfo;
199 /* ccpu00132523- Moved out this from for loop as updating of raIndex is
200 * relates to only raRnti and all preambles having same raRnti*/
202 /* UL subframes do not occupy all the subframes in a radio frame.
203 * So RA Rnti index to be calculated based on actual UL subframe index. */
204 /* Get the actual subframe number */
205 tid = (raRnti-1)%RGSCH_NUM_SUB_FRAMES;
206 /* Get the frequency index in the subframe */
207 fid = ((raRnti-1) / RGSCH_NUM_SUB_FRAMES)* RGSCH_NUM_SUB_FRAMES;
208 /* Get the index of RA RNTI in the array */
209 raIndex = ((timingInfo.sfn % cell->raInfo.maxRaSize) \
210 * RGSCH_MAX_RA_RNTI_PER_SUBFRM * RGSCH_NUM_SUB_FRAMES) + \
212 /* Fixes for RACH handling in TDD: Removed deletion of queued RaReq */
214 /* ccpu00132523- Placing the raReq into array based on RA SFN */
215 raIndex = (timingInfo.sfn & 1) * RGSCH_MAX_RA_RNTI + raRnti-1;
218 /* allocate new raReqInfos and enqueue them */
219 if (raReqInd->raReqInfoArr[raReqCnt].rapId >= RGSCH_MAX_NUM_RA_PREAMBLE)
221 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
222 "RARNTI:%d rgSCHTomRaReqInd(): RAM processing failed errType(%d) ",
227 /* SR_RACH_STATS : DED PREAMB*/
228 if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
235 if (raReqInd->raReqInfoArr[raReqCnt].rapId < cell->rachCfg.sizeRaPreambleGrpA)
237 cell->raPrmbs.preamGrpA++;
239 else if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
241 cell->raPrmbs.dedPream++;
245 cell->raPrmbs.preamGrpB++;
249 if((rgSCHUtlAllocSBuf(cell->instIdx, (Data **)(&raReqInfo),
250 sizeof(RgSchRaReqInfo))) == RFAILED)
252 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamProcRaReq(): Allocation"
253 " of RaReq failed RARNTI:%d",raRnti);
254 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
258 /* Insert the given raReqInfo */
260 raReqInfo->timingInfo = timingInfo;
261 raReqInfo->raReq = raReqInd->raReqInfoArr[raReqCnt];
262 raReqInfo->raReqLstEnt.next = NULLP;
263 raReqInfo->raReqLstEnt.prev = NULLP;
264 raReqInfo->raReqLstEnt.node = (PTR)raReqInfo;
269 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->raInfo.raReqLst, raIndex);
271 /* RACHO: If dedicated preamble, then give preference by appending at front */
272 if (RGSCH_IS_DEDPRM(cell, raReqInd->raReqInfoArr[raReqCnt].rapId))
274 cmLListFirst(&cell->raInfo.raReqLst[raIndex]);
275 cmLListInsCrnt(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
279 cmLListAdd2Tail(&cell->raInfo.raReqLst[raIndex], &raReqInfo->raReqLstEnt);
283 } /* rgSCHRamProcRaReq */
286 * @brief Handler for Random Access control block creation
290 * Function : rgSCHRamCreateRaCb
291 * Creates a raCb and gives the same to scheduler for its updation
294 * @param[in] RgSchCellCb *cell
295 * @param[in, out] RgSchRaCb **raCb
296 * @param[out] RgSchErrInfo *err
301 S16 rgSCHRamCreateRaCb
308 RgSchRntiLnk *rntiLnk;
309 Inst inst = cell->instIdx;
312 if((rgSCHUtlAllocSBuf(inst, (Data **)(raCb),
313 sizeof(RgSchRaCb))) == RFAILED)
315 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
317 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
321 rntiLnk = rgSCHDbmGetRnti(cell);
324 (*raCb)->rntiLnk = rntiLnk;
325 (*raCb)->tmpCrnti = rntiLnk->rnti;
330 /* SR_RACH_STATS: RNTI POOL Exhaution */
331 rgNumRarFailDuetoRntiExhaustion++;
333 /* No rnti available! */
334 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Allocation of "
335 "temporary RNTI failed at MAC(CRNTI exhausted)");
336 /* ccpu00117052 - MOD - Passing double pointer
337 for proper NULLP assignment*/
338 rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
339 err->errCause = RGSCHERR_RAM_RNTI_EXHAUST;
343 /* Allocate and initialize the DL HARQ portion of the RACB */
344 (*raCb)->dlHqE = rgSCHDhmHqEntInit(cell);
345 if ((*raCb)->dlHqE == NULLP)
347 /* No memory available! */
348 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSCHRamCreateRaCb(): Creation of"
350 /* ccpu00117052 - MOD - Passing double pointer
351 for proper NULLP assignment*/
352 rgSCHUtlFreeSBuf(inst, (Data **)(raCb), sizeof(RgSchRaCb));
353 err->errCause = RGSCHERR_RAM_MEM_EXHAUST;
357 (*raCb)->isEmtcRaCb = FALSE;
358 rgSCHEmtcHqPAlloc(cell, (*raCb)->dlHqE);
360 (*raCb)->dlHqE->raCb = (*raCb);
361 /* Initialize RaCb's contents */
362 (*raCb)->timingInfo = cell->crntTime;
363 (*raCb)->raState = RGSCH_RA_MSG3_PENDING;
364 (*raCb)->toDel = FALSE;
365 (*raCb)->phr.pres = FALSE;
367 /* Insert the created raCb into raCb list of cell */
368 (*raCb)->raCbLnk.node = (PTR)(*raCb);
369 cmLListAdd2Tail(&cell->raInfo.raCbLst, &(*raCb)->raCbLnk);
372 } /* rgSCHRamCreateRaCb */
375 * @brief Handler for Ue Configuration Request
379 * Function : rgSCHRamRgrUeCfg
381 * This function handles the UE config received based on the state of the
383 * -# If raCb is in RGSCH_RA_MSG4_PENDING state, it shall update the harq
384 * information to UeCb and update the references.
385 * -# If raCb is in RGSCH_RA_MSG4_DONE, then it shall free the raCb
388 * @param[in] RgSchCellCb *cell
389 * @param[in,out] RgSchUeCb *ue
390 * @param[in,out] RgSchRaCb *raCb
391 * @param[out] RgSchErrInfo *err
404 /* Releasing HARQ processes of old UE when ue
405 * reconfig with new crnti */
407 RgSchDlHqEnt **hqEnt = &(RG_SCH_CMN_GET_UE_HQE(ue, cell));
408 RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
411 /* Fix : set UE inactive in DL until UE is reinitialization completed */
412 ue->dl.dlInactvMask |= RG_HQENT_INACTIVE;
413 ue->ul.ulInactvMask |= RG_HQENT_INACTIVE;
415 if(raCb->raState == RGSCH_RA_MSG4_PENDING)
418 ue->rntiLnk = raCb->rntiLnk;
419 /* Update UL Harq process information */
420 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
421 ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
423 else if(raCb->raState == RGSCH_RA_MSG4_DONE)
425 ue->rntiLnk = raCb->rntiLnk;
426 /* Update UL Harq process information */
427 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
428 ueUl->hqEnt.hqProcCb[raCb->msg3HqProcId].ndi = raCb->msg3HqProc.ndi;
429 /* Fix : syed Assign hqEnt to UE only if msg4 is done */
430 rgSCHDhmAssgnUeHqEntFrmRaCb(ue, raCb);
434 err->errCause = RGSCHERR_RAM_NO_MSG3_RCVD;
436 raCb->dlHqE->ue = NULLP;
441 } /* rgSCHRamRgrUeCfg */
445 * @brief Handler for C-RNTI based contention resolution
449 * Function : rgSCHRamContResCrnti
451 * This function shall be invoked once Msg3 indicates C-RNTI based
452 * contention resolution.This shall indicate the scheduler regarding
453 * C-RNTI based uplink grant.
456 * @param[in,out] RgSchCellCb *cell
457 * @param[in,out] RgSchUeCb *ue
458 * @param[in,out] RgSchRaCb *raCb
462 static S16 rgSCHRamContResCrnti
470 TfuUlCqiRpt ulCqiRpt;
471 RgSchCmnCell *cellSch= (RgSchCmnCell *)(cell->sc.sch);
474 /* Fix: syed It is incorrect to copy over msg3HqProc to ueCb's
475 * UL harq proc. In case of Crnti based RACH, ueCb has valid context which
476 * cannot be over written. It was leading to a crash. */
478 rgSCHUtlRecMsg3Alloc(cell, ue, raCb);
480 /* Fix for ccpu00123908: Reset the UL CQI to the cell default value here */
481 ulCqiRpt.isTxPort0 = TRUE;
482 ulCqiRpt.numSubband = 0;
483 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
484 ulCqiRpt.rnti = ue->ueId;
485 /* rg002.301:[ccpu00124018]-MOD- Avoiding hard coding of CQI and retriving from cell config*/
486 ulCqiRpt.wideCqi = cellSch->ul.dfltUlCqi;
487 rgSCHUtlUlCqiInd(cell, ue, &ulCqiRpt);
490 /* Invoke scheduler to indicate UL grant req for contention resolution */
491 rgSCHUtlContResUlGrant(cell, ue, err);
493 if (raCb->phr.pres == TRUE)
495 rgSCHUtlUpdPhr(cell, ue, raCb->phr.val, err);
497 /* No need of raCb any more */
498 rgSCHRamDelRaCb(cell, raCb, TRUE);
501 } /* rgSCHRamContResCrnti */
505 * @brief Handler for CCCH SDU based contention resolution
509 * Function : rgSCHRamContResCcchsdu
511 * This function shall be invoked once Msg3 indicates contention resolution
512 * based on CCCH sdu. This shall update the raCb state to
513 * RGSCH_RA_MSG4_PENDING.
516 * @param[in,out] RgSchRaCb *raCb
520 static S16 rgSCHRamContResCcchsdu
527 CmLteTimingInfo expTime = {0};
528 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
530 if(raCb->raState != RGSCH_RA_MSG3_PENDING)
532 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
533 "RNTI:%d RaCb in wrong State %d Drop Msg 3",
539 raCb->raState = RGSCH_RA_MSG4_PENDING;
542 if(cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay > 0)
544 /* Set the contension resolution guard timer =
545 Cont Res Timer - Max msg4 Tx Delay */
546 RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime,
547 (cell->rachCfg.contResTmr - cellSch->dl.msg4TxDelay));
551 /* Schedule the CRI CE in the next Sf itself */
552 RG_SCH_ADD_TO_CRNT_TIME(cell->crntTime, expTime, 1);
554 raCb->expiryTime = expTime;
555 raCb->contResTmrLnk.node = (PTR)(raCb);
556 cmLListAdd2Tail(&(cell->contResGrdTmrLst), &(raCb->contResTmrLnk));
559 } /* rgSCHRamContResCcchsdu */
563 * @brief Handler for Msg3
567 * Function : rgSCHRamProcMsg3
569 * This function processes the received Msg3 and identifies the type of
570 * contention resolution and act accordingly.
573 * @param[in,out] RgSchCellCb *cell
574 * @param[in,out] RgSchUeCb *ue
575 * @param[in,out] RgSchRaCb *raCb
590 /* Update raCb with PHR if received along with Msg3 */
591 if (pdu->ceInfo.bitMask & RGSCH_PHR_CE_PRSNT)
594 raCb->phr.pres = TRUE;
595 raCb->phr.val = pdu->ceInfo.ces.phr;
599 rgSCHRamContResCrnti(cell, ue, raCb, err);
604 if(TRUE == raCb->isEmtcRaCb)
606 /* starting the emtc Contention resolution timer */
607 rgSCHRamEmtcContResCcchsdu(cell,raCb);
612 rgSCHRamContResCcchsdu(cell, raCb);
617 } /* rgSCHRamProcMsg3 */
621 * @brief Handler for Updating Bo received in StaRsp
625 * Function : rgSCHRamUpdtBo
627 * This function shall be invoked by RAM once it receives staRsp on CCCH
629 * @param[in] RgSchCellCb *cell
630 * @param[in,out] RgSchRaCb *raCb
631 * @param[in] RgRguCmnStaRsp *staRsp
639 RgInfCmnBoRpt *staRsp
643 /* Update Bo in RaCb */
644 raCb->dlCcchInfo.bo = (uint32_t)(staRsp->bo);
645 /* SR_RACH_STATS : MSG4 WITH CCCH SDU */
646 rgNumMsg4WithCCCHSdu++;
648 /* add this to the "tobeSchdLst" */
650 rgSCHRamAddToRaInfoSchdLst(cell, raCb);
654 } /* rgSCHRamUpdtBo */
657 * @brief Handler for Msg3 Feedback indication
661 * Function : rgSCHRamMsg3DatInd
663 * This function shall be invoked by TOM once the transmission of Msg4 is
665 * This shall invoke UHM to set ACK for Msg3 reception.
667 * @param[in,out] RgSchRaCb *raCb
671 S16 rgSCHRamMsg3DatInd(RgSchRaCb *raCb)
674 /* SR_RACH_STATS : MSG3 ACK*/
675 rgNumMsg3CrcPassed++;
676 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
677 rgSCHUhmProcMsg3DatInd(&(raCb->msg3HqProc));
680 } /* rgSCHRamMsg3DatInd */
683 * @brief Handler for Msg3 Feedback indication
687 * Function : rgSCHRamMsg3FailureInd
689 * This function shall be invoked by TOM once the transmission of Msg4 is
691 * This shall invoke UHM to set ACK for Msg3 reception.
693 * @param[in,out] RgSchRaCb *raCb
697 S16 rgSCHRamMsg3FailureInd(RgSchRaCb *raCb)
700 /*ccpu00128820 - MOD - Msg3 alloc double delete issue*/
701 rgSCHUhmProcMsg3Failure(&(raCb->msg3HqProc));
704 } /* rgSCHRamMsg3FailureInd */
707 * @brief Handler for Msg4 Feedback indication
711 * Function : rgSCHRamMsg4FdbkInd
713 * This function shall be invoked by TOM once the transmission of Msg4 is
715 * This shall invoke UHM to set ACK for Msg3 reception.
717 * @param[in,out] RgSchRaCb *raCb
721 S16 rgSCHRamMsg4FdbkInd(RgSchRaCb *raCb)
725 } /* rgSCHRamMsg4FdbkInd */
729 * @brief Handler for Msg4 state updation
733 * Function : rgSCHRamMsg4Done
735 * This function shall be invoked by DHM once the transmission of Msg4 is
736 * done. This shall delete the raCb if there is a valid Ue or if this is to
737 * be deleted. If not this shall update the state of the raCb.
740 * @param[in] RgSchCellCb *cell
741 * @param[in,out] RgSchRaCb *raCb
745 S16 rgSCHRamMsg4Done(RgSchCellCb *cell,RgSchRaCb *raCb)
748 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
749 "rgSCHRamMsg4Done(): tmpCRNTI = %u",
752 if(raCb->ue != NULLP)
754 /* Fix : syed Let this funtion decide on releasing
755 * hqP than the caller of this function otherwise sometimes it
756 * might lead to incorrec NDI setting. */
757 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
758 /* Fix : syed Assign hqEnt to UE only if msg4 is done */
759 rgSCHDhmAssgnUeHqEntFrmRaCb(raCb->ue, raCb);
761 if(TRUE == raCb->isEmtcRaCb)
763 rgSCHEmtcUtlUpdCmnNb(raCb);
766 /* MS_FIX :Proceed to CCCH scheduling irrespective of
768 if (raCb->ue->dlCcchInfo.bo)
771 /*if CR-ID Ack has been received ,Add emtc Ue to cchSduUeLst*/
772 if(TRUE == raCb->isEmtcRaCb)
774 rgSCHUtlAddUeToEmtcCcchSduLst(cell, raCb->ue);
779 rgSCHUtlAddUeToCcchSduLst(cell, raCb->ue);
782 /* Rnti shall not be released as Ue exists with this rnti */
783 rgSCHRamDelRaCb(cell, raCb, FALSE);
785 else if(raCb->toDel == TRUE)
787 #ifdef XEON_SPECIFIC_CHANGES
788 CM_LOG_DEBUG(CM_LOG_ID_SCH, "Deleting RacB:%d\n", raCb->tmpCrnti);
790 /* Delete RACB and release RNTI */
791 rgSCHRamDelRaCb(cell, raCb, TRUE);
795 #ifdef XEON_SPECIFIC_CHANGES
796 CM_LOG_DEBUG(CM_LOG_ID_SCH, "Releasing Harq of RacB:%d\n", raCb->tmpCrnti);
798 raCb->raState = RGSCH_RA_MSG4_DONE;
799 /* Release harq process as final feedback is received for Msg4. In other
800 * cases, delRaCb will take care of releasing the harq process */
801 printf("=======Harq process released \n");
802 RLOG_ARG0(L_DEBUG,DBG_CELLID,cell->cellId,
803 "Harq process released ");
804 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
808 } /* rgSCHRamMsg4Done */
812 * @brief Handler for deletion
816 * Function : rgSCHRamDelRaCb
818 * This function shall be invoked whenever a raCb needs to be deleted.
819 * Invoked by both RAM and downlink scheduler
821 * @param[in] RgSchCellCb *cell
822 * @param[in,out] RgSchRaCb *raCb
823 * @param[in] Bool rlsRnti
828 S16 rgSCHRamDelRaCb(RgSchCellCb *cell,RgSchRaCb *raCb,Bool rlsRnti)
830 Inst inst = cell->instIdx;
833 /* Delete from all the lists it is enqueued */
834 cmLListDelFrm(&(cell->raInfo.raCbLst),&(raCb->raCbLnk));
836 /*ue Type is EMTC, then Delete the toBeSchedLst and stop the Guard Timer */
837 if(TRUE == raCb->isEmtcRaCb)
839 rgSCHRamEmtcDelRaCb(cell,raCb);
845 if (raCb->schdLnk.node == (PTR)raCb)
847 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
850 else if(raCb->contResTmrLnk.node != NULLP)
852 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
853 raCb->contResTmrLnk.node = NULLP;
860 rgSCHUtlRlsRnti(cell, raCb->rntiLnk, FALSE, 0);
863 /* Check if msg4 Hq Proc has been released. If not, release it */
866 if (raCb->dlHqE->msg4Proc != NULLP)
868 /* Fix: syed Remove the msg4Proc if it waiting in sf->tbs list for
870 if ((raCb->dlHqE->msg4Proc->subFrm != NULLP) &&
871 (raCb->dlHqE->msg4Proc->hqPSfLnk.node != NULLP))
873 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"TMP CRNTI:%d RACH FAILURE!! "
874 "msg4proc removed from SF", raCb->tmpCrnti);
875 rgSCHUtlDlHqPTbRmvFrmTx(raCb->dlHqE->msg4Proc->subFrm,
876 raCb->dlHqE->msg4Proc, 0, FALSE);
878 /* Fix: syed Remove the msg4Proc from cell
879 * msg4Retx Queue. I have used CMN scheduler function
880 * directly. Please define a new API and call this
881 * function through that. */
882 rgSCHCmnDlMsg4ProcRmvFrmRetx(cell, raCb->dlHqE->msg4Proc);
883 rgSCHDhmRlsHqpTb(raCb->dlHqE->msg4Proc, 0, TRUE);
886 /* Mark the raCb pointer in dlHqE to NULLP */
887 raCb->dlHqE->raCb = NULLP;
889 rgSCHDhmDelHqEnt(cell, &raCb->dlHqE);
891 /* Fix: syed Adaptive Msg3 Retx crash. Remove the harqProc
892 * from adaptive retx List. Free the alloc if it exists. */
893 if (raCb->msg3HqProc.reTxLnk.node)
895 //TODO_SID: Need to take care of retxLst
896 //cmLListDelFrm(raCb->msg3HqProc.reTxAlloc.reTxLst, &raCb->msg3HqProc.reTxLnk);
897 raCb->msg3HqProc.reTxLnk.node = (PTR)NULLP;
900 if (raCb->msg3HqProc.alloc)
902 /* Fix: syed During GPR, please write an API instead of direct
903 * call to cmn scheduler function */
904 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
905 /*ccpu00130356 - MOD- To avoid segmentation problem because of double
906 free due to recursive calling of rgSCHRamDelRaCb*/
907 rgSCHRamUlFreeAllocation(&cellUl->ulSfArr[raCb->msg3HqProc.ulSfIdx],
908 raCb->msg3HqProc.alloc,
913 if(TRUE == raCb->isEmtcRaCb)
915 rgSCHEmtcRaInfoFree(cell, raCb);
918 rgSCHUtlFreeSBuf(inst, (Data **)&raCb, sizeof(RgSchRaCb));
921 } /* rgSCHRamDelRaCb */
925 * @brief TTI Handler for RAM module
929 * Function : rgSCHRamTtiHndlr
931 * This function shall be invoked upon TtiInd by TOM
933 * - remove RaReqs added to the queue for a raRnti for which PHY may
934 * give the requests in the next subframe
935 * - remove raCbs which are not yet processed once the
936 * counter for raCb processing expires.
939 * @param[in,out] RgSchCellCb *cell
943 S16 rgSCHRamTtiHndlr(RgSchCellCb *cell)
948 uint16_t dist; /* Number of frames between raCb's creation and crnt frame */
954 RgSchRaReqInfo *raReqInfo;
961 crntSfn = cell->crntTime.sfn;
964 /*Check if Contention resolution guard timer expiring in the TTI*/
965 rgSCHChkContResGrdTmrExp(cell);
966 /*Check if Contention resolution timer expiring in the TTI*/
967 rgSCHChkContResTmrExp(cell);
969 /*Check if EMTC Contention resolution guard timer expiring in the TTI*/
970 rgSCHChkEmtcContResGrdTmrExp(cell);
971 /*Check if EMTC Contention resolution timer expiring in the TTI*/
972 rgSCHChkEmtcContResTmrExp(cell);
977 /* Delete the RA requests for which RAR window expired in this subframe
978 * And were not considered for RAR scheduling*/
979 winGap = (rgRaPrmblToRaFrmTbl[cell->rachCfg.preambleFormat]-1)+
980 (cell->rachCfg.raWinSize -1 ) + RGSCH_RARSP_WAIT_PERIOD;
982 raIdx = (((crntSfn & 1) * RGSCH_MAX_RA_RNTI+ cell->crntTime.slot
983 + RG_SCH_CMN_DL_DELTA - winGap)+ RGSCH_RAREQ_ARRAY_SIZE )
984 % RGSCH_RAREQ_ARRAY_SIZE;
986 /* Flush the already existing raReqs against the given raRnti */
988 maxCnt = cell->raInfo.raReqLst[raIdx].count;
989 for (idx = 0; idx < maxCnt; idx++)
991 raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raIdx].first->node);
992 cmLListDelFrm(&(cell->raInfo.raReqLst[raIdx]),&(raReqInfo->raReqLstEnt));
993 /* ccpu00117052 - MOD - Passing double pointer
994 for proper NULLP assignment*/
995 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&raReqInfo,
996 sizeof(RgSchRaReqInfo));
999 /* Fixes for RACH handling: Added deletion of queued RaReq */
1000 frm = cell->crntTime;
1001 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
1002 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot] !=
1003 RG_SCH_TDD_UL_SUBFRAME)
1005 raIdx = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot]-1;
1006 rgSCHRamDelRaReq(cell, cell->crntTime, raIdx);
1010 /* Remove the RACBs which are timed out */
1011 /* ccpu00132536:MOD- racb timeout will be verified in each SFN such that
1012 * the RACB whose processing is not completed in RG_MAX_RA_PRC_FRM
1014 if (cell->crntTime.slot == 0)
1016 maxCnt = cell->raInfo.raCbLst.count;
1017 for (idx = 0; idx < maxCnt; idx++)
1019 raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
1020 /* Calculate number of frames between raCb's creation and crnt frame */
1021 raSfn = raCb->timingInfo.sfn;
1022 dist = (crntSfn + (RGSCH_MAX_SFN - raSfn)) % RGSCH_MAX_SFN;
1023 /* Delete RaCbs whose processing is not complete within
1024 * "cell->t300TmrVal" frames */
1025 /* raCb not to be deleted if msg4 is not completed */
1026 /* raCb should not be deleted(RNTI should not be released) if UE is present
1027 * as it means the application still holds the RNTI. raCb will get deleted
1028 * as part of UE deletion. raCb will anyway get deleted without releasing RNTI on success/failure of MSG4*/
1030 if (dist >= cell->t300TmrVal)
1032 if ((raCb->dlHqE->msg4Proc == NULLP) && (raCb->dlHqE->ue == NULLP))
1034 rgSCHRamDelRaCb(cell, raCb, TRUE);
1045 } /* rgSCHRamTtiHndlr */
1049 * @brief Function for handling cell delete
1053 * Function : rgSCHRamFreeCell
1055 * This function shall be invoked whenever a cell needs to be deleted.
1056 * This shall remove raCbs and raReqs stored in cell.
1059 * @param[in,out] RgSchCellCb *cell
1063 S16 rgSCHRamFreeCell(RgSchCellCb *cell)
1065 RgSchRaReqInfo *raReqInfo;
1069 Inst inst = cell->instIdx;
1072 uint8_t maxUlSubframes;
1073 uint8_t maxDlSubframes;
1081 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1083 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1084 lstSz = cell->raInfo.maxRaSize * RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
1087 /* ccpu00133557- MEM LEAK FIX- Need to free all the nodes in RA Array list */
1088 lstSz = RGSCH_RAREQ_ARRAY_SIZE;
1091 for (idx = 0; idx < lstSz; idx++)
1093 /* Delete and free raReqs stored */
1094 /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
1095 while(cell->raInfo.raReqLst[idx].count)
1097 raReqInfo = (RgSchRaReqInfo *)(cell->raInfo.raReqLst[idx].first->node);
1098 cmLListDelFrm(&(cell->raInfo.raReqLst[idx]),&(raReqInfo->raReqLstEnt));
1099 /* ccpu00117052 - MOD - Passing double pointer
1100 for proper NULLP assignment*/
1101 rgSCHUtlFreeSBuf(inst, (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
1106 /* Delete the RACH response list*/
1107 /* ccpu00117052 - MOD - Passing double pointer
1108 for proper NULLP assignment*/
1109 rgSCHUtlFreeSBuf(inst,
1110 (Data **)(&(cell->rachRspLst)), sizeof(RgSchTddRachRspLst) * \
1114 /* Delete raCbs in the "to be scheduled" list */
1115 /* ccpu00133557- MEM LEAK FIX- Need to be freed till the count is non-zero */
1116 while(cell->raInfo.toBeSchdLst.count)
1118 raCb = (RgSchRaCb *)(cell->raInfo.toBeSchdLst.first->node);
1119 /* MSG4 Fix Start */
1121 rgSCHRamRmvFrmRaInfoSchdLst(cell, raCb);
1125 /* Delete raCbs in the "Emtc to be scheduled" list */
1126 if(cell->emtcEnable)
1128 rgSCHRamRmvAllFrmEmtcRaInfoSchdLst(cell);
1132 raCbCnt = cell->raInfo.raCbLst.count;
1134 /* Delete and free raCbs stored */
1135 for (idx = 0; idx < raCbCnt; idx++)
1137 raCb = (RgSchRaCb *)(cell->raInfo.raCbLst.first->node);
1138 rgSCHRamDelRaCb(cell, raCb, TRUE);
1142 } /* rgSCHRamFreeCell */
1144 static Void rgSCHRamProcContResExp(RgSchCellCb *cell,RgSchRaCb *raCb)
1146 raCb->expiryTime.sfn = RGSCH_CONTRES_EXP;
1150 /* UE exists and RNTI will be released as part of UE DEL */
1151 rgSCHRamDelRaCb(cell, raCb, FALSE);
1155 /* Calling Release RNTI, which would perform Racb deletion
1156 * RNTI removal and RNTI release indication to MAC. */
1157 /* Delete RACB and release RNTI */
1158 rgSCHRamDelRaCb(cell, raCb, TRUE);
1163 static Void rgSCHRamProcContResGrdExp(RgSchCellCb *cell,RgSchRaCb *raCb)
1167 /*Guard timer has expired, schedule only the contention REsolution CE with
1169 raCb->dlCcchInfo.bo = 0;
1170 /* SR_RACH_STATS : MSG4 WO CCCH SDU */
1171 rgNumMsg4WoCCCHSdu++;
1173 /* add this to the "tobeSchdLst" */
1174 raCb->schdLnk.node = (PTR)(raCb);
1176 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
1177 raCb->contResTmrLnk.node = NULLP;
1179 /* MSG4 Fix Start */
1180 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,
1181 "Con Res Grd Tmr exp RNTI:%d",
1182 raCb->rntiLnk->rnti);
1183 rgSCHRamAddToRaInfoSchdLst(cell, raCb);
1189 * @brief Check the Contention Resolution Guard Timer Expiry.
1193 * Function: rgSCHChkContResTmrExp
1196 * Invoked by: Scheduler
1197 * @param[in] RgSchCellCb *cell
1202 static Void rgSCHChkContResTmrExp(RgSchCellCb *cell)
1204 CmLList *chkLnk = NULLP;
1205 RgSchRaCb *raCb = NULLP;
1208 chkLnk = cmLListFirst(&(cell->contResTmrLst));
1210 for (; chkLnk; chkLnk = chkLnk->next)
1212 raCb = (RgSchRaCb *)(chkLnk->node);
1214 if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
1216 /*If timer expired, call the handler function*/
1217 rgSCHRamProcContResExp(cell, raCb);
1219 /*Fix: Need to traverse till end of list as the entries may not be in ascending order*/
1227 * @brief Check the Contention Resolution Guard Timer Expiry.
1231 * Function: rgSCHChkContResGrdTmrExp
1234 * Invoked by: Scheduler
1235 * @param[in] RgSchCellCb *cell
1240 static Void rgSCHChkContResGrdTmrExp(RgSchCellCb *cell)
1242 CmLList *chkLnk = NULLP;
1243 RgSchRaCb *raCb = NULLP;
1246 chkLnk = cmLListFirst(&(cell->contResGrdTmrLst));
1248 /*[ccpu00131941]-MOD-List traversal should be done using the listCp */
1249 for (; chkLnk; chkLnk = cmLListNext(&cell->contResGrdTmrLst))
1251 raCb = (RgSchRaCb *)(chkLnk->node);
1253 if(RGSCH_TIMEINFO_SAME(raCb->expiryTime, cell->crntTime))
1255 /*If timer expired, call the handler function*/
1256 rgSCHRamProcContResGrdExp(cell, raCb);
1267 * @brief Function for handling RACH Request deletion
1271 * Function : rgSCHRamDelRaReq
1273 * This function shall be invoked to delete the RACH Requests
1274 * that is not scheduled within the RA window size.
1277 * @param[in,out] RgSchCellCb *cell
1278 * @param[in] CmLteTimingInfo timingInfo
1279 * @param[in] uint8_t raIdx
1283 S16 rgSCHRamDelRaReq
1286 CmLteTimingInfo timingInfo,
1291 RgSchTddRachRspLst *rachRsp;
1295 RgSchRaReqInfo *raReqInfo;
1303 rachRsp = &cell->rachRspLst[raIdx];
1304 /* Get the SFN Index to be deleted */
1305 calcSfn = timingInfo.sfn - rachRsp->delInfo.sfnOffset;
1308 sfnIdx = (calcSfn + RGSCH_MAX_SFN) % cell->raInfo.maxRaSize;
1315 /* Iterate through all the subframes to be delted in the SFN */
1316 for(subfrmIdx=0; subfrmIdx < rachRsp->delInfo.numSubfrms; subfrmIdx++)
1318 subfrm = rachRsp->delInfo.subframe[subfrmIdx];
1319 /* Get the subframe Index to be deleted */
1320 /* Fixes for RACH handling in TDD:
1321 * Corrected the computation of raRntiIdx
1323 raRntiIdx = ((sfnIdx % cell->raInfo.maxRaSize) * \
1324 RGSCH_MAX_RA_RNTI_PER_SUBFRM * \
1325 RGSCH_NUM_SUB_FRAMES) + subfrm;
1327 /* Iterate through all the RNTIs in the subframe */
1328 for(i=0; i < RGSCH_MAX_RA_RNTI_PER_SUBFRM; i++)
1330 raRnti = raRntiIdx + (i*RGSCH_NUM_SUB_FRAMES);
1331 for (idx = 0; idx < cell->raInfo.raReqLst[raRnti].count; idx++)
1334 (RgSchRaReqInfo *)(cell->raInfo.raReqLst[raRnti].first->node);
1335 cmLListDelFrm(&(cell->raInfo.raReqLst[raRnti]),
1336 &(raReqInfo->raReqLstEnt));
1337 /* ccpu00117052 - MOD - Passing double pointer
1338 for proper NULLP assignment*/
1339 rgSCHUtlFreeSBuf(cell->instIdx,
1340 (Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
1350 S16 rgSCHRamAddToRaInfoSchdLst(RgSchCellCb *cell,RgSchRaCb *raCb)
1352 CmLteTimingInfo expTime ={0};
1353 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1356 /*Fix: This can be called even when guard timer is not expired.
1357 * In this case CR timer expiry should be guard timer expiry time + Guard timer time*/
1358 RG_SCH_ADD_TO_CRNT_TIME(raCb->expiryTime, expTime, cellSch->dl.msg4TxDelay);
1359 raCb->expiryTime = expTime;
1360 raCb->schdLnk.node = (PTR)(raCb);
1361 cmLListAdd2Tail(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
1362 raCb->contResTmrLnk.node = (PTR)(raCb);
1363 cmLListAdd2Tail(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
1365 } /* rgSCHRamAddToRaInfoSchdLst */
1369 S16 rgSCHRamRmvFrmRaInfoSchdLst(RgSchCellCb *cell,RgSchRaCb *raCb)
1372 cmLListDelFrm(&(cell->raInfo.toBeSchdLst), &(raCb->schdLnk));
1373 raCb->schdLnk.node = NULLP;
1374 cmLListDelFrm(&(cell->contResTmrLst), &(raCb->contResTmrLnk));
1375 raCb->contResTmrLnk.node = NULLP;
1377 } /* rgSCHRamRmvFrmRaInfoSchdLst */
1381 /***********************************************************
1383 * Func : rgSCHRamUlFreeAllocation
1385 * Desc : Free an allocation - invokes UHM and releases
1394 **********************************************************/
1395 static Void rgSCHRamUlFreeAllocation
1398 RgSchUlAlloc *alloc,
1404 rgSCHUhmFreeProc(alloc->hqProc, cell);
1407 rgSCHUtlUlAllocRls(sf, alloc);
1412 /**********************************************************************
1415 **********************************************************************/