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 scheduler 1
29 **********************************************************************/
31 /** @file rg_sch_sc1.c
32 @brief The scheduling functionality is implemented in this file.
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_MODULE_ID=4096;
37 static int RLOG_FILE_ID=173;
39 /* header include files -- defines (.h) */
40 #include "common_def.h"
46 #include "rg_sch_inf.h"
47 #include "rg_sch_err.h"
49 #include "rg_sch_cmn.h"
50 #include "rg_sch_sc1.h"
51 #include "rl_interface.h"
52 #include "rl_common.h"
54 /* header/extern include files (.x) */
55 #include "tfu.x" /* RGU types */
56 #include "lrg.x" /* layer management typedefs for MAC */
57 #include "rgr.x" /* layer management typedefs for MAC */
58 #include "rgm.x" /* layer management typedefs for MAC */
59 #include "rg_sch_inf.x" /* typedefs for Scheduler */
60 #include "rg_sch.x" /* typedefs for Scheduler */
61 #include "rg_sch_cmn.x"
62 #include "rg_sch_sc1.x" /* typedefs for SC1 Scheduler */
69 #endif /* __cplusplus */
71 /* Functions called from outside */
72 PRIVATE S16 rgSCHSc1RgrDlCellRecfg ARGS((
78 /*--------------------------*
79 * DL SCHED STATIC declarations START
80 *---------------------------*/
81 PRIVATE Void rgSCHSc1DlSvcAddToSchd ARGS((
85 PRIVATE Void rgSCHSc1DlAdd2UeSchdSvcs ARGS((
90 PRIVATE Void rgSCHSc1DlRmvUeFrmPrioQs ARGS((
94 PRIVATE Void rgSCHSc1DlSuspendUe ARGS((
98 PRIVATE Void rgSCHSc1DlInactvtUe ARGS((
102 PRIVATE Void rgSCHSc1DlProcRmvFrmCellRetx ARGS((
106 PRIVATE Void rgSCHSc1DlProcRmvFrmUeRetx ARGS((
111 PRIVATE Void rgSCHSc1DlMngPrio0SvcPosn ARGS((
116 PRIVATE Void rgSCHSc1DlMngGbrSvcPosn ARGS((
121 PRIVATE Void rgSCHSc1DlMngAmbrSvcPosn ARGS((
126 PRIVATE Void rgSCHSc1DlMngSvcPosn ARGS((
131 PRIVATE Void rgSCHSc1DlUeAddToSchd ARGS((
135 PRIVATE Void rgSCHSc1DlTaCmd ARGS((
137 RgSchCmnDlRbAllocInfo *allocInfo
139 PRIVATE Void rgSCHSc1DlInitQueues ARGS((
140 RgSchSc1DlCell *cellDl
142 PRIVATE Void rgSCHSc1DlDeinitQueues ARGS((
143 RgSchSc1DlCell *cellDl
145 PRIVATE Void rgSCHSc1DlAdd2UeLcsWithData ARGS((
150 PRIVATE Void rgSCHSc1DlRmFrmUeLcsWithData ARGS((
155 /*--------------------------*
156 * UL SCHED STATIC declarations START
157 *---------------------------*/
158 PRIVATE Void rgSCHSc1UlPosnUeInQ ARGS((
162 PRIVATE Void rgSCHSc1UlSchdUeTxLst ARGS((
165 RgSchCmnUlRbAllocInfo *allocInfo,
168 PRIVATE Void rgSCHSc1DlProcRmvFrmRetx ARGS((
173 PUBLIC Void rgSCHSc1DlScanUpdPdbPrio ARGS((
176 PUBLIC S16 rgSCHSc1DlFillFlowCntrlInfo ARGS((
178 RgInfSfAlloc *sfAlloc
181 PRIVATE Void rgSCHSc1DlPreSchd ARGS ((
184 PRIVATE Void rgSCHSc1DlPstSchd ARGS ((
189 #endif /* __cplusplus */
194 /***************** SC1 DL SCHEDULER FUNCTION DEFNs START HERE ********/
196 /***********************************************************
198 * Func : rgSCHSc1DlUeReset
200 * Desc : Out of Meas Gap. Reposition the UEs Retx Hq Procs,
201 * and Svc in respective Prio Qs.
210 **********************************************************/
212 PUBLIC Void rgSCHSc1DlUeReset
218 PUBLIC Void rgSCHSc1DlUeReset(cell, ue)
223 TRC2(rgSCHSc1DlUeReset);
225 rgSCHSc1DlSuspendUe(cell, ue);
231 /***********************************************************
233 * Func : rgSCHSc1DlActvtUe
235 * Desc : Out of Meas Gap. Reposition the UEs Retx Hq Procs,
236 * and Svc in respective Prio Qs.
245 **********************************************************/
247 PUBLIC Void rgSCHSc1DlActvtUe
253 PUBLIC Void rgSCHSc1DlActvtUe(cell, ue)
258 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
261 RgSchDlHqProcCb *hqP;
264 TRC2(rgSCHSc1DlActvtUe);
266 /* Add UE's HqProcs From UERetxLst to CellRetxLst */
267 lst = &ueDl->retxHqProcs;
271 hqP = (RgSchDlHqProcCb *)node->node;
273 rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
274 rgSCHSc1DlProcAddToCellRetx(cell, hqP);
277 /* Iterate over all the Services if bo != 0 then add */
278 for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx)
280 svc = ue->dl.lcCb[idx];
285 rgSCHSc1DlMngSvcPosn(cell, ue, svc);
288 /* Add UE to AMBR Prio Q */
291 rgSCHSc1DlUeAddToSchd(cell, ue);
298 /***********************************************************
300 * Func : rgSCHSc1DlUeRefresh
302 * Desc : Handle 'refresh' for Downlink
303 * (ie UE's downlink AMBR and downlink GBR LCGs are
304 * refreshed at this point)
312 **********************************************************/
314 PUBLIC Void rgSCHSc1DlUeRefresh
320 PUBLIC Void rgSCHSc1DlUeRefresh(cell, ue)
325 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
326 /*cell added as part of CA dev*/
327 RgSchCmnDlSvc *svcCmn;
328 RgSchSc1DlSvc *svcSc1;
332 TRC2(rgSCHSc1DlUeRefresh);
336 ueDl->ambr = ue->dl.ambrCfgd;
340 ueDl->ambr = RG_SC1_MAX_DL_AMBR;
343 if (ueDl->ambrSvc != NULLP)
345 ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, ueDl->ambrSvc->bo);
346 /* Update UEs position in the Queue */
347 rgSCHSc1DlUeAddToSchd(cell, ue);
350 lst = &ueDl->gbrSvcs;
352 while (node != NULLP)
354 svc = (RgSchDlLcCb *)node->node;
355 svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
356 svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
358 svcSc1->gbr = svcCmn->gbr;
359 svcSc1->mbr = svcCmn->mbr;
360 /* Update the SVC's positioning in the Queue */
361 rgSCHSc1DlMngGbrSvcPosn(cell, ue, svc);
368 * @brief This function removes a HARQ process from the retx
372 * Function: rgSCHSc1DlProcRmvFrmCellRetx
373 * Purpose: This function removes a HARQ process from retransmission
374 * queue. This may be performed when a HARQ ack is successful
375 * for a retransmission or when the scheduling determines
376 * to throw out the process due to poor conditions
378 * Invoked by: LIM and Scheduler
380 * @param[in] RgSchSc1Cb* cell
381 * @param[in] RgDlHqProc* hqP
386 PRIVATE Void rgSCHSc1DlProcRmvFrmCellRetx
392 PRIVATE Void rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP)
394 RgSchDlHqProcCb *hqP;
397 RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
398 RgSchCmnDlHqProc *hqProcDl = RG_SCH_CMN_GET_DL_HQP(hqP);
400 TRC2(rgSCHSc1DlProcRmvFrmCellRetx);
402 if (hqProcDl->retxLnk.node != NULLP)
404 cmLListDelFrm(&cellDl->retxLst[((RgSchSc1DlHqProc *)\
405 (hqProcDl->schSpfc))->prio], &(hqProcDl->retxLnk));
406 hqProcDl->retxLnk.node = NULLP;
413 * @brief This function removes a HARQ process from the UE retx
417 * Function: rgSCHSc1DlProcRmvFrmUeRetx
418 * Purpose: This function removes a HARQ process from UE retransmission
421 * Invoked by: LIM and Scheduler
423 * @param[in] RgSchUeCb* ue
424 * @param[in] RgDlHqProc* hqP
429 PRIVATE Void rgSCHSc1DlProcRmvFrmUeRetx
436 PRIVATE Void rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP)
439 RgSchDlHqProcCb *hqP;
442 RgSchSc1DlUe *sc1Ue = RG_GET_SC1_UE_DL(ue, cell);
443 RgSchSc1DlHqProc *hqProcDl = RG_GET_SC1_HQP_DL(hqP);
445 TRC2(rgSCHSc1DlProcRmvFrmUeRetx);
447 if (hqProcDl->retxLnkUe.node != NULLP)
449 cmLListDelFrm(&sc1Ue->retxHqProcs,
450 &(hqProcDl->retxLnkUe));
451 hqProcDl->retxLnkUe.node = NULLP;
458 * @brief This function adds a HARQ process for UEs retxLst
462 * Function: rgSCHSc1DlProcAddToUeRetx
463 * Purpose: This function adds a HARQ process to UE retransmission
464 * queue. This is performed when UE is suspended due
465 * to measurement gap.
467 * Invoked by: HARQ feedback processing
469 * @param[in] RgSchUeCb* ue
470 * @param[in] RgSchDlHqProc* hqP
475 PRIVATE Void rgSCHSc1DlProcAddToUeRetx
482 PRIVATE Void rgSCHSc1DlProcAddToUeRetx(cell, ue, hqP)
485 RgSchDlHqProcCb *hqP;
488 RgSchSc1DlUe *sc1Ue = RG_GET_SC1_UE_DL(ue, cell);
489 RgSchSc1DlHqProc *cmnHqDl = RG_GET_SC1_HQP_DL(hqP);
491 TRC2(rgSCHSc1DlProcAddToUeRetx);
493 cmLListAdd2Tail(&sc1Ue->retxHqProcs,
494 &(cmnHqDl->retxLnkUe));
495 cmnHqDl->retxLnkUe.node = (PTR)hqP;
501 * @brief This function adds a HARQ process for retx
505 * Function: rgSCHSc1DlProcAddToCellRetx
506 * Purpose: This function adds a HARQ process to retransmission
507 * queue. This may be performed when a HARQ ack is
510 * Invoked by: HARQ feedback processing
512 * @param[in] RgSchCellCb* cell
513 * @param[in] RgSchDlHqProc* hqP
518 PUBLIC Void rgSCHSc1DlProcAddToCellRetx
524 PUBLIC Void rgSCHSc1DlProcAddToCellRetx(cell, hqP)
526 RgSchDlHqProcCb *hqP;
529 RgSchSc1DlCell *sc1CellDl = RG_GET_SC1_CELL_DL(cell);
530 RgSchCmnDlHqProc *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
532 TRC2(rgSCHSc1DlProcAddToCellRetx);
534 if (!RG_SCH_CMN_DL_IS_UE_ACTIVE(hqP->hqE->ue))
536 rgSCHSc1DlProcAddToUeRetx(cell, hqP->hqE->ue, hqP);
539 cmLListAdd2Tail(&sc1CellDl->retxLst[((RgSchSc1DlHqProc *)\
540 (cmnHqDl->schSpfc))->prio], &(cmnHqDl->retxLnk));
541 cmnHqDl->retxLnk.node = (PTR)hqP;
547 * @brief This function implements DL RETRANSMISSION allocation
551 * Function: rgSCHSc1DlRetxAlloc
552 * Purpose: This function implements downlink scheduler's
553 * retransmission allocation.
555 * Invoked by: Scheduler
557 * @param[in] RgSchCellCb *cell
558 * @param[in] RgSchDlSf *subFrm
559 * @param[out] RgSchCmnDlRbAllocInfo *allocInfo
564 PRIVATE Void rgSCHSc1DlRetxAlloc
568 RgSchCmnDlRbAllocInfo *allocInfo
571 PRIVATE Void rgSCHSc1DlRetxAlloc(cell, subFrm, allocInfo)
574 RgSchCmnDlRbAllocInfo *allocInfo;
580 RgSchDlHqProcCb *hqP;
581 RgSchSc1DlCell *sc1CellDl;
582 RgSchSc1DlUe *sc1DlUe;
583 RgSchCmnDlUe *cmnUeDl;
584 #if (defined(LTEMAC_SPS) || (!defined(LTE_TDD)))
585 CmLteTimingInfo schdTime;
588 RgSchUeCb *ue = NULLP;
590 Bool dlAllowed = FALSE;
592 RgSchDlRbAlloc *dlAllocCb;
593 TRC2(rgSCHSc1DlRetxAlloc);
595 sc1CellDl = RG_GET_SC1_CELL_DL(cell);
596 #if (defined(LTEMAC_SPS) || (!defined(LTE_TDD)))
597 schdTime = cell->crntTime;
599 /* Increment by DL DELTA to determine the time for which scheduling
601 RGSCH_INCR_SUB_FRAME(schdTime, RG_SCH_CMN_DL_DELTA);
603 for (i = 0; i < RG_SCH_SC1_DL_PRIOS; i++)
605 retxLst = &sc1CellDl->retxLst[i];
606 /* allocate bw for the retransmission..should be same are previous */
607 /* If CQI gets worse, as we cannot find same TB size for another */
608 /* MCS, we just remove this from the retransmission queue */
609 node = retxLst->first;
610 while (node != NULLP)
612 hqP = (RgSchDlHqProcCb *)node->node;
617 if((0 == schdTime.slot) || (5 == schdTime.slot))
620 rgSCHCmnChkRetxAllowDtx(cell, ue, hqP, &reTxAllw);
621 if(FALSE == reTxAllw)
630 rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed);
631 if (dlAllowed == FALSE)
637 /* This UE is already scheduled for transmission */
638 cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
639 /*cell added as part of CA dev*/
641 if (RG_SCH_CMN_IS_UE_SPS_SCHDLD(ue, cell, schdTime))
646 if (RG_SCH_CMN_IS_UE_SCHDLD(ue, cell))
651 /* Extra check: indicate if there is furtherScope for NewTx
652 * addition for a HqProc. This information will
653 * be utilized by common scheduler, in case of SM
654 * UEs with only one of the TBs retransmitting and the
655 * other TB can be used for clubbing new TX. */
656 sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
657 dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
658 if (sc1DlUe->lcsWithData.first != NULLP)
660 dlAllocCb->mimoAllocInfo.hasNewTxData = TRUE;
662 /* 3.1 MIMO : last parameter changed */
663 if (rgSCHCmnDlAllocRetxRb(cell, subFrm, ue, 0, &effBo, hqP, allocInfo) !=\
666 /* SF/RETX Bandwidth expired */
674 if ((hqP->tbInfo[0].state == HQ_TB_ACKED)
675 && (hqP->tbInfo[1].state == HQ_TB_ACKED))
677 rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
682 /* 3.1 MIMO moving this call in cmn scheduler */
683 /*rgSCHCmnDlRbInfoAddUeRetx(allocInfo, ue);*/
689 /***********************************************************
691 * Func : rgSCHSc1RlsHqProc
693 * Desc : Toggles the NDI and releases the harq proc.
701 **********************************************************/
703 PRIVATE Void rgSCHSc1RlsHqProc
705 RgSchDlHqProcCb *hqProc
708 PRIVATE Void rgSCHSc1RlsHqProc(hqProc)
709 RgSchDlHqProcCb *hqProc;
712 TRC2(rgSCHSc1RlsHqProc)
713 rgSCHDhmRlsHqProc(hqProc);
718 * @brief This function implements dedicated logical channel data scheduling
722 * Function: rgSCHSc1DlDedSvcAlloc
723 * Purpose: This function implements dedicated logical
724 * channel data scheduling
726 * Invoked by: Scheduler
728 * @param[in] RgSchCellCb *cell
729 * @param[in] RgSchDlSf *subFrm
730 * @param[in] RgSchDlLcCb *svc
732 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
737 PRIVATE S16 rgSCHSc1DlDedSvcAlloc
743 RgSchCmnDlRbAllocInfo *allocInfo
746 PRIVATE S16 rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, bo, allocInfo)
751 RgSchCmnDlRbAllocInfo *allocInfo;
755 RgSchDlHqProcCb *proc;
758 RgSchCmnDlCell *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
759 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
760 RgSchSc1DlSvc *svcSc1;
762 RgSchSc1DlHqProc *sc1HqDl;
763 RgSchCmnDlHqProc *cmnHqDl;
765 CmLteTimingInfo schdTime;
768 Bool dlAllowed = FALSE;
772 TRC2(rgSCHSc1DlDedSvcAlloc);
774 /* Get the UE to which this service belongs to */
779 rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed);
780 if (dlAllowed == FALSE)
786 ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
787 /*cell added as part of CA dev*/
789 schdTime = cell->crntTime;
791 /* Increment by DL DELTA to determine the time for which scheduling
793 RGSCH_INCR_SUB_FRAME(schdTime, RG_SCH_CMN_DL_DELTA);
794 if (RG_SCH_CMN_IS_UE_SPS_SCHDLD(ue, cell, schdTime))
799 if (RG_SCH_CMN_IS_UE_SCHDLD(ue, cell))
801 proc = (RgSchDlHqProcCb *)(ueDl->proc);
802 /* This UE is selected for retransmission. Hence no further */
803 /* scheduling may be done for this UE */
804 if (RG_SCH_CMN_PROC_SLCTD_FOR_RETX(proc))
806 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d rgSCHSc1DlDedSvcAlloc():"
807 "Ue retransmitting",ue->ueId);
810 /* UE is scheduled for either other services or TA */
811 sc1HqDl = RG_GET_SC1_HQP_DL(proc);
812 cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc);
813 if (sc1HqDl->prio > svcCmn->prio)
815 sc1HqDl->prio = svcCmn->prio;
818 else /* First consideration of this UE for scheduling */
820 if (rgSCHDhmGetAvlHqProc(cell, ue, cmnCellDl->time, &proc) != ROK)
822 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "CRNTI:%d rgSCHSc1DlDedSvcAlloc():"
823 " No HARQ Proc available", ue->ueId);
826 sc1HqDl = RG_GET_SC1_HQP_DL(proc);
827 cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc);
828 cmnHqDl->totBytes = 0;
829 /* Initialize some of the parameters of the HQ proc */
830 sc1HqDl->prio = svcCmn->prio;
833 /* Including each SDU's header size */
834 RG_SCH_CMN_DL_GET_HDR_EST(svc, rlcHdrEstmt);
837 ret = rgSCHCmnDlAllocTxRb(cell, subFrm, ue, bo, &effBo, proc, allocInfo);
838 if ((ret != ROK) || (effBo == 0))
840 /* If no allocations so far, meaning proc obtained now */
841 if (cmnHqDl->totBytes == 0)
843 rgSCHSc1RlsHqProc(proc);
844 /* Added the handling for removing
845 * UE from txHqPLst and resetting outStndAlloc.*/
846 if(proc->reqLnk.node != (PTR)NULLP)
848 cmLListDelFrm(&allocInfo->dedAlloc.txHqPLst, &proc->reqLnk);
849 proc->reqLnk.node = (PTR)NULLP;
851 /*Re-set the outstanding alloc information.*/
852 ueDl->outStndAlloc = 0;
854 /* ccpu00126519: proc should be set to NULLP in UE's DL scratch pad info as well. */
859 svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
860 svcSc1->hdrEstimate = rlcHdrEstmt;
861 svcSc1->reqBytes = bo;
863 cmnHqDl->totBytes += effBo;
865 rgSCHSc1DlAdd2UeSchdSvcs(cell, ue, svc);
866 /* 3.1 MIMO moving this call to cmn scheduler */
867 /*rgSCHCmnDlRbInfoAddUeTx(allocInfo, ue); */
872 * @brief This function adds a SVC to UE's schdSvcsLst.
876 * Function: rgSCHSc1DlAdd2UeSchdSvcs
877 * Purpose: This function adds a SVC to UE's schdSvcsLst.
879 * Invoked by: Specific Scheduler
881 * @param[out] RgSchUeCb *ue
882 * @param[in] RgSchDlLcCb *svc
887 PRIVATE Void rgSCHSc1DlAdd2UeSchdSvcs
894 PRIVATE Void rgSCHSc1DlAdd2UeSchdSvcs(cell, ue, svc)
900 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
901 RgSchSc1DlUe *ueSc1 = RG_GET_SC1_UE_DL(ue, cell);
902 TRC2(rgSCHSc1DlAdd2UeSchdSvcs);
904 /* checking SVC's presence in this lst is unnecessary */
905 cmLListAdd2Tail(&ueSc1->schdSvcs, &svcSc1->schdSvcLnk);
906 svcSc1->schdSvcLnk.node = (PTR)svc;
912 * @brief This function performs new allocations for UEs
916 * Function: rgSCHSc1DlDedTx
917 * Purpose: This function implements scheduler for DL allocation for
918 * new transmissions of UEs.
919 * 1. It performs across 9 priorities that it supports -
920 * This is from 3GPP specifications
921 * 2. There are known number of GBR/MBR queues
922 * 3. The first queue is highest priority queue and is
923 * satisfied completely prior to any other queues. This
924 * queue is for RRC signalling.
925 * 4. Futher GBR/MBR queues are satisfied for GBR and then MBR
926 * 5. Subsequently all other queues are looked at for AMBR
928 * Invoked by: Scheduler
930 * @param[in] RgSchCellCb* cell
931 * @param[in] RgSchDlSf *subFrm
932 * @param[out] RgSchCmnDlRbAllocInfo *allocInfo
937 PRIVATE Void rgSCHSc1DlDedTx
941 RgSchCmnDlRbAllocInfo *allocInfo
944 PRIVATE Void rgSCHSc1DlDedTx(cell, subFrm, allocInfo)
947 RgSchCmnDlRbAllocInfo *allocInfo;
952 RgSchUeCb *ue = NULLP;
955 RgSchSc1DlSvc *svcSc1;
957 RgSchSc1DlCell *sc1CellDl = RG_GET_SC1_CELL_DL(cell);
959 TRC2(rgSCHSc1DlDedTx);
961 /* Process the first queue that is for RRC signalling and is of */
962 /* highest priority. */
963 lst = &sc1CellDl->prioLst[0];
967 /* Getting service instead of UE */
968 svc = (RgSchDlLcCb *)node->node;
970 svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
972 if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, svcSc1->bo, allocInfo) != ROK)
979 /* Perform allocation for the GBR transmissions */
980 for(i = RG_SCH_SC1_DL_GBR_PRIO_START; i <= RG_SCH_SC1_DL_GBR_PRIO_END; i++)
982 lst = &sc1CellDl->prioLst[i];
986 /* Getting service instead of UE */
987 svc = (RgSchDlLcCb *)node->node;
989 svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
991 if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, svcSc1->effMbr, allocInfo) != ROK)
999 /* To implement AMBR svc scheduling */
1000 for(i = RG_SCH_SC1_DL_GBR_PRIO_END + 1; i < RG_SCH_SC1_DL_PRIOS; i++)
1002 lst = &sc1CellDl->prioLst[i];
1004 while(node != NULLP)
1006 ue = (RgSchUeCb *)node->node;
1007 ueDl = RG_GET_SC1_UE_DL(ue, cell);
1009 /* Get the Curr ambr svc for which allocation is to be made */
1010 svc = ueDl->ambrSvc;
1011 if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, ueDl->effAmbr, allocInfo) != ROK)
1022 * @brief scheduling for a cell
1026 * Function : rgSCHSc1DlPreSchd
1029 * - Nothing to be done in case of RR
1031 * @param[in] Inst schInst
1035 PRIVATE Void rgSCHSc1DlPreSchd
1040 PUBLIC Void rgSCHSc1DlPreSchd(cell)
1044 TRC2(rgSCHSc1DlPreSchd);
1049 * @brief scheduling for a cell
1053 * Function : rgSCHSc1DlPstSchd
1056 * - Nothing to be done in case of RR
1058 * @param[in] Inst schInst
1062 PRIVATE Void rgSCHSc1DlPstSchd
1067 PUBLIC Void rgSCHSc1DlPstSchd(schInst)
1071 TRC2(rgSCHSc1DlPstSchd);
1078 * @brief This function implements scheduler DL allocation
1082 * Function: rgSCHSc1DlDedNewTx
1083 * Purpose: This function implements scheduler for DL allocation for
1086 * Invoked by: Scheduler
1088 * @param[in] RgSchCellCb *cell
1089 * @param[out] RgSchCmnDlRbAllocInfo *allocInfo
1094 PRIVATE Void rgSCHSc1DlDedNewTx
1097 RgSchCmnDlRbAllocInfo *allocInfo
1100 PRIVATE Void rgSCHSc1DlDedNewTx(cell, allocInfo)
1102 RgSchCmnDlRbAllocInfo *allocInfo;
1105 RgSchDlSf *subFrm = allocInfo->dedAlloc.dedDlSf;
1107 Inst inst = cell->instIdx;
1109 TRC2(rgSCHSc1DlDedNewTx);
1110 RGSCHDBGPRM(inst, (rgSchPBuf(inst), "rgSCHSc1DlDedNewTx\n"));
1112 /* Now perform the new UE selections */
1113 rgSCHSc1DlDedTx(cell, subFrm, allocInfo);
1115 /* Stack Crash problem for TRACE5 changes. Added the return below */
1120 * @brief This function implements scheduler DL allocation
1124 * Function: rgSCHSc1DlDedRetx
1125 * Purpose: This function implements scheduler for DL allocation for
1128 * Invoked by: Scheduler
1130 * @param[in] RgSchCellCb *cell
1131 * @param[out] RgSchCmnDlRbAllocInfo *allocInfo
1136 PRIVATE Void rgSCHSc1DlDedRetx
1139 RgSchCmnDlRbAllocInfo *allocInfo
1142 PRIVATE Void rgSCHSc1DlDedRetx(cell, allocInfo)
1144 RgSchCmnDlRbAllocInfo *allocInfo;
1147 RgSchDlSf *subFrm = allocInfo->dedAlloc.dedDlSf;
1149 Inst inst = cell->instIdx;
1151 TRC2(rgSCHSc1DlDedRetx);
1152 RGSCHDBGPRM(inst, (rgSchPBuf(inst), "rgSCHSc1DlDedRetx\n"));
1154 rgSCHSc1DlRetxAlloc(cell, subFrm, allocInfo);
1163 * @brief This function adds a service to scheduler
1167 * Function: rgSCHSc1DlSvcAddToSchd
1168 * Purpose: This function adds a service to the list of services
1169 * based on the priority of the services.
1171 * Invoked by: BO and Scheduler
1173 * @param[in] RgSchCellCb* cell
1174 * @param[in] RgSchUeCb* ue
1179 PRIVATE Void rgSCHSc1DlSvcAddToSchd
1185 PRIVATE Void rgSCHSc1DlSvcAddToSchd(cell, svc)
1193 RgSchSc1DlSvc *svcSc1;
1194 RgSchSc1DlSvc *lSvcSc1;
1195 RgSchSc1DlCell *sc1CellDl = RG_GET_SC1_CELL_DL(cell);
1196 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1198 TRC2(rgSCHSc1DlSvcAddToSchd);
1200 svcSc1 = RG_GET_SC1_SVC_DL(svc->ue,svc,cell);
1201 /* The service is already in the scheduler */
1202 if (svcSc1->prioLnk.node != NULLP)
1207 /* If the priority = 0, it is the highest priority with infinite */
1208 /* allowance and the priority is time bound and hence just place */
1209 /* it at the end of the queue */
1210 if (svcCmn->prio == 0)
1212 lst = &(sc1CellDl->prioLst[0]);
1213 cmLListAdd2Tail(lst, &svcSc1->prioLnk);
1214 svcSc1->prioLnk.node = (PTR)svc;
1215 /* If a svc is put in to cell wide priority Qs
1216 * then add the same to UE's lcsWithData List */
1217 rgSCHSc1DlAdd2UeLcsWithData(cell, svc->ue, svc);
1221 /* Handle GBR services. We have them of next importance */
1222 /* check changed from .._START to .._END */
1223 if (svcCmn->prio <= RG_SCH_SC1_DL_GBR_PRIO_END)
1225 if (!RG_SC1_SVC_HAS_DATA(svc,cell))
1227 lst = &(sc1CellDl->prioLst[svcCmn->prio]);
1231 lSvc = (RgSchDlLcCb *)(node->node);
1232 lSvcSc1 = RG_GET_SC1_SVC_DL(lSvc->ue,lSvc,cell);
1233 if (((svcSc1->effGbr > 0) &&
1234 (lSvcSc1->effGbr <= svcSc1->effGbr)) ||
1235 ((lSvcSc1->effGbr == 0) && (svcSc1->effMbr > 0) &&
1236 (lSvcSc1->effMbr <= svcSc1->effMbr)))
1244 /* We have come to the end of the queue. Let's place it */
1245 /* here irresepctive of effGbr or effMBr */
1246 cmLListAdd2Tail(lst, &svcSc1->prioLnk);
1247 svcSc1->prioLnk.node = (PTR)svc;
1252 cmLListInsCrnt(lst, &svcSc1->prioLnk);
1253 svcSc1->prioLnk.node = (PTR)svc;
1255 /* If a svc is put in to cell wide priority Qs
1256 * then add the same to UE's lcsWithData List */
1257 rgSCHSc1DlAdd2UeLcsWithData(cell, svc->ue, svc);
1265 * @brief This function removes a UE from scheduler Queue
1269 * Function: rgSCHSc1DlUeRmvFrmSchd
1270 * Purpose: This function removes a UE from the list of UEs
1271 * based on the priority of the UEs Current AMBR SVC.
1273 * Invoked by: BO and Scheduler
1275 * @param[in] RgSchCellCb* cell
1276 * @param[in] RgSchUeCb* ue
1281 PRIVATE Void rgSCHSc1DlUeRmvFrmSchd
1287 PRIVATE Void rgSCHSc1DlUeRmvFrmSchd(cell, ue)
1292 RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1293 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1296 TRC2(rgSCHSc1DlUeRmvFrmSchd);
1298 lst = &cellDl->prioLst[ueDl->prio];
1299 if (ueDl->prioLnk.node != NULLP)
1301 cmLListDelFrm(lst, &ueDl->prioLnk);
1302 ueDl->prioLnk.node = (PTR)NULLP;
1303 /* If a svc is removed from cell wide priority Qs
1304 * then remove the same from UE's lcsWithData List */
1305 rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, ueDl->ambrSvc);
1312 * @brief This function removes a SVC from UEs AMBR LIST
1316 * Function: rgSCHSc1DlSvcRmvFrmUeAmbrLst
1317 * Purpose: This function removes a SVC from UEs AMBR List.
1319 * Invoked by: BO and Scheduler
1321 * @param[in] RgSchUeCb* ue
1322 * @param[in] RgSchDlLcCb* svc
1327 PRIVATE Void rgSCHSc1DlSvcRmvFrmUeAmbrLst
1334 PRIVATE Void rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc)
1340 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1341 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1344 TRC2(rgSCHSc1DlSvcRmvFrmUeAmbrLst);
1346 lst = &ueDl->ambrLst;
1347 if (svcSc1->prioLnk.node != NULLP)
1349 cmLListDelFrm(lst, &svcSc1->prioLnk);
1350 svcSc1->prioLnk.node = (PTR)NULLP;
1357 * @brief This function adds a SVC to UEs AMBR LIST
1361 * Function: rgSCHSc1DlSvcAddToUeAmbrLst
1362 * Purpose: This function adds a SVC to UEs AMBR List.
1364 * Invoked by: BO and Scheduler
1366 * @param[in] RgSchUeCb* ue
1367 * @param[in] RgSchDlLcCb* svc
1372 PRIVATE Void rgSCHSc1DlSvcAddToUeAmbrLst
1379 PRIVATE Void rgSCHSc1DlSvcAddToUeAmbrLst(cell, ue, svc)
1385 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1388 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1389 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1391 TRC2(rgSCHSc1DlSvcAddToUeAmbrLst);
1393 /* If svc already present in AMBR List return */
1394 if (svcSc1->prioLnk.node != NULLP)
1397 node = ueDl->ambrLst.first;
1400 lsvc = (RgSchDlLcCb *)(node->node);
1401 if (((RgSchCmnDlSvc*)(lsvc->sch))->prio > svcCmn->prio)
1409 cmLListAdd2Tail(&ueDl->ambrLst, &svcSc1->prioLnk);
1410 svcSc1->prioLnk.node = (PTR)svc;
1414 ueDl->ambrLst.crnt = node;
1415 cmLListInsCrnt(&ueDl->ambrLst, &svcSc1->prioLnk);
1416 svcSc1->prioLnk.node = (PTR)svc;
1424 * @brief This function removes a service from scheduler
1428 * Function: rgSCHSc1DlSvcRmvFrmSchd
1429 * Purpose: This function removes the SVC from the scheduler Qs.
1431 * Invoked by: BO and Scheduler
1433 * @param[in] RgSchCellCb* cell
1434 * @param[in] RgSchUeCb* ue
1439 PRIVATE Void rgSCHSc1DlSvcRmvFrmSchd
1445 PRIVATE Void rgSCHSc1DlSvcRmvFrmSchd(cell, svc)
1450 RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1451 RgSchSc1DlSvc *svcDl = RG_GET_SC1_SVC_DL(svc->ue,svc,cell);
1452 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1455 TRC2(rgSCHSc1DlSvcRmvFrmSchd);
1457 lst = &(cellDl->prioLst[svcCmn->prio]);
1458 if (svcDl->prioLnk.node != NULLP)
1460 cmLListDelFrm(lst, &svcDl->prioLnk);
1461 svcDl->prioLnk.node = NULLP;
1462 /* If a svc is removed from cell wide priority Qs
1463 * then remove the same from UE's lcsWithData List */
1464 rgSCHSc1DlRmFrmUeLcsWithData(cell, svc->ue, svc);
1471 * @brief This function adds a service to scheduler for a UE
1475 * Function: rgSCHSc1DlSvcAdd
1476 * Purpose: This function is made available through a FP for
1477 * making scheduler aware of a service added to UE
1479 * Invoked by: BO and Scheduler
1481 * @param[in] RgSchUeCb* ue
1482 * @param[in] RgSchDlLcCb* svc
1483 * @param[in] CrgDlLchCfg* qos
1488 PRIVATE Void rgSCHSc1DlSvcAdd
1496 PRIVATE Void rgSCHSc1DlSvcAdd(cell, ue, svc, cfg)
1503 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1504 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1505 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1506 TRC2(rgSCHSc1DlSvcAdd);
1510 if (RG_SCH_CMN_SVC_IS_GBR(svc))
1512 svcSc1->gbr = svcCmn->gbr;
1513 svcSc1->mbr = svcCmn->mbr;
1514 cmLListAdd2Tail(&ueDl->gbrSvcs, &svcSc1->gbrLnk);
1515 svcSc1->gbrLnk.node = (PTR)svc;
1522 * @brief This function deletes a service from scheduler
1526 * Function: rgSCHSc1DlLcRmv
1527 * Purpose: This function is made available through a FP for
1528 * making scheduler aware of a service being deleted from UE
1530 * Invoked by: BO and Scheduler
1532 * @param[in] RgSchCellCb* cell
1533 * @param[in] RgSchUeCb* ue
1534 * @param[in] RgSchDlLcCb* svc
1539 PUBLIC Void rgSCHSc1DlLcRmv
1546 PUBLIC Void rgSCHSc1DlLcRmv(cell, ue, svc)
1553 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1554 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1556 TRC2(rgSCHSc1DlLcRmv);
1558 if (svcSc1 == NULLP)
1562 ueDl = RG_GET_SC1_UE_DL(ue, cell);
1564 if (svcCmn->prio == 0)
1566 rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1568 else if (RG_SCH_CMN_SVC_IS_GBR(svc))
1570 if (svcSc1->gbrLnk.node != NULLP)
1572 cmLListDelFrm(&ueDl->gbrSvcs, &svcSc1->gbrLnk);
1573 svcSc1->gbrLnk.node = NULLP;
1575 rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1577 else /* if AMBR service */
1579 if (ueDl->ambrSvc == svc)
1581 rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1582 rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1583 ueDl->ambrSvc = NULLP;
1584 if (ueDl->ambrLst.first != NULLP)
1586 ueDl->ambrSvc = (RgSchDlLcCb *)(ueDl->ambrLst.first->node);
1587 ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svc->bo);
1590 rgSCHSc1DlUeAddToSchd(cell, ue);
1596 rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1599 /* ccpu00117052 - MOD - Passing double pointer
1600 for proper NULLP assignment*/
1601 rgSCHUtlFreeSBuf(cell->instIdx,
1602 (Data**)(&(RG_SCH_CMN_GET_LC_SCH_SPFC(ue,svc,cell))), (sizeof(RgSchSc1DlSvc)));
1607 * @brief This function is invoked as part of SVC reconfig
1611 * Function: rgSCHSc1DlSvcMod
1612 * Purpose: This function is made available through a FP for
1613 * making scheduler aware of a service reconfiguration.
1615 * Invoked by: Scheduler
1617 * @param[in] RgSchDlLcCb* svc
1618 * @param[in] CrgLchRecfg* recfg
1623 PRIVATE Void rgSCHSc1DlSvcMod
1631 PRIVATE Void rgSCHSc1DlSvcMod(cell,ue,svc, recfg)
1638 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1639 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1640 TRC2(rgSCHSc1DlSvcMod);
1642 if (RG_SCH_CMN_SVC_IS_GBR(svc))
1644 /* Convert the QOS to handle the refresh duration */
1645 svcSc1->gbr = svcCmn->gbr;
1646 svcSc1->mbr = svcCmn->mbr;
1652 * @brief This function adds UE to scheduler for an AMBR service
1656 * Function: rgSCHSc1DlUeAddToSchd
1657 * Purpose: This function adds a UE to scheduler for the AMBR
1658 * service of highest priority.
1660 * Invoked by: BO and Scheduler
1662 * @param[in] RgSchCellCb* cell
1663 * @param[in] RgSchUeCb* ue
1668 PRIVATE Void rgSCHSc1DlUeAddToSchd
1674 PRIVATE Void rgSCHSc1DlUeAddToSchd(cell, ue)
1679 RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1680 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1681 RgSchSc1DlUe *lueDl;
1684 RgSchUeCb *nodeUe = NULLP;
1685 TRC2(rgSCHSc1DlUeAddToSchd);
1687 ueDl->prio = ((RgSchCmnDlSvc *)(ueDl->ambrSvc->sch))->prio;
1688 lst = &cellDl->prioLst[ueDl->prio];
1689 /* if UE already in list, remove and
1691 if (ueDl->prioLnk.node != NULLP)
1693 cmLListDelFrm(lst, &ueDl->prioLnk);
1694 ueDl->prioLnk.node = NULLP;
1695 /* If a svc is removed from cell wide priority Qs
1696 * then remove the same from UE's lcsWithData List */
1697 rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, ueDl->ambrSvc);
1702 nodeUe = (RgSchUeCb *)(node->node);
1703 lueDl = RG_GET_SC1_UE_DL(nodeUe, cell);
1704 if (lueDl->effAmbr < ueDl->effAmbr)
1710 cmLListAdd2Tail(lst, &ueDl->prioLnk);
1711 ueDl->prioLnk.node = (PTR)ue;
1716 cmLListInsCrnt(lst, &ueDl->prioLnk);
1717 ueDl->prioLnk.node = (PTR)ue;
1719 /* If a svc is put in to cell wide priority Qs
1720 * then add the same to UE's lcsWithData List */
1721 rgSCHSc1DlAdd2UeLcsWithData(cell, ue, ueDl->ambrSvc);
1727 * @brief This function implements managing BO for an ABMR service
1731 * Function: rgSCHSc1DlMngAmbrSvcPosn
1732 * Purpose: This function should be called whenever there is a
1733 * change BO for a AMBR service.
1735 * Invoked by: BO and Scheduler
1737 * @param[in] RgSchCellCb* cell
1738 * @param[in] RgSchUeCb* ue
1739 * @param[in] RgSchDlLcCb* svc
1744 PRIVATE Void rgSCHSc1DlMngAmbrSvcPosn
1751 PRIVATE Void rgSCHSc1DlMngAmbrSvcPosn(cell, ue, svc)
1757 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1758 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1760 TRC2(rgSCHSc1DlMngAmbrSvcPosn);
1762 if (svcSc1->bo == 0)
1764 if (ueDl->ambrSvc == svc)
1766 rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1767 rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1768 ueDl->ambrSvc = NULLP;
1769 if (ueDl->ambrLst.first != NULLP)
1771 ueDl->ambrSvc = (RgSchDlLcCb *)(ueDl->ambrLst.first->node);
1772 ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svcSc1->bo);
1775 rgSCHSc1DlUeAddToSchd(cell, ue);
1781 rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1784 else /* svcSc1->bo != 0 */
1786 if (svcSc1->prioLnk.node != NULLP)
1788 if (svc == ueDl->ambrSvc)
1790 ueDl->effAmbr = RGSCH_MIN(svcSc1->bo, ueDl->ambr);
1791 /* Update UE's position in the scheduler */
1794 rgSCHSc1DlUeAddToSchd(cell, ue);
1798 rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1803 rgSCHSc1DlSvcAddToUeAmbrLst(cell, ue, svc);
1804 /* Current ambr svc is always the first node of ambrLst.*/
1805 if (ueDl->ambrLst.first->node == (PTR)svc)
1807 if(ueDl->ambrSvc != svc)
1811 rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1813 ueDl->ambrSvc = svc;
1814 ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svcSc1->bo);
1817 rgSCHSc1DlUeAddToSchd(cell, ue);
1827 * @brief This function updates the scheduler with service for a UE
1831 * Function: rgSCHSc1DlLcBoUpd
1832 * Purpose: This function should be called whenever there is a
1833 * change BO for a service.
1835 * Invoked by: BO and Scheduler
1837 * @param[in] RgSchCellCb* cell
1838 * @param[in] RgSchUeCb* ue
1839 * @param[in] RgSchDlLcCb* svc
1844 PUBLIC Void rgSCHSc1DlLcBoUpd
1851 PUBLIC Void rgSCHSc1DlLcBoUpd(cell, ue, svc)
1857 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1858 TRC2(rgSCHSc1DlLcBoUpd);
1860 if (svcSc1->bo == svc->bo)
1864 svcSc1->bo = svc->bo;
1865 if (!RG_SCH_CMN_DL_IS_UE_ACTIVE(ue))
1869 rgSCHSc1DlMngSvcPosn(cell, ue, svc);
1871 /* Stack Crash problem for TRACE5 changes. Added the return below */
1878 * @brief This function updates the scheduler with Prio0 service for a UE
1882 * Function: rgSCHSc1DlMngPrio0SvcPosn
1883 * Purpose: This func shall be triggered whenever there is a
1884 * change in the "Bo yet to be satisfied" field of the service.
1885 * Appropriately positions the svc in its prio Q.
1886 * Removes the SVC from the Q if BO is completely satisfied.
1888 * Invoked by: BO and Scheduler
1890 * @param[in] RgSchCellCb* cell
1891 * @param[in] RgSchUeCb* ue
1892 * @param[in] RgSchDlLcCb* svc
1897 PRIVATE Void rgSCHSc1DlMngPrio0SvcPosn
1904 PRIVATE Void rgSCHSc1DlMngPrio0SvcPosn(cell, ue, svc)
1910 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1911 TRC2(rgSCHSc1DlMngPrio0SvcPosn);
1913 /* In this priority, we just add or remove to the queue */
1916 rgSCHSc1DlSvcAddToSchd(cell, svc);
1920 rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1927 * @brief This function updates the scheduler with GBR service for a UE
1931 * Function: rgSCHSc1DlMngGbrSvcPosn
1932 * Purpose: This func shall be triggered whenever there is a
1933 * change in the "Bo yet to be satisfied" field of the service.
1934 * Appropriately positions the svc in its prio Q.
1935 * Removes the SVC from the Q if BO is completely satisfied.
1937 * Invoked by: BO and Scheduler
1939 * @param[in] RgSchCellCb* cell
1940 * @param[in] RgSchUeCb* ue
1941 * @param[in] RgSchDlLcCb* svc
1946 PRIVATE Void rgSCHSc1DlMngGbrSvcPosn
1953 PRIVATE Void rgSCHSc1DlMngGbrSvcPosn(cell, ue, svc)
1959 RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1960 TRC2(rgSCHSc1DlMngGbrSvcPosn);
1962 /* Handle a GBR service. */
1963 svcSc1->effGbr = RGSCH_MIN(svcSc1->bo, svcSc1->gbr);
1964 svcSc1->effMbr = RGSCH_MIN(svcSc1->bo, svcSc1->mbr);
1965 /* Adjust the SVC priority within the queue */
1966 rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1967 rgSCHSc1DlSvcAddToSchd(cell, svc);
1973 * @brief This function updates the scheduler with service for a UE
1977 * Function: rgSCHSc1DlMngSvcPosn
1978 * Purpose: This func shall be triggered whenever there is a
1979 * change in the "Bo yet to be satisfied" field of the service.
1980 * Appropriately positions the svc in its prio Q.
1981 * Removes the SVC from the Q if BO is completely satisfied.
1983 * Invoked by: BO and Scheduler
1985 * @param[in] RgSchCellCb* cell
1986 * @param[in] RgSchUeCb* ue
1987 * @param[in] RgSchDlLcCb* svc
1992 PRIVATE Void rgSCHSc1DlMngSvcPosn
1999 PRIVATE Void rgSCHSc1DlMngSvcPosn(cell, ue, svc)
2005 RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
2006 RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
2007 TRC2(rgSCHSc1DlMngSvcPosn);
2009 (cellDl->svcMngFunc[svcCmn->prio])(cell, ue, svc);
2013 /*--------------------------*
2014 * DL specific functions END
2015 *---------------------------*/
2020 * @brief Scheduler processing on cell configuration
2024 * Function : rgSCHSc1RgrDlCellCfg
2026 * This function does requisite initialisation
2027 * and setup for scheduler1 when a cell is
2030 * @param[in] RgSchCellCb *cell
2031 * @param[in] RgrCellCfg *cellCfg
2032 * @param[out] RgSchErrInfo *err
2038 PUBLIC S16 rgSCHSc1RgrDlCellCfg
2041 RgrCellCfg *cellCfg,
2045 PUBLIC S16 rgSCHSc1RgrDlCellCfg(cell, cellCfg, err)
2047 RgrCellCfg *cellCfg;
2052 RgSchSc1DlCell *cellDl;
2054 TRC2(rgSCHSc1RgrDlCellCfg);
2056 if((ret = rgSCHUtlAllocSBuf(cell->instIdx,
2057 (Data**)&(((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc), \
2058 (sizeof(RgSchSc1DlCell)))) != ROK)
2060 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
2061 "Memory allocation FAILED");
2062 err->errCause = RGSCHERR_SCH_SC1_DL_CFG;
2066 cellDl = RG_GET_SC1_CELL_DL(cell);
2067 /* Now perform downlink Queues related initializations */
2068 rgSCHSc1DlInitQueues(cellDl);
2070 } /* rgSCHSc1RgrDlCellCfg */
2072 /***********************************************************
2074 * Func : rgSCHSc1DlDeinitQueues
2076 * Desc : De-initialise downlink scheduler queues
2084 **********************************************************/
2086 PRIVATE Void rgSCHSc1DlDeinitQueues
2088 RgSchSc1DlCell *cellDl
2091 PRIVATE Void rgSCHSc1DlDeinitQueues(cellDl)
2092 RgSchSc1DlCell *cellDl;
2096 TRC2(rgSCHSc1DlDeinitQueues);
2098 for (i = 0; i < RG_SC1_DL_NUM_Q; ++i)
2100 cmLListInit(&cellDl->prioLst[i]);
2101 cmLListInit(&cellDl->retxLst[i]);
2108 * @brief Scheduler processing for cell delete
2112 * Function : rgSCHSc1DlCellDel
2114 * This functions de-initialises and frees memory
2115 * taken up by scheduler1 for the entire cell.
2117 * @param[in] RgSchCellCb *cell
2121 PUBLIC Void rgSCHSc1DlCellDel
2126 PUBLIC Void rgSCHSc1DlCellDel(cell)
2130 TRC2(rgSCHSc1DlCellDel);
2132 if (((RgSchSc1DlCell *)((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc) \
2138 /* Perform the deinit for the DL scheduler */
2139 rgSCHSc1DlDeinitQueues(RG_GET_SC1_CELL_DL(cell));
2140 /* ccpu00117052 - MOD - Passing double pointer
2141 for proper NULLP assignment*/
2142 rgSCHUtlFreeSBuf(cell->instIdx,
2143 (Data**)(&(((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc)),
2144 (sizeof(RgSchSc1DlCell)));
2146 } /* rgSCHSc1DlCellDel */
2149 * @brief UE initialisation for scheduler
2153 * Function : rgSCHSc1RgrDlUeCfg
2155 * This functions intialises UE specific scheduler
2158 * @param[in] RgSchCellCb *cell
2159 * @param[in] RgSchUeCb *ue
2160 * @param[int] RgrUeCfg *ueCfg
2161 * @param[out] RgSchErrInfo *err
2167 PUBLIC S16 rgSCHSc1RgrDlUeCfg
2175 PUBLIC S16 rgSCHSc1RgrDlUeCfg(cell, ue, ueCfg, err)
2182 RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue, cell);
2183 Inst inst = cell->instIdx;
2186 TRC2(rgSCHSc1RgrDlUeCfg);
2188 if((rgSCHUtlAllocSBuf(inst,
2189 (Data**)&(ueSchCmn->dl.schSpfc), (sizeof(RgSchSc1DlUe))) != ROK))
2191 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId, "Memory allocation FAILED"
2192 "CRNTI:%d",ue->ueId);
2193 err->errCause = RGSCHERR_SCH_SC1_DL_CFG;
2196 ueDl = (RgSchSc1DlUe *)ueSchCmn->dl.schSpfc;
2197 if (ue->dl.ambrCfgd)
2199 ueDl->ambr = ue->dl.ambrCfgd;
2203 ueDl->ambr = RG_SC1_MAX_DL_AMBR;
2205 cmLListInit(&ueDl->lcsWithData);
2206 cmLListInit(&ueDl->gbrSvcs);
2207 cmLListInit(&ueDl->ambrLst);
2208 cmLListInit(&ueDl->schdSvcs);
2209 cmLListInit(&ueDl->retxHqProcs);
2211 } /* rgSCHSc1RgrDlUeCfg */
2215 * @brief Dl Harq Entity initialization for SC1
2219 * Function : rgSCHSc1DlUeHqEntInit
2222 * - Create SC1 related information per Harq Entity
2224 * @param[in] RgrSchCellCb *cell
2225 * @param[in] RgSchUeCb *ue
2231 PUBLIC S16 rgSCHSc1DlUeHqEntInit
2237 PUBLIC S16 rgSCHSc1DlUeHqEntInit(cell, hqEnt)
2242 RgSchSc1DlHqProc *hqSpcSch;
2243 RgSchDlHqProcCb *hqP;
2245 TRC2(rgSCHSc1DlUeHqEntInit);
2246 /* making use of hqE->sch for one shot allocation
2247 * of RgSchSc1DlHqProc structures */
2248 if (rgSCHUtlAllocSBuf(cell->instIdx,
2249 (Data**)&(hqEnt->sch),
2250 (hqEnt->numHqPrcs * sizeof(RgSchSc1DlHqProc))) != ROK)
2252 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
2253 "Memory allocation FAILED CRNTI:%d",hqEnt->ue->ueId);
2256 hqSpcSch = (RgSchSc1DlHqProc *)(hqEnt->sch);
2257 for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++)
2259 hqP = &hqEnt->procs[cnt];
2260 ((RgSchCmnDlHqProc *)((hqP)->sch))->schSpfc = \
2267 * @brief Dl Harq Entity deletion for Sc1
2271 * Function : rgSCHSc1DlUeHqEntDeInit
2274 * - Free SC1 related information per Harq Entity
2276 * @param[in] RgrSchCellCb *cell
2277 * @param[in] RgSchDlHqEnt *hqE
2281 PUBLIC S16 rgSCHSc1DlUeHqEntDeInit
2287 PUBLIC S16 rgSCHSc1DlUeHqEntDeInit(cell, hqE)
2292 TRC2(rgSCHSc1DlUeHqEntDeInit);
2296 rgSCHUtlFreeSBuf(cell->instIdx,
2297 (Data**)(&(hqE->sch)),
2298 (hqE->numHqPrcs * sizeof(RgSchSc1DlHqProc)));
2307 * @brief UE reconfiguration for scheduler
2311 * Function : rgSCHSc1RgrDlUeRecfg
2313 * This functions updates UE specific scheduler
2314 * information upon UE reconfiguration
2316 * @param[in] RgSchCellCb *cell
2317 * @param[in] RgSchUeCb *ue
2318 * @param[int] RgrUeRecfg *ueRecfg
2319 * @param[out] RgSchErrInfo *err
2325 PUBLIC S16 rgSCHSc1RgrDlUeRecfg
2329 RgrUeRecfg *ueRecfg,
2333 PUBLIC S16 rgSCHSc1RgrDlUeRecfg(cell, ue, ueRecfg, err)
2336 RgrUeRecfg *ueRecfg;
2340 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
2341 RgSchCmnDlUe *ueCmnDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
2342 /*cell added as part of CA dev*/
2343 RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
2344 TRC2(rgSCHSc1RgrDlUeRecfg);
2346 if (ue->dl.ambrCfgd)
2348 ueDl->ambr = ue->dl.ambrCfgd;
2352 ueDl->ambr = RG_SC1_MAX_DL_AMBR;
2355 /* Discarding TB2's context from scheduling Queues.
2356 * Since TB2 transmission needs signalling using
2357 * TM specific formats. And since during this transient
2358 * period of UE TM Recfg, SCH always uses Format 1A,
2359 * the TB2s are discarded. */
2360 if (ueCmnDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG)
2362 /* If HqP is in retx queue only for TB2 retx scheduling
2363 * then remove the harp proc from retx Queue */
2365 /* If Hqp is in retx queue for retx allocation of
2366 * both TB1 and TB2, then reset TB2's state as ACKED */
2367 RgSchDlHqProcCb *hqP;
2369 RgInfRlsHqInfo *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]);
2372 /* Prepare TB2 release information to be sent to MAC */
2373 rlsHqBufs->numUes = 0;
2374 for(i = 0; i < hqEnt->numHqPrcs; i++)
2376 hqP = &hqEnt->procs[i];
2377 rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = ue->ueId;
2378 rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = hqP->procId;
2379 if (hqP->tbInfo[1].state == HQ_TB_NACKED)
2381 if (hqP->tbInfo[0].state != HQ_TB_NACKED)
2383 /* Remove the HqP from retx Queue.
2385 rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
2386 rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
2388 rgSCHDhmRlsHqpTb(hqP, 1, TRUE);
2389 rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[0] = 2;
2390 rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 1;
2392 rlsHqBufs->numUes++;
2394 /* Send the hqProc list for MAC to clear TB1 contents */
2395 if (rlsHqBufs->numUes)
2397 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
2398 RgSchMacRlsHq (&pst, rlsHqBufs);
2402 } /* rgSCHSc1RgrDlUeRecfg */
2405 * @brief Removes UEs context from Priority Qs.
2409 * Function : rgSCHSc1DlRmvUeFrmPrioQs
2412 * @param[in] RgSchCellCb *cell
2413 * @param[in] RgSchUeCb *ue
2417 PRIVATE Void rgSCHSc1DlRmvUeFrmPrioQs
2423 PRIVATE Void rgSCHSc1DlRmvUeFrmPrioQs(cell, ue)
2428 RgSchSc1DlUe *sc1Ue;
2432 TRC2(rgSCHSc1DlRmvUeFrmPrioQs);
2434 sc1Ue = RG_GET_SC1_UE_DL(ue, cell);
2436 /* Remove UE From DL priority queues */
2437 if (sc1Ue->ambrSvc != NULLP)
2439 rgSCHSc1DlUeRmvFrmSchd(cell, ue);
2442 for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx)
2444 svc = ue->dl.lcCb[idx];
2449 rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
2453 } /* rgSCHSc1DlRmvUeFrmPrioQs */
2456 * @brief Inactivate UE reason : measgap, acknaprept, poInactv.
2460 * Function : rgSCHSc1DlInactvtUe
2463 * @param[in] RgSchCellCb *cell
2464 * @param[in] RgSchUeCb *ue
2468 PRIVATE Void rgSCHSc1DlInactvtUe
2474 PRIVATE Void rgSCHSc1DlInactvtUe(cell, ue)
2479 RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
2480 RgSchDlHqProcCb *hqP;
2481 RgSchCmnDlHqProc *hqProcDl;
2483 RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
2485 TRC2(rgSCHSc1DlInactvtUe);
2487 /* ccpu00130170: UE related HARQ Procs are cleared only
2488 if UE's Re-establishment procedure is not in progress*/
2489 if(!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE))
2491 /* remove all in use HARQ processes from the subframes.
2492 * Store them in UEs hqProc Lst. Add back to cell's
2493 * retx lst when UE is activated again. */
2494 for(i = 0; i < hqEnt->numHqPrcs; i++)
2496 hqP = &hqEnt->procs[i];
2497 hqProcDl = RG_SCH_CMN_GET_DL_HQP(hqP);
2498 /* Remove retx procs from cell's list and
2499 * add them to UE's List */
2502 !(RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)) &&
2504 hqProcDl->retxLnk.node != NULLP)
2506 cmLListDelFrm(&cellDl->retxLst[((RgSchSc1DlHqProc *)\
2507 (hqProcDl->schSpfc))->prio], &(hqProcDl->retxLnk));
2508 hqProcDl->retxLnk.node = NULLP;
2509 rgSCHSc1DlProcAddToUeRetx(cell, ue, hqP);
2514 rgSCHSc1DlRmvUeFrmPrioQs(cell, ue);
2517 } /* rgSCHSc1DlInactvtUe */
2521 * @brief UE suspension.
2525 * Function : rgSCHSc1DlSuspendUe
2527 * Removes UE, its SVCs and its HqPs from CELL WIDE
2528 * PrioQs and Retx Qs Respectively.
2530 * @param[in] RgSchCellCb *cell
2531 * @param[in] RgSchUeCb *ue
2535 PRIVATE Void rgSCHSc1DlSuspendUe
2541 PRIVATE Void rgSCHSc1DlSuspendUe(cell, ue)
2546 RgSchDlHqProcCb *hqP;
2549 RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
2551 TRC2(rgSCHSc1DlSuspendUe);
2553 /* remove all in use HARQ processes from the subframes.
2554 * Store them in UEs hqProc Lst. Add back to cell's
2555 * retx lst when UE is activated again. */
2556 for(i = 0; i < hqEnt->numHqPrcs; i++)
2558 hqP = &hqEnt->procs[i];
2559 rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
2560 rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
2561 /* Removing the Harq Proc from subframes list */
2562 if (hqP->hqPSfLnk.node != NULLP)
2566 cmLListDelFrm(&hqP->subFrm->pdcchInfo.pdcchs,
2568 cmLListAdd2Tail(&cell->pdcchLst, &hqP->pdcch->lnk);
2572 rgSCHUtlDlHqPTbRmvFrmTx(hqP->subFrm,hqP,0,FALSE);
2574 for (j = 0; j < 2; j++)
2576 if (hqP->tbInfo[j].state == HQ_TB_WAITING)
2578 rgSCHDhmRlsHqpTb(hqP, j, TRUE);
2583 rgSCHSc1DlRmvUeFrmPrioQs(cell, ue);
2586 } /* rgSCHSc1DlSuspendUe */
2588 /***********************************************************
2590 * Func : rgSCHSc1DlScanUpdPdbPrio
2592 * Desc : Increment the pivot and reposition the LCs under the pivot to
2593 * new location according to thieir PDB and elapsed time.
2601 **********************************************************/
2603 PUBLIC Void rgSCHSc1DlScanUpdPdbPrio
2608 PUBLIC Void rgSCHSc1DlScanUpdPdbPrio (cell)
2612 TRC2(rgSCHSc1DlScanUpdPdbPrio);
2618 * @brief Function to update Flow control information
2619 * to be sent to MAC.
2623 * Function: rgSCHSc1DlFillFlowCntrlInfo
2625 * update Flow control information
2632 * @param[in] RgSchCellCb *cell
2633 RgInfSfAlloc *sfAlloc;
2638 PUBLIC S16 rgSCHSc1DlFillFlowCntrlInfo
2641 RgInfSfAlloc *sfAlloc
2644 PUBLIC S16 rgSCHSc1DlFillFlowCntrlInfo(cell,sfAlloc)
2646 RgInfSfAlloc *sfAlloc;
2649 TRC2(rgSCHSc1DlFillFlowCntrlInfo);
2653 * @brief UE deletion for scheduler
2657 * Function : rgSCHSc1DlUeDel
2659 * This functions deletes all scheduler information
2660 * pertaining to a UE
2662 * @param[in] RgSchCellCb *cell
2663 * @param[in] RgSchUeCb *ue
2667 PUBLIC Void rgSCHSc1DlUeDel
2673 PUBLIC Void rgSCHSc1DlUeDel(cell, ue)
2678 RgSchDlHqEnt *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
2679 RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
2681 TRC2(rgSCHSc1DlUeDel);
2683 if (sc1DlUe == NULLP)
2689 /* Remove UEs scheduler context */
2690 rgSCHSc1DlSuspendUe(cell, ue);
2692 /* Free all SC1 specific control blocks */
2693 if (hqEnt->sch != NULLP)
2695 /* ccpu00117052 - MOD - Passing double pointer
2696 for proper NULLP assignment*/
2697 rgSCHUtlFreeSBuf(cell->instIdx,
2698 (Data**)(&(hqEnt->sch)),
2699 (hqEnt->numHqPrcs * sizeof(RgSchSc1DlHqProc)));
2703 /* ccpu00117052 - MOD - Passing double pointer
2704 for proper NULLP assignment*/
2705 rgSCHUtlFreeSBuf(cell->instIdx, (Data**)(&sc1DlUe), (sizeof(RgSchSc1DlUe)));
2708 } /* rgSCHSc1DlUeDel */
2711 * @brief Scheduler invocation on Downlink logical channel addition
2715 * Function : rgSCHSc1RgrLcCfg
2717 * This functions does required processing when a new
2718 * (dedicated) logical channel is added.
2720 * @param[in] RgSchCellCb *cell
2721 * @param[in] RgSchUeCb *ue
2722 * @param[in] RgSchDlLcCb *dlLc
2723 * @param[int] RgrLchCfg *lcCfg
2724 * @param[out] RgSchErrInfo *err
2730 PUBLIC S16 rgSCHSc1RgrLcCfg
2739 PUBLIC S16 rgSCHSc1RgrLcCfg(cell, ue, dlLc, lcCfg, err)
2748 TRC2(rgSCHSc1RgrLcCfg);
2750 ret = rgSCHUtlAllocSBuf(cell->instIdx,
2751 (Data**)&(RG_SCH_CMN_GET_LC_SCH_SPFC(ue,dlLc,cell)), \
2752 (sizeof(RgSchSc1DlSvc)));
2755 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId, "rgSCHSc1CrgLcCfg():"
2756 "SCH struct alloc failed CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
2757 err->errCause = RGSCHERR_SCH_SC1_DL_CFG;
2761 rgSCHSc1DlSvcAdd(cell, ue, dlLc, &lcCfg->dlInfo);
2763 } /* rgSCHSc1RgrLcCfg */
2767 * @brief Scheduler invocation on logical channel addition
2771 * Function : rgSCHSc1RgrLcRecfg
2773 * This functions does required processing when an existing
2774 * (dedicated) logical channel is reconfigured. Assumes lcg
2775 * pointer in ulLc is set to the old value.
2776 * Independent of whether new LCG is meant to be configured,
2777 * the new LCG scheduler info is accessed and possibly modified.
2779 * @param[in] RgSchCellCb *cell
2780 * @param[in] RgSchUeCb *ue
2781 * @param[in] RgSchDlLcCb *dlLc
2782 * @param[int] RgrLchRecfg *lcRecfg
2783 * @param[out] RgSchErrInfo *err
2789 PUBLIC S16 rgSCHSc1RgrLcRecfg
2794 RgrLchRecfg *lcRecfg,
2798 PUBLIC S16 rgSCHSc1RgrLcRecfg(cell, ue, dlLc, lcRecfg, err)
2802 RgrLchRecfg *lcRecfg;
2806 TRC2(rgSCHSc1RgrLcRecfg);
2810 rgSCHSc1DlSvcMod(cell,ue,dlLc, lcRecfg);
2813 } /* rgSCHSc1RgrLcRecfg */
2817 * @brief This function handles the reconfiguration of cell
2821 * Function: rgSCHSc1RgrDlCellRecfg
2822 * Purpose: Update the reconfiguration parameters.
2824 * Invoked by: Scheduler
2826 * @param[in] RgSchCellCb* cell
2831 PRIVATE S16 rgSCHSc1RgrDlCellRecfg
2834 RgrCellRecfg *recfg,
2838 PRIVATE S16 rgSCHSc1RgrDlCellRecfg(cell, recfg, err)
2840 RgrCellRecfg *recfg;
2844 TRC2(rgSCHSc1DlUeReset);
2851 * @brief This function implements scheduler DL allocation
2855 * Function: rgSCHSc1DlTaCmd
2856 * Purpose: This function implements scheduler for TA cmd alloc for
2857 * UEs. The hq proc availed as part of this alloc can be used
2858 * by the UEs Dedicated CH transmission allocation.
2860 * Invoked by: Scheduler
2862 * @param[in] RgSchCellCb* cell
2863 * @param[out] RgSchCmnDlRbAllocInfo *allocInfo
2868 PRIVATE Void rgSCHSc1DlTaCmd
2871 RgSchCmnDlRbAllocInfo *allocInfo
2874 PRIVATE Void rgSCHSc1DlTaCmd(cell, allocInfo)
2876 RgSchCmnDlRbAllocInfo *allocInfo;
2881 RgSchDlHqProcCb *proc;
2884 RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
2885 RgSchCmnDlUe *cmnUeDl;
2887 RgSchCmnDlHqProc *cmnHqDl;
2888 RgSchDlSf *subFrm = allocInfo->dedAlloc.dedDlSf;
2890 Bool dlAllowed = FALSE;
2892 TRC2(rgSCHSc1DlTaCmd);
2894 lst = &cellCmnDl->taLst;
2898 ue = (RgSchUeCb *)node->node;
2903 rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed);
2904 if (dlAllowed == FALSE)
2910 /* If Ue is inactive in DL then ignore */
2911 if (ue->dl.dlInactvMask)
2915 cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
2916 /*cell added as part of CA dev*/
2917 ueDl = RG_GET_SC1_UE_DL(ue, cell);
2919 if (rgSCHDhmGetAvlHqProc(cell, ue, cellCmnDl->time, &proc) != ROK)
2923 /* Initialize some of the parameters of the HQ proc */
2924 cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc);
2928 cmnHqDl->totBytes = 0;
2929 rgSCHCmnDlAllocTxRb(cell, subFrm, ue, RGSCH_TA_SIZE, &effBo, proc, allocInfo);
2932 /* If no allocations so far, meaning proc obtained now */
2933 if (cmnHqDl->totBytes == 0)
2935 rgSCHSc1RlsHqProc(proc);
2936 /* Added the handling for removing
2937 * UE from txHqPLst and resetting outStndalloc.*/
2938 if(proc->reqLnk.node != (PTR)NULLP)
2940 cmLListDelFrm(&allocInfo->dedAlloc.txHqPLst, &proc->reqLnk);
2941 proc->reqLnk.node = (PTR)NULLP;
2943 /*Re-set the outstanding alloc information.*/
2944 cmnUeDl->outStndAlloc = 0;
2946 /* Avl BW could not satisfy even TA so break */
2949 ueDl->taReqBytes = RGSCH_TA_SIZE;
2950 cmnUeDl->proc = proc;
2951 cmnHqDl->totBytes += effBo;
2952 /* 3.1 MIMO moving this call to cmn scheduler */
2953 /*rgSCHCmnDlRbInfoAddUeTx(allocInfo, ue);*/
2959 * @brief Scheduler invocation
2963 * Function: rgSCHSc1DlHndlInActUes
2964 * Purpose: The list of inactive UEs present in inactvLst should
2965 * be removed from the scheduling Qs.
2967 * Invoked by: Common Scheduler (TTI processing)
2969 * @param[in] RgSchCellCb *cell
2970 * @param[out] CmLListCp *inactvLst
2974 PUBLIC Void rgSCHSc1DlHndlInActUes
2977 CmLListCp *inactvLst
2980 PUBLIC Void rgSCHSc1DlHndlInActUes(cell, inactvLst)
2982 CmLListCp *inactvLst;
2988 TRC2(rgSCHSc1DlHndlInActUes);
2990 node = inactvLst->first;
2993 ue = (RgSchUeCb *)node->node;
2995 /* Suspend this UE from further scheduling
2996 * till it is activated again. */
2997 rgSCHSc1DlInactvtUe(cell, ue);
3003 * @brief This function initializes all the data for the scheduler
3007 * Function: rgSCHSc1DlInit
3008 * Purpose: This function initializes the following information
3009 * 1. Efficiency table
3010 * 2. CQI to table index - It is one row for upto 3 RBs
3011 * and another row for greater than 3 RBs
3013 * currently extended prefix is compiled out.
3014 * Invoked by: MAC intialization code..may be ActvInit
3020 PUBLIC Void rgSCHSc1DlInit
3022 RgDlSchdApis *rgSchDlApis
3025 PUBLIC Void rgSCHSc1DlInit(rgSchDlApis)
3026 RgDlSchdApis *rgSchDlApis;
3029 TRC2(rgSCHSc1DlInit);
3030 /* Init the function pointers */
3031 rgSchDlApis->rgSCHRgrDlUeCfg = rgSCHSc1RgrDlUeCfg;
3032 rgSchDlApis->rgSCHRgrDlUeRecfg = rgSCHSc1RgrDlUeRecfg;
3033 rgSchDlApis->rgSCHFreeDlUe = rgSCHSc1DlUeDel;
3034 rgSchDlApis->rgSCHRgrDlCellCfg = rgSCHSc1RgrDlCellCfg;
3035 rgSchDlApis->rgSCHRgrDlCellRecfg = rgSCHSc1RgrDlCellRecfg;
3036 rgSchDlApis->rgSCHFreeDlCell = rgSCHSc1DlCellDel;
3037 rgSchDlApis->rgSCHRgrDlLcCfg = rgSCHSc1RgrLcCfg;
3038 rgSchDlApis->rgSCHRgrDlLcRecfg = rgSCHSc1RgrLcRecfg;
3039 rgSchDlApis->rgSCHFreeDlLc = rgSCHSc1DlLcRmv;
3040 rgSchDlApis->rgSCHDlNewSched = rgSCHSc1DlDedNewTx;
3041 rgSchDlApis->rgSCHDlPreSched = rgSCHSc1DlPreSchd;
3042 rgSchDlApis->rgSCHDlPstSched = rgSCHSc1DlPstSchd;
3043 rgSchDlApis->rgSCHDlRetxSched = rgSCHSc1DlDedRetx;
3044 rgSchDlApis->rgSCHDlCeSched = rgSCHSc1DlTaCmd;
3045 rgSchDlApis->rgSCHDlDedBoUpd = rgSCHSc1DlLcBoUpd;
3046 rgSchDlApis->rgSCHDlProcAddToRetx = rgSCHSc1DlProcAddToCellRetx;
3047 rgSchDlApis->rgSCHDlAllocFnlz = rgSCHSc1DlAllocFnlz;
3048 rgSchDlApis->rgSCHDlCqiInd = rgSCHSc1DlCqiInd;
3049 rgSchDlApis->rgSCHDlUeRefresh = rgSCHSc1DlUeRefresh;
3050 rgSchDlApis->rgSCHDlUeReset = rgSCHSc1DlUeReset;
3051 rgSchDlApis->rgSCHDlActvtUe = rgSCHSc1DlActvtUe;
3052 rgSchDlApis->rgSCHDlInactvtUes = rgSCHSc1DlHndlInActUes;
3053 rgSchDlApis->rgSCHDlUeHqEntInit = rgSCHSc1DlUeHqEntInit;
3054 rgSchDlApis->rgSCHDlUeHqEntDeInit = rgSCHSc1DlUeHqEntDeInit;
3055 rgSchDlApis->rgSCHDlProcRmvFrmRetx = rgSCHSc1DlProcRmvFrmRetx;
3056 rgSchDlApis->rgSCHDlTickForPdbTrkng = rgSCHSc1DlScanUpdPdbPrio;
3057 rgSchDlApis->rgSCHDlFillFlwCtrlInfo = rgSCHSc1DlFillFlowCntrlInfo;
3065 /***********************************************************
3067 * Func : rgSCHSc1DlInitQueues
3069 * Desc : Initial downlink scheduler queues
3077 **********************************************************/
3079 PRIVATE Void rgSCHSc1DlInitQueues
3081 RgSchSc1DlCell *cellDl
3084 PRIVATE Void rgSCHSc1DlInitQueues(cellDl)
3085 RgSchSc1DlCell *cellDl;
3089 TRC2(rgSCHSc1DlInitQueues);
3091 for (i = 0; i < RG_SC1_DL_NUM_Q; ++i)
3093 cmLListInit(&cellDl->prioLst[i]);
3094 cmLListInit(&cellDl->retxLst[i]);
3096 /* Set appropriate "manage svc positioning" function based on
3097 * svc priority as array index */
3099 for (i = 0; i < RG_SCH_SC1_DL_GBR_PRIO_START; i++)
3101 cellDl->svcMngFunc[i] = rgSCHSc1DlMngPrio0SvcPosn;
3104 for (i = RG_SCH_SC1_DL_GBR_PRIO_START; i <= RG_SCH_SC1_DL_GBR_PRIO_END; i++)
3106 cellDl->svcMngFunc[i] = rgSCHSc1DlMngGbrSvcPosn;
3108 /* for Non-GBR svcs */
3109 for (i = RG_SCH_SC1_DL_GBR_PRIO_END+1; i <= RG_SCH_CMN_MAX_PRIO; i++)
3111 cellDl->svcMngFunc[i] = rgSCHSc1DlMngAmbrSvcPosn;
3120 * @brief This function Processes the Final Allocations
3121 * made by the RB Allocator against the requested
3126 * Function: rgSCHSc1DlRetxAllocFnlz
3127 * Purpose : Remove the Retx Hq Proc from the Cell's
3128 * Retx list, if allocation is successful.
3129 * Fill the HqProc and PDCCH and append it to the SubFrm.
3133 * Invoked by: Common Scheduler
3135 * @param[in] RgSchCellCb *cell
3136 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
3141 PRIVATE Void rgSCHSc1DlRetxAllocFnlz
3144 RgSchCmnDlRbAllocInfo *allocInfo
3147 PRIVATE Void rgSCHSc1DlRetxAllocFnlz(cell, allocInfo)
3149 RgSchCmnDlRbAllocInfo *allocInfo;
3154 RgSchDlHqProcCb *hqP;
3155 RgSchDlRbAlloc *dlAllocCb = NULLP;
3156 TRC2(rgSCHSc1DlRetxAllocFnlz);
3158 node = allocInfo->dedAlloc.schdRetxHqPLst.first;
3161 hqP = (RgSchDlHqProcCb *)node->node;
3164 /* Fill PDCCH and assign it to HqP */
3165 dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
3167 rgSCHCmnFillHqPPdcch(cell, dlAllocCb, hqP);
3171 rgSCHCmnHdFddUpdDLMark(cell, ue);
3174 /* Extra Check: Retain the hqProc in the RETX Queue if one/more
3175 * TBs of the HqProc are yet to be scheduled for RETX.
3176 * Note: Here we are not tracking at TB Level, the priority Q
3177 * to which it belongs to. The retx prio of transmission is still
3178 * being maintained at hqProc level, rather than at TB level */
3179 if ((hqP->tbInfo[0].state != HQ_TB_NACKED) &&
3180 (hqP->tbInfo[1].state != HQ_TB_NACKED)) {
3181 rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
3183 /* reset the UE allocation Information */
3184 rgSCHCmnDlUeResetTemp(ue, hqP);
3187 /* Traverse the nonSchdTxUeLst and reset the UE allocation Info */
3188 node = allocInfo->dedAlloc.nonSchdRetxHqPLst.first;
3191 hqP = (RgSchDlHqProcCb *)node->node;
3194 /* reset the UE allocation Information */
3195 rgSCHCmnDlUeResetTemp(ue, hqP);
3200 /* 3.1 MIMO Alloc distribution functions being performed
3204 /***********************************************************
3206 * Func : rgSCHSc1DlSprTxTbDstn
3208 * Desc : Perform Actual allocation distribution among
3209 * UEs schd svcs and TA for a given spare TB "tbInfo" allocation.
3210 * spare TB allocation is as a result of 1 RETX TB allocation, when
3211 * conditions are favourable for 2 TB spatial multiplexing.
3219 **********************************************************/
3221 PRIVATE Void rgSCHSc1DlSprTxTbDstn
3225 RgSchDlHqTbCb *tbInfo,
3230 PRIVATE Void rgSCHSc1DlSprTxTbDstn(cell, ue, tbInfo, effAlloc, node)
3233 RgSchDlHqTbCb *tbInfo;
3239 RgSchSc1DlSvc *svcSc1;
3240 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
3242 RgSchLchAllocInfo lchSchdData;
3246 TRC2(rgSCHSc1DlSprTxTbDstn);
3248 while((*node) && (*effAlloc > 0))
3250 svc = (RgSchDlLcCb *)(*node)->node;
3251 *node = (*node)->next;
3252 svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
3254 RG_SCH_CMN_DL_GET_HDR_EST(svc, rlcHdrEstmt);
3255 /* Update the SVC QOS Param */
3256 if (RG_SCH_CMN_SVC_IS_GBR(svc))
3258 effBo = svcSc1->effMbr + rlcHdrEstmt;
3259 bytes = RGSCH_MIN(*effAlloc, effBo);
3260 /* Determine How much BO is satisfied */
3261 if (bytes <= rlcHdrEstmt)
3265 (svcSc1->bo <= bytes-rlcHdrEstmt)?\
3267 (svcSc1->bo -= bytes-rlcHdrEstmt);
3268 svc->bo = svcSc1->bo;
3272 /* Increment qciActiveLCs once since this LCs buffer will be present
3274 if (svc->lcType == CM_LTE_LCH_DTCH)
3276 ue->qciActiveLCs[svc->qciCb->qci]++;
3279 if ((svc->bo == 0) && (svc->lcType == CM_LTE_LCH_DTCH))
3281 if (ue->qciActiveLCs[svc->qciCb->qci])
3283 ue->qciActiveLCs[svc->qciCb->qci]--;
3285 if (!(ue->qciActiveLCs[svc->qciCb->qci]))
3287 svc->qciCb->dlUeCount--;
3291 (svcSc1->gbr <= bytes)? (svcSc1->gbr = 0):
3292 (svcSc1->gbr -= bytes);
3293 (svcSc1->mbr <= bytes)? (svcSc1->mbr = 0):
3294 (svcSc1->mbr -= bytes);
3296 else if(RG_SCH_CMN_SVC_IS_AMBR(svc))
3298 effBo = ueDl->effAmbr + rlcHdrEstmt;
3299 bytes = RGSCH_MIN(*effAlloc, effBo);
3300 /* Determine How much BO is satisfied */
3301 if (bytes <= rlcHdrEstmt)
3305 (svcSc1->bo <= bytes-rlcHdrEstmt)?\
3307 (svcSc1->bo -= bytes-rlcHdrEstmt);
3309 (ueDl->ambr <= bytes)? (ueDl->ambr = 0):
3310 (ueDl->ambr -= bytes);
3312 else /* Prio 0 SVC */
3314 effBo = svcSc1->bo + rlcHdrEstmt;
3315 bytes = RGSCH_MIN(*effAlloc, effBo);
3316 /* Determine How much BO is satisfied */
3317 if (bytes <= rlcHdrEstmt)
3321 (svcSc1->bo <= bytes-rlcHdrEstmt)?\
3323 (svcSc1->bo -= bytes-rlcHdrEstmt);
3325 /* Position the service accordingly */
3326 rgSCHSc1DlMngSvcPosn(cell, svc->ue, svc);
3327 /* Update effAlloc */
3330 /* Update DHM for this SVC */
3331 lchSchdData.lcId = svc->lcId;
3332 lchSchdData.schdData = bytes;
3333 rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, tbInfo);
3339 /***********************************************************
3341 * Func : rgSCHSc1DlNewTxTbDstn
3343 * Desc : Perform Actual allocation distribution among
3344 * UEs schd svcs and TA for a given TB "tbInfo" allocation.
3345 * Assumption: TA is given higher priority in Alloc Distribution.
3353 **********************************************************/
3355 PRIVATE Void rgSCHSc1DlNewTxTbDstn
3359 RgSchDlHqTbCb *tbInfo,
3364 PRIVATE Void rgSCHSc1DlNewTxTbDstn(cell, ue, tbInfo, effAlloc, node)
3367 RgSchDlHqTbCb *tbInfo;
3373 RgSchSc1DlSvc *svcSc1 = NULLP;
3374 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
3376 RgSchLchAllocInfo lchSchdData;
3377 CmLList *prev = NULLP;
3379 TRC2(rgSCHSc1DlNewTxTbDstn);
3381 if (ueDl->taReqBytes)
3383 if (ueDl->taReqBytes < *effAlloc)
3385 /*TA satisfied, hence remove from TA Lst */
3386 rgSCHCmnRmvFrmTaLst(cell, ue);
3387 /* Indicate to DHM that TA has been scheduled */
3388 rgSCHDhmSchdTa(ue, tbInfo);
3389 *effAlloc -= ueDl->taReqBytes;
3391 /* Reset the TA Req Bytes Field */
3392 ueDl->taReqBytes = 0;
3394 while((*node) && (*effAlloc > 0))
3396 svc = (RgSchDlLcCb *)(*node)->node;
3398 *node = (*node)->next;
3399 svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
3400 if (*effAlloc > svcSc1->reqBytes)
3402 bytes = svcSc1->reqBytes;
3403 if (bytes <= svcSc1->hdrEstimate)
3407 /* 3.1 MIMO updating the reqBytes field */
3408 svcSc1->reqBytes = 0;
3414 if (bytes <= svcSc1->hdrEstimate)
3418 /* 3.1 MIMO updating the reqBytes field */
3419 svcSc1->reqBytes -= bytes;
3420 (svcSc1->bo <= bytes-svcSc1->hdrEstimate)?\
3422 (svcSc1->bo -= bytes-svcSc1->hdrEstimate);
3424 svc->bo = svcSc1->bo;
3429 /* Increment qciActiveLCs once since this LCs buffer will be present
3431 if (svc->lcType == CM_LTE_LCH_DTCH)
3433 ue->qciActiveLCs[svc->qciCb->qci]++;
3436 if ((svc->bo == 0) && (svc->lcType == CM_LTE_LCH_DTCH))
3438 if (ue->qciActiveLCs[svc->qciCb->qci])
3440 ue->qciActiveLCs[svc->qciCb->qci]--;
3442 if (!(ue->qciActiveLCs[svc->qciCb->qci]))
3444 svc->qciCb->dlUeCount--;
3449 /* Update the SVC QOS Param */
3450 if (RG_SCH_CMN_SVC_IS_GBR(svc))
3452 (svcSc1->gbr <= bytes)? (svcSc1->gbr = 0):
3453 (svcSc1->gbr -= bytes);
3454 (svcSc1->mbr <= bytes)? (svcSc1->mbr = 0):
3455 (svcSc1->mbr -= bytes);
3457 else if(RG_SCH_CMN_SVC_IS_AMBR(svc))
3459 (ueDl->ambr <= bytes)? (ueDl->ambr = 0):
3460 (ueDl->ambr -= bytes);
3462 /* Position the service accordingly */
3463 rgSCHSc1DlMngSvcPosn(cell, svc->ue, svc);
3464 /* Update effAlloc */
3467 /* Update DHM for this SVC */
3468 lchSchdData.lcId = svc->lcId;
3469 lchSchdData.schdData = bytes;
3470 rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, tbInfo);
3472 /* If no more scheduled LCs for TB data distribution
3473 * then distribute the spare TB data among the LCs
3474 * of the UE with non-zero BO. This is effective for
3475 * schedulers work on LC level priorities rather than
3477 if ((*node == NULLP) && (svcSc1) && (svcSc1->reqBytes == 0))
3479 rgSCHSc1DlSprTxTbDstn(cell, ue, tbInfo, effAlloc,
3480 &ueDl->lcsWithData.first);
3484 /* make sure node points to the svc not completely
3486 * make sure if not served completely then
3487 * the other TB allocation accomodates the same */
3494 /***********************************************************
3496 * Func : rgSCHSc1DlNewTxUeFnlz
3498 * Desc : Perform allocation Distribution from scheduled TB
3499 * among the list of services considered for scheduling.
3507 **********************************************************/
3509 PRIVATE Void rgSCHSc1DlNewTxUeFnlz
3512 RgSchCmnDlRbAllocInfo *allocInfo,
3516 PRIVATE Void rgSCHSc1DlNewTxUeFnlz(cell, allocInfo, ue)
3518 RgSchCmnDlRbAllocInfo *allocInfo;
3523 RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
3524 RgSchCmnDlUe *cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
3525 /*cell added as part of CA dev*/
3526 /* 3.1 MIMO Distribute data of each TB across services */
3527 RgSchDlRbAlloc *dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
3528 U32 remTb1Bytes = dlAllocCb->tbInfo[0].bytesAlloc;
3529 U32 remTb2Bytes = dlAllocCb->tbInfo[1].bytesAlloc;
3531 /*ccpu00120365-ADD-added to code to check if second TB is utilized */
3534 TRC2(rgSCHSc1DlNewTxUeFnlz);
3537 /* 3.1 MIMO Consider the allocation of New TX TB for distribution */
3538 /* Handle schd services */
3539 node = ueDl->schdSvcs.first;
3541 effAlloc += remTb1Bytes;
3542 rgSCHSc1DlNewTxTbDstn(cell, ue, &cmnUeDl->proc->tbInfo[0],\
3543 &remTb1Bytes, &node);
3544 /* In the event that TB1 is not completely filled by the DL LCs
3545 * BO, consider the reducing the iMcs for increasing redundancy
3546 * and hence reception quality at UE */
3547 rgSCHCmnRdcImcsTxTb(dlAllocCb, 0,
3548 dlAllocCb->tbInfo[0].bytesAlloc - remTb1Bytes);
3551 /*ccpu00120365-ADD-assigning value of remTb2Bytes before utilization */
3552 tb2Bytes = remTb2Bytes;
3554 /* Extra check for a non SM UE allocation */
3556 effAlloc += remTb2Bytes;
3557 rgSCHSc1DlNewTxTbDstn(cell, ue, &cmnUeDl->proc->tbInfo[1],\
3558 &remTb2Bytes, &node);
3559 /* In the event that TB2 is not completely filled by the DL LCs
3560 * BO, consider the reducing the iMcs for increasing redundancy
3561 * and hence reception quality at UE */
3562 rgSCHCmnRdcImcsTxTb(dlAllocCb, 1,
3563 dlAllocCb->tbInfo[1].bytesAlloc - remTb2Bytes);
3566 /* ccpu00120365-ADD-Disable the second TB as the second TB is not
3568 if ( remTb2Bytes && ( tb2Bytes == remTb2Bytes) )
3570 dlAllocCb->mimoAllocInfo.precIdxInfo = 0;
3571 dlAllocCb->mimoAllocInfo.numTxLyrs = 1;
3572 dlAllocCb->tbInfo[1].schdlngForTb = FALSE;
3573 dlAllocCb->tbInfo[1].isDisabled = TRUE;
3576 if (effAlloc == (remTb1Bytes + remTb2Bytes))
3578 /* Allocation such that Nothing could be satisfied */
3579 /* Return the grabbed PDCCH */
3580 rgSCHUtlPdcchPut(cell, &dlAllocCb->dlSf->pdcchInfo,
3582 rgSCHSc1RlsHqProc(cmnUeDl->proc);
3586 /* Fill PDCCH and assign it to HqP */
3587 rgSCHCmnFillHqPPdcch(cell, dlAllocCb, cmnUeDl->proc);
3594 * @brief This function Processes the Final Allocations
3595 * made by the RB Allocator against the requested
3596 * New TX allocations.
3600 * Function: rgSCHSc1DlNewTxAllocFnlz
3601 * Purpose : Distribute the allocation among the Scheduled SVCs.
3602 * Fill pdcch and HqP for UEs will allocations.
3603 * Release HqP for UE with no allocation.
3605 * Invoked by: Common Scheduler
3607 * @param[in] RgSchCellCb *cell
3608 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
3613 PRIVATE Void rgSCHSc1DlNewTxAllocFnlz
3616 RgSchCmnDlRbAllocInfo *allocInfo
3619 PRIVATE Void rgSCHSc1DlNewTxAllocFnlz(cell, allocInfo)
3621 RgSchCmnDlRbAllocInfo *allocInfo;
3626 RgSchCmnDlUe *cmnUeDl;
3627 RgSchDlHqProcCb *hqP;
3628 TRC2(rgSCHSc1DlNewTxAllocFnlz);
3630 node = allocInfo->dedAlloc.schdTxHqPLst.first;
3633 hqP = (RgSchDlHqProcCb *)node->node;
3636 cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
3637 /*cell added as part of CA dev*/
3639 rgSCHSc1DlNewTxUeFnlz(cell, allocInfo, ue);
3643 rgSCHCmnHdFddUpdDLMark(cell, ue);
3646 /* reset the UE allocation Information */
3647 cmLListInit(&((RgSchSc1DlUe *)(cmnUeDl->schSpfc))->schdSvcs);
3648 rgSCHCmnDlUeResetTemp(ue, hqP);
3651 /* Traverse the nonSchdTxUeLst and reset the UE allocation Info */
3652 node = allocInfo->dedAlloc.nonSchdTxHqPLst.first;
3655 hqP = (RgSchDlHqProcCb *)node->node;
3658 cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue, cell);
3660 /* Release HqProc */
3661 rgSCHSc1RlsHqProc(hqP);
3662 /* reset the UE allocation Information */
3663 cmLListInit(&((RgSchSc1DlUe *)(cmnUeDl->schSpfc))->schdSvcs);
3664 rgSCHCmnDlUeResetTemp(ue, hqP);
3669 /* 3.1 Added new function to handle TX+RETX alloc fnlz'n */
3672 * @brief This function Processes the Final Allocations
3673 * made by the RB Allocator against the requested
3674 * RETX+New TX allocations. The NewTx TB allocation
3675 * is considered for distribution among LCs.
3679 * Function: rgSCHSc1DlRetxNewTxAllocFnlz
3680 * Purpose : 1. Reached here due to 1 RETX TB allocation for a
3681 * SM UE, which is capable to accomodate a newTX
3683 * 2. Distribute NewTX TB allocation among the
3684 * SVCs present in lcsWithData list of UE.
3687 * Invoked by: Common Scheduler
3689 * @param[in] RgSchCellCb *cell
3690 * @param[in] RgSchCmnDlRbAllocInfo *cellAllocInfo
3695 PRIVATE Void rgSCHSc1DlRetxNewTxAllocFnlz
3698 RgSchCmnDlRbAllocInfo *cellAllocInfo
3701 PRIVATE Void rgSCHSc1DlRetxNewTxAllocFnlz(cell, cellAllocInfo)
3703 RgSchCmnDlRbAllocInfo *cellAllocInfo;
3708 RgSchSc1DlUe *sc1DlUe;
3709 RgSchDlHqProcCb *hqP;
3710 RgSchDlHqTbCb *newTxTbInfo;
3713 RgSchDlRbAlloc *ueAllocInfo;
3714 RgSchDlRbAlloc *dlAllocCb;
3716 TRC2(rgSCHSc1DlRetxNewTxAllocFnlz);
3718 node = cellAllocInfo->dedAlloc.schdTxRetxHqPLst.first;
3721 hqP = (RgSchDlHqProcCb *)node->node;
3724 sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
3725 ueAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
3726 dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
3727 /* Index 0 of ueAllocInfo->tbInfo will always hold the
3728 * RETX TB and index 1 will hold the NewTX TB in case of
3729 * RETX+TX allocation. */
3730 newTxTbInfo = ueAllocInfo->tbInfo[1].tbCb;
3731 effAlloc = remTbBytes = ueAllocInfo->tbInfo[1].bytesAlloc;
3732 rgSCHSc1DlSprTxTbDstn(cell, ue, newTxTbInfo,\
3733 &remTbBytes, &(sc1DlUe->lcsWithData.first));
3734 /* Trying to reduce mcs of TX TB to increase reception quality at UE.
3735 * In case of RETX+TX allocation, TX TB allocation was irrespective
3736 * of actual requirement by UE, hence in case if consumption is
3737 * less than allocation, consider reducing the iMcs of this TX TB. */
3738 rgSCHCmnRdcImcsTxTb(dlAllocCb, 1, effAlloc - remTbBytes);
3739 /* 3.1 MIMO Remove/Retain from/in cell RETX List */
3740 rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
3741 /* Fill PDCCH and assign it to HqP */
3742 rgSCHCmnFillHqPPdcch(cell, dlAllocCb, hqP);
3746 rgSCHCmnHdFddUpdDLMark(cell, ue);
3749 /* reset the UE allocation Information */
3750 rgSCHCmnDlUeResetTemp(ue, hqP);
3753 /* Traverse the nonSchdTxRetxHqPLst and reset the UE allocation Info */
3754 node = cellAllocInfo->dedAlloc.nonSchdTxRetxHqPLst.first;
3757 hqP = (RgSchDlHqProcCb *)node->node;
3760 /* reset the UE allocation Information */
3761 rgSCHCmnDlUeResetTemp(ue, hqP);
3767 * @brief This function Processes the Final Allocations
3768 * made by the RB Allocator against the requested.
3772 * Function: rgSCHSc1DlAllocFnlz
3773 * Purpose: This function Processes the Final Allocations
3774 * made by the RB Allocator against the requested.
3775 * 1. Loop through scheduled TX and RETX lists.
3776 * Fill in the corresponding PDCCH and HqProcs.
3777 * In case of TX If actual Alloc < requested, then perform
3778 * an appropriate distribution among the schdSvcs.
3779 * If TA is satisfied, then remove UE from TA Lst.
3780 * 2. Loop through UnScheduled TX and RETX Lists.
3781 * Release grabbed HqProcs.
3782 * Put back SVCs from schdSvcsLst to their corresponding Qs.
3785 * Invoked by: Common Scheduler
3787 * @param[in] RgSchCellCb *cell
3788 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
3793 PUBLIC Void rgSCHSc1DlAllocFnlz
3796 RgSchCmnDlRbAllocInfo *allocInfo
3799 PUBLIC Void rgSCHSc1DlAllocFnlz(cell, allocInfo)
3801 RgSchCmnDlRbAllocInfo *allocInfo;
3804 TRC2(rgSCHSc1DlAllocFnlz);
3806 rgSCHSc1DlRetxAllocFnlz(cell, allocInfo);
3808 rgSCHSc1DlNewTxAllocFnlz(cell, allocInfo);
3810 /*3.1 MIMO new Function added to handle TX+RETX
3811 * harq process scheduling finalization */
3812 rgSCHSc1DlRetxNewTxAllocFnlz(cell, allocInfo);
3819 * @brief This function Updates the DL CQI for the UE.
3823 * Function: rgSCHSc1DlCqiInd
3824 * Purpose: Updates the DL CQI for the UE
3826 * Invoked by: Common Scheduler. SC1 does nothing.
3828 * @param[in] RgSchCellCb *cell
3829 * @param[in] RgSchUeCb *ue
3830 * @param[in] TfuDlCqiRpt *dlCqiRpt
3835 PUBLIC Void rgSCHSc1DlCqiInd
3843 PUBLIC Void rgSCHSc1DlCqiInd(cell, ue, isPucchInfo, dlCqi)
3850 TRC2(rgSCHSc1DlCqiInd);
3856 * @brief This function adds a service to UE's list of lcsWithData.
3860 * Function: rgSCHSc1DlAdd2UeLcsWithData
3861 * Purpose: 1. This is to maintain a snapshot view of the
3862 * DL SVCs distributions among the cellwide priority
3864 * 2. This snapshot view is maintained in the order
3865 * of priority of the SVCs with in UE.
3866 * 3. Addition of SVC to a cellwide priority Queue
3867 * triggers this function.
3869 * Invoked by: Functions of DL SC1 which add SVC or UE(for ambr svc)
3870 * to cellwide priority Queues.
3872 * @param[in] RgSchUeCb* ue
3873 * @param[in] RgSchDlLcCb* svc
3878 PRIVATE Void rgSCHSc1DlAdd2UeLcsWithData
3885 PRIVATE Void rgSCHSc1DlAdd2UeLcsWithData(cell, ue, svc)
3893 RgSchCmnDlSvc *cmnDlSvc = RG_SCH_CMN_GET_DL_SVC(svc);
3894 RgSchSc1DlSvc *sc1DlSvc = RG_GET_SC1_SVC_DL(ue,svc,cell);
3895 RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
3896 RgSchCmnDlSvc *cmnDlLstSvc;
3898 TRC2(rgSCHSc1DlAdd2UeLcsWithData);
3900 lst = &(sc1DlUe->lcsWithData);
3904 cmnDlLstSvc = RG_SCH_CMN_GET_DL_SVC(((RgSchDlLcCb *)(node->node)));
3905 if (cmnDlSvc->prio <= cmnDlLstSvc->prio)
3913 cmLListAdd2Tail(lst, &sc1DlSvc->lcWithDataLnk);
3914 sc1DlSvc->lcWithDataLnk.node = (PTR)svc;
3919 cmLListInsCrnt(lst, &sc1DlSvc->lcWithDataLnk);
3920 sc1DlSvc->lcWithDataLnk.node = (PTR)svc;
3927 * @brief This function adds a service to UE's list of lcsWithData.
3931 * Function: rgSCHSc1DlRmFrmUeLcsWithData
3932 * Purpose: 1. This is to maintain a snapshot view of the
3933 * DL SVCs distributions among the cellwide priority
3935 * 2. This snapshot view is maintained in the order
3936 * of priority of the SVCs with in UE.
3937 * 3. Addition of SVC to a cellwide priority Queue
3938 * triggers this function.
3940 * Invoked by: Functions of DL SC1 which add SVC or UE(for ambr svc)
3941 * to cellwide priority Queues.
3943 * @param[in] RgSchUeCb* ue
3944 * @param[in] RgSchDlLcCb* svc
3949 PRIVATE Void rgSCHSc1DlRmFrmUeLcsWithData
3956 PRIVATE Void rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, svc)
3962 RgSchSc1DlSvc *sc1DlSvc = RG_GET_SC1_SVC_DL(ue,svc,cell);
3963 RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
3965 TRC2(rgSCHSc1DlRmFrmUeLcsWithData);
3967 cmLListDelFrm(&(sc1DlUe->lcsWithData), &sc1DlSvc->lcWithDataLnk);
3968 sc1DlSvc->lcWithDataLnk.node = NULLP;
3971 /***************** SC1 DL SCHEDULER FUNCTION DEFNs END HERE ****************/
3973 /***************************************************************************/
3975 /***************** SC1 UL SCHEDULER FUNCTION DEFNs START HERE **************/
3977 /*--------------------------*
3978 * UL specific functions START
3979 *---------------------------*/
3982 * @brief UE Lc Config for RR
3986 * Function : rgSCHSc1UlLchCfg
3988 * Processing Steps: Dummy function
3990 * @param[in] RgrSchCellCb *cell
3991 * @param[in] RgSchUeCb *ue
3992 * @param[in] RgrLchCfg *cfg
3993 * @param[in] RgSchErrInfo *err
3997 PUBLIC S16 rgSCHSc1UlLchCfg
4008 * @brief UE Lc Reconfig for RR
4012 * Function : rgSCHSc1UlLchRecfg
4014 * Processing Steps: Dummy function
4016 * @param[in] RgrSchCellCb *cell
4017 * @param[in] RgSchUeCb *ue
4018 * @param[in] RgrLchRecfg *recfg
4019 * @param[in] RgSchErrInfo *err
4023 PUBLIC S16 rgSCHSc1UlLchRecfg
4034 * @brief LC deletion for PFS
4038 * Function : rgSCHSc1UlLchDel
4040 * Processing Steps: Dummy function
4042 * @param[in] RgrSchCellCb *cell
4043 * @param[in] RgSchUeCb *ue
4044 * @param[in] CmLteLcId lcId
4049 PUBLIC S16 rgSCHSc1UlLchDel
4057 PUBLIC S16 rgSCHRrUlLchDel(cell, ue, lcId, lcgId)
4068 * @brief This function initializes all the data for the scheduler
4072 * Function: rgSCHSc1UlInit
4073 * Purpose: This function initializes the following information
4074 * 1. Efficiency table
4075 * 2. CQI to table index - It is one row for upto 3 RBs
4076 * and another row for greater than 3 RBs
4078 * currently extended prefix is compiled out.
4079 * Invoked by: MAC intialization code..may be ActvInit
4085 PUBLIC Void rgSCHSc1UlInit
4087 RgUlSchdApis *rgSchUlApis
4090 PUBLIC Void rgSCHSc1UlInit(rgSchUlApis)
4091 RgUlSchdApis *rgSchUlApis;
4094 TRC2(rgSCHSc1UlInit);
4095 /* Init the function pointers */
4096 rgSchUlApis->rgSCHRgrUlUeCfg = rgSCHSc1RgrUlUeCfg;
4097 rgSchUlApis->rgSCHRgrUlUeRecfg = rgSCHSc1RgrUlUeRecfg;
4098 rgSchUlApis->rgSCHFreeUlUe = rgSCHSc1UlUeDel;
4099 rgSchUlApis->rgSCHRgrUlCellCfg = rgSCHSc1RgrUlCellCfg;
4100 rgSchUlApis->rgSCHRgrUlCellRecfg = rgSCHSc1RgrUlCellRecfg;
4101 rgSchUlApis->rgSCHFreeUlCell = rgSCHSc1UlCellDel;
4102 rgSchUlApis->rgSCHRgrUlLcCfg = rgSCHSc1UlLchCfg;
4103 rgSchUlApis->rgSCHRgrUlLcRecfg = rgSCHSc1UlLchRecfg;
4104 rgSchUlApis->rgSCHRgrUlLcgCfg = rgSCHSc1RgrLcgCfg;
4105 rgSchUlApis->rgSCHRgrUlLcgRecfg = rgSCHSc1RgrLcgRecfg;
4106 rgSchUlApis->rgSCHFreeUlLcg = rgSCHSc1LcgDel;
4107 rgSchUlApis->rgSCHRgrUlLchDel = rgSCHSc1UlLchDel;
4108 rgSchUlApis->rgSCHUlSched = rgSCHSc1UlSched;
4109 rgSchUlApis->rgSCHUpdBsrShort = rgSCHSc1UpdBsrShort;
4110 rgSchUlApis->rgSCHUpdBsrTrunc = rgSCHSc1UpdBsrTrunc;
4111 rgSchUlApis->rgSCHUpdBsrLong = rgSCHSc1UpdBsrLong;
4112 rgSchUlApis->rgSCHContResUlGrant = rgSCHSc1ContResUlGrant;
4113 rgSchUlApis->rgSCHSrRcvd = rgSCHSc1SrRcvd;
4114 rgSchUlApis->rgSCHUlCqiInd = rgSCHSc1UlCqiInd;
4115 rgSchUlApis->rgSCHUlUeRefresh = rgSCHSc1UlUeRefresh;
4116 rgSchUlApis->rgSCHUlAllocFnlz = rgSCHSc1UlAllocFnlz;
4117 rgSchUlApis->rgSCHUlInactvtUes = rgSCHSc1UlHndlInActUes;
4118 rgSchUlApis->rgSCHUlActvtUe = rgSCHSc1UlActvtUe;
4119 rgSchUlApis->rgSCHUlUeReset = rgSCHSc1UlUeReset;
4120 rgSchUlApis->rgSCHRgrUlLcgUpd = rgSCHSc1UlLcgUpd;
4125 * @brief UE initialisation for scheduler
4129 * Function : rgSCHSc1RgrUlUeCfg
4131 * This functions intialises UE specific scheduler
4134 * @param[in] RgSchCellCb *cell
4135 * @param[in] RgSchUeCb *ue
4136 * @param[int] RgrUeCfg *ueCfg
4137 * @param[out] RgSchErrInfo *err
4143 PUBLIC S16 rgSCHSc1RgrUlUeCfg
4151 PUBLIC S16 rgSCHSc1RgrUlUeCfg(cell, ue, ueCfg, err)
4159 RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue, cell);
4160 TRC2(rgSCHSc1RgrUlUeCfg);
4162 if(rgSCHUtlAllocSBuf(cell->instIdx,
4163 (Data**)&(ueSchCmn->ul.schSpfc), (sizeof(RgSchSc1UlUe))) != ROK)
4165 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
4166 "Memory allocation FAILED CRNTI:%d",ue->ueId);
4167 err->errCause = RGSCHERR_SCH_SC1_UL_CFG;
4172 } /* rgSCHSc1RgrUlUeCfg */
4175 * @brief UE reconfiguration for scheduler
4179 * Function : rgSCHSc1RgrUlUeRecfg
4181 * This functions updates UE specific scheduler
4182 * information upon UE reconfiguration
4184 * @param[in] RgSchCellCb *cell
4185 * @param[in] RgSchUeCb *ue
4186 * @param[int] RgrUeRecfg *ueRecfg
4187 * @param[out] RgSchErrInfo *err
4193 PUBLIC S16 rgSCHSc1RgrUlUeRecfg
4197 RgrUeRecfg *ueRecfg,
4201 PUBLIC S16 rgSCHSc1RgrUlUeRecfg(cell, ue, ueRecfg, err)
4204 RgrUeRecfg *ueRecfg;
4208 TRC2(rgSCHSc1RgrUlUeRecfg);
4210 } /* rgSCHSc1RgrUeRecfg */
4213 * @brief UE deletion for scheduler
4217 * Function : rgSCHSc1UlUeDel
4219 * This functions deletes all scheduler information
4220 * pertaining to a UE
4222 * @param[in] RgSchCellCb *cell
4223 * @param[in] RgSchUeCb *ue
4227 PUBLIC Void rgSCHSc1UlUeDel
4233 PUBLIC Void rgSCHSc1UlUeDel(cell, ue)
4238 RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
4239 RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell);
4241 TRC2(rgSCHSc1UlUeDel);
4247 if(ueUl->txLnk.node)
4249 cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
4250 ueUl->txLnk.node = NULLP;
4252 if(ueUl->contResLnk.node)
4254 cmLListDelFrm(&(cellUl->contResLst), &(ueUl->contResLnk));
4255 ueUl->contResLnk.node = NULLP;
4257 /* ccpu00117052 - MOD - Passing double pointer
4258 for proper NULLP assignment*/
4259 rgSCHUtlFreeSBuf(cell->instIdx,
4260 (Data**)(&(ueUl)), (sizeof(RgSchSc1UlUe)));
4263 } /* rgSCHSc1UlUeDel */
4266 * @brief UE Reset for scheduler
4270 * Function : rgSCHSc1UlUeReset
4272 * Remove this UE from all Scheduling Priority Qs
4274 * @param[in] RgSchCellCb *cell
4275 * @param[in] RgSchUeCb *ue
4279 PUBLIC Void rgSCHSc1UlUeReset
4285 PUBLIC Void rgSCHSc1UlUeReset(cell, ue)
4290 RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
4291 RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell);
4293 TRC2(rgSCHSc1UlUeReset);
4295 ueUl->srRcvd = FALSE;
4297 if(ueUl->txLnk.node)
4299 cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
4300 ueUl->txLnk.node = NULLP;
4302 if(ueUl->contResLnk.node)
4304 cmLListDelFrm(&(cellUl->contResLst), &(ueUl->contResLnk));
4305 ueUl->contResLnk.node = NULLP;
4308 } /* rgSCHSc1UlUeReset */
4312 * @brief Scheduler processing on cell configuration
4316 * Function : rgSCHSc1RgrUlCellCfg
4318 * This function does requisite initialisation
4319 * and setup for scheduler1 when a cell is
4322 * @param[in] RgSchCellCb *cell
4323 * @param[in] RgrCellCfg *cellCfg
4324 * @param[out] RgSchErrInfo *err
4330 PUBLIC S16 rgSCHSc1RgrUlCellCfg
4333 RgrCellCfg *cellCfg,
4337 PUBLIC S16 rgSCHSc1RgrUlCellCfg(cell, cellCfg, err)
4339 RgrCellCfg *cellCfg;
4343 RgSchSc1UlCell *cellUl;
4345 TRC2(rgSCHSc1RgrUlCellCfg);
4347 if((rgSCHUtlAllocSBuf(cell->instIdx,
4348 (Data**)&(((RgSchCmnCell*)((cell)->sc.sch))->ul.schSpfc), \
4349 (sizeof(RgSchSc1UlCell))) != ROK))
4351 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
4352 "Memory allocation FAILED");
4353 err->errCause = RGSCHERR_SCH_SC1_UL_CFG;
4356 cellUl = RG_GET_SC1_CELL_UL(cell);
4357 cmLListInit(&cellUl->contResLst);
4358 cmLListInit(&cellUl->ueTxLst[0]);
4359 cmLListInit(&cellUl->ueTxLst[1]);
4362 } /* rgSCHSc1RgrUlCellCfg */
4366 * @brief This function handles the reconfiguration of cell
4370 * Function: rgSCHSc1RgrUlCellRecfg
4371 * Purpose: Update the reconfiguration parameters.
4373 * Invoked by: Scheduler
4375 * @param[in] RgSchCellCb* cell
4380 PUBLIC S16 rgSCHSc1RgrUlCellRecfg
4383 RgrCellRecfg *recfg,
4387 PUBLIC S16 rgSCHSc1RgrUlCellRecfg(cell, recfg, err)
4389 RgrCellRecfg *recfg;
4393 TRC2(rgSCHSc1RgrUlCellRecfg);
4398 * @brief Scheduler processing for cell delete
4402 * Function : rgSCHSc1UlCellDel
4404 * This functions de-initialises and frees memory
4405 * taken up by scheduler1 for the entire cell.
4407 * @param[in] RgSchCellCb *cell
4411 PUBLIC Void rgSCHSc1UlCellDel
4416 PUBLIC Void rgSCHSc1UlCellDel(cell)
4420 RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
4422 TRC2(rgSCHSc1UlCellDel);
4424 if (cellUl == NULLP)
4428 /* ccpu00117052 - MOD - Passing double pointer
4429 for proper NULLP assignment*/
4430 rgSCHUtlFreeSBuf(cell->instIdx,
4431 (Data**)(&(cellUl)), (sizeof(RgSchSc1UlCell)));
4434 } /* rgSCHSc1UlCellDel */
4437 * @brief Scheduler invocation on logical channel Group addition
4441 * Function : rgSCHSc1RgrLcgCfg
4443 * This functions does required processing when a new
4444 * (dedicated) logical channel is added. Assumes lcg
4445 * pointer in ulLc is set.
4447 * @param[in] RgSchCellCb *cell
4448 * @param[in] RgSchUeCb *ue
4449 * @param[in] RgSchLcgCb *lcg
4450 * @param[int] RgrLcgCfg *lcgCfg
4451 * @param[out] RgSchErrInfo *err
4457 PUBLIC S16 rgSCHSc1RgrLcgCfg
4466 PUBLIC S16 rgSCHSc1RgrLcgCfg(cell, ue, lcg, lcgCfg, err)
4474 TRC2(rgSCHSc1RgrLcgCfg);
4476 } /* rgSCHSc1RgrLcgCfg */
4479 * @brief Scheduler invocation on logical channel addition
4483 * Function : rgSCHSc1RgrLcgRecfg
4485 * This functions does required processing when an existing
4486 * (dedicated) logical channel is reconfigured. Assumes lcg
4487 * pointer in ulLc is set to the old value.
4488 * Independent of whether new LCG is meant to be configured,
4489 * the new LCG scheduler info is accessed and possibly modified.
4491 * @param[in] RgSchCellCb *cell,
4492 * @param[in] RgSchUeCb *ue,
4493 * @param[in] RgSchLcgCb *lcg,
4494 * @param[in] RgrLcgRecfg *reCfg,
4495 * @param[out] RgSchErrInfo *err
4501 PUBLIC S16 rgSCHSc1RgrLcgRecfg
4510 PUBLIC S16 rgSCHSc1RgrLcgRecfg(cell, ue, lcg, reCfg, err)
4518 TRC2(rgSCHSc1RgrLcgRecfg);
4520 } /* rgSCHSc1RgrLcgRecfg */
4522 /***********************************************************
4524 * Func : rgSCHSc1LcgDel
4526 * Desc : Scheduler handling for a (dedicated)
4527 * uplink lcg being deleted
4535 **********************************************************/
4537 PUBLIC Void rgSCHSc1LcgDel
4544 PUBLIC Void rgSCHSc1LcgDel(cell, ue, lcg)
4550 TRC2(rgSCHSc1LcgDel);
4551 rgSCHSc1UlPosnUeInQ(cell, ue);
4556 * @brief Perform alloction for this UE
4560 * Function : rgSCHSc1UlSchdUe
4562 * Processing Steps: cater to as much as UE needs, with
4563 * a limitation on maxBits per scheduling instance(per TTI)
4564 * per UE. Return failure, if UE is not considered
4565 * for scheduling (case, where it is already selected for a
4569 * @param[in] RgSchUeCb *ue
4573 PRIVATE Void rgSCHSc1UlSchdUe
4579 PRIVATE Void rgSCHSc1UlSchdUe(ue,cell)
4584 RgSchCmnUlUe *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue, cell);
4585 /*cell added as part of CA dev*/
4586 RgSchSc1UlUe *ulUe = RG_GET_SC1_UE_UL(ue, cell);
4588 TRC2(rgSCHSc1UlSchdUe);
4590 if(ulUe->srRcvd == TRUE)
4592 cmnUlUe->alloc.reqBytes = RGSCH_MAX(RG_SCH_CMN_UL_SR_BYTES, \
4597 cmnUlUe->alloc.reqBytes = ue->ul.effBsr;
4603 * @brief Scheduler invocation
4607 * Function: rgSCHSc1UlSchdForDataTrans
4608 * Purpose: Uplink Scheduling for UE data Transmission.
4611 * Invoked by: Scheduler
4613 * @param[in] RgSchCellCb *cell
4614 * @param[out] RgSchCmnUlRbAllocInfo *allocInfo
4615 * @param[in] U8 remUe
4619 PRIVATE Void rgSCHSc1UlSchdForDataTrans
4622 RgSchCmnUlRbAllocInfo *allocInfo,
4626 PRIVATE Void rgSCHSc1UlSchdForDataTrans(cell, allocInfo, remUe)
4628 RgSchCmnUlRbAllocInfo *allocInfo;
4632 RgSchSc1UlCell *sc1UlCell = RG_GET_SC1_CELL_UL(cell);
4634 TRC2(rgSCHSc1UlSchdForDataTrans);
4640 /* Allocate UEs with LCG0 data pending */
4641 rgSCHSc1UlSchdUeTxLst(cell, &sc1UlCell->ueTxLst[0], allocInfo, &remUe);
4647 /* Allocate UEs with other LCGs data pending */
4648 rgSCHSc1UlSchdUeTxLst(cell, &sc1UlCell->ueTxLst[1], allocInfo, &remUe);
4654 * @brief Scheduler invocation
4658 * Function: rgSCHSc1UlSchdUeTxLst
4659 * Purpose: Uplink Scheduling for UE data Transmission.
4662 * Invoked by: Scheduler
4664 * @param[in] CmLListCp *ueTxLst
4665 * @param[out] RgSchCmnUlRbAllocInfo *allocInfo
4666 * @param[in] U8 *remUe
4670 PRIVATE Void rgSCHSc1UlSchdUeTxLst
4674 RgSchCmnUlRbAllocInfo *allocInfo,
4678 PRIVATE Void rgSCHSc1UlSchdUeTxLst(cell, ueTxLst, allocInfo, remUe)
4681 RgSchCmnUlRbAllocInfo *allocInfo;
4688 Bool ulAllowed = FALSE;
4691 TRC2(rgSCHSc1UlSchdUeTxLst);
4693 node = ueTxLst->first;
4694 while ((node) && (*remUe))
4696 ue = (RgSchUeCb *)node->node;
4701 rgSCHCmnHdFddChkUlAllow (cell, ue, &ulAllowed);
4702 if (ulAllowed == FALSE)
4709 if (RG_SCH_CMN_IS_UL_UE_RETX(ue, cell))
4711 /* UE already scheduled in this subframe (for retx)
4712 * OR is inactive for UL Transmission.*/
4715 /* Added support for SPS*/
4717 else if (RG_SCH_CMN_IS_SPS_SCHD(ue, cell))
4719 /*-- Already Scheduled by SPS --*/
4724 rgSCHSc1UlSchdUe(ue,cell);/*cell added as part of CA dev*/
4726 rgSCHCmnUlAdd2UeLst(cell, allocInfo, ue);
4735 * @brief Scheduler invocation
4739 * Function: rgSCHSc1UlSchdForContRes
4740 * Purpose: Uplink Scheduling for Contention Resolution.
4743 * Invoked by: Scheduler
4745 * @param[in] RgSchCellCb *cell
4746 * @param[out] RgSchCmnUlRbAllocInfo *allocInfo
4747 * @param[out] U8 *remUe
4751 PRIVATE Void rgSCHSc1UlSchdForContRes
4754 RgSchCmnUlRbAllocInfo *allocInfo,
4758 PRIVATE Void rgSCHSc1UlSchdForContRes(cell, allocInfo, remUe)
4760 RgSchCmnUlRbAllocInfo *allocInfo;
4764 RgSchSc1UlCell *sc1UlCell = RG_GET_SC1_CELL_UL(cell);
4767 RgSchCmnUlUe *cmnUlUe;
4769 Bool ulAllowed = FALSE;
4772 TRC2(rgSCHSc1UlSchdForContRes);
4774 node = sc1UlCell->contResLst.first;
4775 while ((node) && (*remUe))
4777 ue = (RgSchUeCb *)node->node;
4778 cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue, cell);
4779 /*cell added as part of CA dev*/
4784 rgSCHCmnHdFddChkUlAllow (cell, ue, &ulAllowed);
4785 if (ulAllowed == FALSE)
4791 if (RG_SCH_CMN_IS_UL_UE_RETX(ue, cell))
4793 /* UE already scheduled in this subframe (for retx)
4794 * OR is inactive for UL Transmission.*/
4797 cmnUlUe->alloc.reqBytes = RG_SCH_CMN_MAX_UL_CONTRES_GRNT;
4798 rgSCHCmnUlAdd2CntResLst(allocInfo, ue);
4800 /* Node removal deferred to ULAllocFinalization */
4807 * @brief Scheduler invocation
4811 * Function: rgSCHSc1UlNewTx
4812 * Purpose: Uplink Scheduling for New Transmissions.
4815 * Invoked by: Scheduler
4817 * @param[in] RgSchCellCb *cell
4818 * @param[out] RgSchCmnUlRbAllocInfo *allocInfo
4822 PRIVATE Void rgSCHSc1UlNewTx
4825 RgSchCmnUlRbAllocInfo *allocInfo
4828 PRIVATE Void rgSCHSc1UlNewTx(cell, allocInfo)
4830 RgSchCmnUlRbAllocInfo *allocInfo;
4833 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4834 U8 remUe = cellUl->maxUeNewTxPerTti;
4836 TRC2(rgSCHSc1UlNewTx);
4838 rgSCHSc1UlSchdForContRes(cell, allocInfo, &remUe);
4839 rgSCHSc1UlSchdForDataTrans(cell, allocInfo, remUe);
4844 * @brief Scheduler invocation
4848 * Function: rgSCHSc1UlSched
4849 * Purpose: This function implements an UL scheduler for LTE. This is
4850 * made available as a function pointer to be called
4851 * at the time of TTI processing by the MAC.
4853 * Invoked by: Common Scheduler (TTI processing)
4855 * @param[in] RgSchCellCb *cell
4856 * @param[out] RgSchCmnUlRbAllocInfo *allocInfo
4860 PUBLIC Void rgSCHSc1UlSched
4863 RgSchCmnUlRbAllocInfo *allocInfo
4866 PUBLIC Void rgSCHSc1UlSched(cell, allocInfo)
4868 RgSchCmnUlRbAllocInfo *allocInfo;
4871 TRC2(rgSCHSc1UlSched);
4872 rgSCHSc1UlNewTx(cell, allocInfo);
4877 * @brief UEs Buffer Status Has changed so reposition it.
4881 * Function : rgSCHSc1UlInsUeInQ
4883 * In UE in the list in Descending order of effBsr.
4886 * @param[in] CmLListCp *lst
4887 * @param[in] RgSchUeCb *ue
4891 PRIVATE Void rgSCHSc1UlInsUeInQ
4898 PRIVATE Void rgSCHSc1UlInsUeInQ(lst, ue, cell)
4904 /*cell added as part of CA dev*/
4905 RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell);
4909 TRC2(rgSCHSc1UlInsUeInQ);
4914 lUe = (RgSchUeCb *)(node->node);
4915 if (lUe->ul.effBsr <= ue->ul.effBsr)
4923 /* We have come to the end of the queue, so Append */
4924 cmLListAdd2Tail(lst, &ueUl->txLnk);
4925 ueUl->txLnk.node = (PTR)ue;
4930 cmLListInsCrnt(lst, &ueUl->txLnk);
4931 ueUl->txLnk.node = (PTR)ue;
4937 * @brief UEs Buffer Status Has changed so reposition it.
4941 * Function : rgSCHSc1UlPosnUeInQ
4943 * -Ues bs value for its LCG has changed, due to either
4944 * allocation or BSR report OR the effUeBR, i.e the byteRate
4945 * has changed due to some allocation, so add/reposition/remove
4946 * it from Qs based on this new bs and/or effUeBR value.
4947 * -If UE has non-zero lcg0 bs value, but the byteRate is
4948 * consumed totally, UE is still schedulable for this control data.
4949 * -If UE's LCG0 has pending bs then position this UE in
4951 * -If Ue has pending BSR to be satisfied, but lcg0's BS
4952 * is 0, then position it in ueTxLst[1].
4953 * -In any of these 2 Qs, insertion is such that UEs are
4954 * positioned in Descending order of their Pending BS.
4957 * @param[in] RgSchCellCb *cell
4958 * @param[in] RgSchUeCb *ue
4962 PRIVATE Void rgSCHSc1UlPosnUeInQ
4968 PRIVATE Void rgSCHSc1UlPosnUeInQ(cell, ue)
4973 RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell);
4974 /*cell added as part of CA dev*/
4975 RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
4976 RgSchCmnLcg *cmnLcg0 = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[0]);
4979 TRC2(rgSCHSc1UlPosnUeInQ);
4981 if (!RG_SCH_CMN_UL_IS_UE_ACTIVE(ue))
4986 /* Remove the UE from its existing position */
4987 if (ueUl->txLnk.node)
4989 cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
4990 ueUl->txLnk.node = (PTR)NULLP;
4992 /* If UE has still bs left for scheduling
4993 * then reposition it */
4994 if ((ue->ul.effBsr > 0) || (ueUl->srRcvd == TRUE))
4996 /* Select the Queue where UE would be Placed */
4997 if (cmnLcg0->bs > 0)
4999 lst = &cellUl->ueTxLst[0];
5004 lst = &cellUl->ueTxLst[1];
5007 /* Insert the UE in the Q */
5008 rgSCHSc1UlInsUeInQ(lst, ue, cell);/*cell added as part of CA dev*/
5011 else if(ue->ul.totalBsr != 0)
5013 if (ue->bsrTmr.tmrEvnt != TMR_NONE)
5015 rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue);
5017 if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres)
5019 rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR,
5020 ue->ul.bsrTmrCfg.prdBsrTmr);
5029 * @brief Short BSR update
5033 * Function : rgSCHSc1UpdBsrShort
5035 * This functions does requisite updates to handle short BSR reporting
5037 * @param[in] RgSchCellCb *cell
5038 * @param[in] RgSchUeCb *ue
5039 * @param[in] RgSchLcgCb *lcg
5044 PUBLIC Void rgSCHSc1UpdBsrShort
5052 PUBLIC Void rgSCHSc1UpdBsrShort(cell, ue, lcg, bsr)
5059 TRC2(rgSCHSc1UpdBsrShort);
5060 rgSCHSc1UlPosnUeInQ(cell, ue);
5062 } /* rgSCHSc1UpdBsrShort */
5065 * @brief Truncated BSR update
5069 * Function : rgSCHSc1UpdBsrTrunc
5071 * This functions does required updates to handle truncated BSR report
5074 * @param[in] RgSchCellCb *cell
5075 * @param[in] RgSchUeCb *ue
5076 * @param[in] RgSchLcgCb *lcg
5081 PUBLIC Void rgSCHSc1UpdBsrTrunc
5089 PUBLIC Void rgSCHSc1UpdBsrTrunc(cell, ue, lcg, bsr)
5096 TRC2(rgSCHSc1UpdBsrTrunc);
5097 rgSCHSc1UlPosnUeInQ(cell, ue);
5099 } /* rgSCHSc1UpdBsrTrunc */
5102 * @brief Long BSR update
5106 * Function : rgSCHSc1UpdBsrLong
5108 * - Update UE's position within/across uplink scheduling queues
5111 * @param[in] RgSchCellCb *cell
5112 * @param[in] RgSchUeCb *ue
5113 * @param[in] U8 bsArr[]
5117 PUBLIC Void rgSCHSc1UpdBsrLong
5124 PUBLIC Void rgSCHSc1UpdBsrLong(cell, ue, bsArr)
5130 TRC2(rgSCHSc1UpdBsrLong);
5131 rgSCHSc1UlPosnUeInQ(cell, ue);
5133 } /* rgSCHSc1UpdBsrLong */
5136 * @brief UL grant for contention resolution
5140 * Function : rgSCHSc1ContResUlGrant
5142 * Add UE to another queue specifically for CRNTI based contention
5146 * @param[in] RgSchCellCb *cell
5147 * @param[in] RgSchUeCb *ue
5151 PUBLIC Void rgSCHSc1ContResUlGrant
5157 PUBLIC Void rgSCHSc1ContResUlGrant(cell, ue)
5162 RgSchSc1UlUe *ueUl = RG_GET_SC1_UE_UL(ue, cell);
5163 RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
5165 TRC2(rgSCHSc1ContResUlGrant);
5167 if (ueUl->contResLnk.node)
5172 /* Remove the UE from other Qs */
5173 if(ueUl->txLnk.node)
5175 cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
5176 ueUl->txLnk.node = NULLP;
5179 cmLListAdd2Tail(&cellUl->contResLst, &ueUl->contResLnk);
5180 ueUl->contResLnk.node = (PTR)ue;
5182 } /* rgSCHSc1ContResUlGrant */
5185 * @brief SR reception handling
5189 * Function : rgSCHSc1SrRcvd
5190 * Shift the UE with SrInd in to the lcgO queue.
5193 * @param[in] RgSchCellCb *cell
5194 * @param[in] RgSchUeCb *ue
5198 PUBLIC Void rgSCHSc1SrRcvd
5204 PUBLIC Void rgSCHSc1SrRcvd(cell, ue)
5209 RgSchSc1UlUe *ulUe = RG_GET_SC1_UE_UL(ue, cell);
5210 RgSchSc1UlCell *ulCell = RG_GET_SC1_CELL_UL(cell);
5212 TRC2(rgSCHSc1SrRcvd);
5214 ulUe->srRcvd = TRUE;
5216 if (ulUe->txLnk.node != NULLP)
5220 /* Already present in lcg0 Q */
5223 cmLListDelFrm(&(ulCell->ueTxLst[ulUe->qId]), &(ulUe->txLnk));
5225 /* Adding the UE to the LCG0 list for SR IND */
5226 cmLListAdd2Tail(&ulCell->ueTxLst[0], &ulUe->txLnk);
5227 ulUe->txLnk.node = (PTR)ue;
5231 } /* rgSCHSc1SrRcvd */
5234 * @brief Indication of UL CQI
5238 * Function : rgSCHSc1UlCqiInd
5240 * - Common Scheduler. SC1 does nothing.
5242 * @param[in] RgSchCellCb *cell
5243 * @param[in] RgSchUeCb *ue
5244 * @param[in] TfuUlCqiRpt *ulCqiInfo
5248 PUBLIC Void rgSCHSc1UlCqiInd
5252 TfuUlCqiRpt *ulCqiInfo
5255 PUBLIC Void rgSCHSc1UlCqiInd(cell, ue, ulCqiInfo)
5258 TfuUlCqiRpt *ulCqiInfo;
5261 TRC2(rgSCHSc1UlCqiInd);
5263 /* Stack Crash problem for TRACE5 changes. Added the return below */
5269 * @brief UL Lcg received data updation
5273 * Function : rgSCHSc1UlLcgUpd
5275 * Processing Steps:Sc1 Does nothing
5277 * @param[in] RgSchCellCb *cell
5278 * @param[in] RgSchUeCb *ue
5279 * @param[in] RgInfUeDatInd *datInd
5283 PUBLIC S16 rgSCHSc1UlLcgUpd
5287 RgInfUeDatInd *datInd
5290 PUBLIC S16 rgSCHSc1UlLcgUpd(cell, ue)
5293 RgInfUeDatInd *datInd;
5297 TRC2(rgSCHSc1UlLcgUpd);
5303 /***********************************************************
5305 * Func : rgSCHSc1UlUeRefresh
5307 * Desc : Handle 'refresh' for uplink part of a UE
5308 * (ie UE's uplink AMBR and uplink GBR LCGs are
5309 * refreshed at this point)
5317 **********************************************************/
5319 PUBLIC Void rgSCHSc1UlUeRefresh
5325 PUBLIC Void rgSCHSc1UlUeRefresh(cell, ue)
5330 TRC2(rgSCHSc1UlUeRefresh);
5331 rgSCHSc1UlPosnUeInQ(cell, ue);
5336 * @brief This function Processes the Final Allocations
5337 * made by the RB Allocator against the requested
5338 * UE data Trans Allocations.
5342 * Function: rgSCHSc1UlDatTransAllocFnlz
5343 * Purpose: This function Processes the Final Allocations
5344 * made by the RB Allocator against the requested
5345 * UE data Trans Allocations .
5347 * Invoked by: Scheduler
5349 * @param[in] RgSchCellCb *cell
5350 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
5355 PRIVATE Void rgSCHSc1UlDatTransAllocFnlz
5358 RgSchCmnUlRbAllocInfo *allocInfo
5361 PRIVATE Void rgSCHSc1UlDatTransAllocFnlz(cell, allocInfo)
5363 RgSchCmnUlRbAllocInfo *allocInfo;
5369 RgSchDrxUeCb *drxUe = NULLP;
5370 CmLListCp ulInactvLst; /* list of UE's becoming UL-inactive */
5371 TRC2(rgSCHSc1UlDatTransAllocFnlz);
5373 cmLListInit(&ulInactvLst);
5374 node = allocInfo->schdUeLst.first;
5377 ue = (RgSchUeCb *)node->node;
5379 ueUl = RG_GET_SC1_UE_UL(ue, cell);
5381 if (ue->isDrxEnabled)
5383 if(ueUl->srRcvd == TRUE)
5385 drxUe = RG_SCH_DRX_GET_UE(ue);
5386 drxUe->drxUlInactvMask |= RG_SCH_DRX_SR_BITMASK;
5388 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
5390 ue->ul.ulInactvMask |= RG_DRX_INACTIVE;
5391 /* Add to Ul inactive List */
5392 ue->ulDrxInactvLnk.node = (PTR)ue;
5393 cmLListAdd2Tail(&ulInactvLst,&(ue->ulDrxInactvLnk));
5395 drxUe->srRcvd = FALSE;
5398 /* Reset no matter */
5399 ueUl->srRcvd = FALSE;
5400 /* Reposition UE in Qs */
5401 rgSCHSc1UlPosnUeInQ(cell, ue);
5405 rgSCHCmnHdFddUpdULMark (cell,ue);
5408 /* reset the UE UL allocation Information */
5409 rgSCHCmnUlUeResetTemp(cell, ue);
5411 rgSCHSc1UlHndlInActUes(cell, &ulInactvLst);
5412 node = allocInfo->nonSchdUeLst.first;
5415 ue = (RgSchUeCb *)node->node;
5417 /* reset the UE UL allocation Information */
5418 rgSCHCmnUlUeResetTemp(cell, ue);
5425 * @brief This function Processes the Final Allocations
5426 * made by the RB Allocator against the requested
5427 * cont res Allocations.
5431 * Function: rgSCHSc1UlContResAllocFnlz
5432 * Purpose: This function Processes the Final Allocations
5433 * made by the RB Allocator against the requested
5434 * cont res Allocations .
5436 * Invoked by: Scheduler
5438 * @param[in] RgSchCellCb *cell
5439 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
5444 PRIVATE Void rgSCHSc1UlContResAllocFnlz
5447 RgSchCmnUlRbAllocInfo *allocInfo
5450 PRIVATE Void rgSCHSc1UlContResAllocFnlz(cell, allocInfo)
5452 RgSchCmnUlRbAllocInfo *allocInfo;
5455 RgSchSc1UlCell *sc1UlCell = RG_GET_SC1_CELL_UL(cell);
5459 TRC2(rgSCHSc1UlContResAllocFnlz);
5461 node = allocInfo->schdContResLst.first;
5464 ue = (RgSchUeCb *)node->node;
5469 rgSCHCmnHdFddUpdULMark (cell,ue);
5472 ueUl = RG_GET_SC1_UE_UL(ue, cell);
5474 /* Remove UE from Cont Res Q */
5475 cmLListDelFrm(&sc1UlCell->contResLst,
5477 ueUl->contResLnk.node = NULLP;
5478 /* reset the UE UL allocation Information */
5479 rgSCHCmnUlUeResetTemp(cell, ue);
5482 node = allocInfo->nonSchdContResLst.first;
5485 ue = (RgSchUeCb *)node->node;
5487 /* reset the UE UL allocation Information */
5488 rgSCHCmnUlUeResetTemp(cell, ue);
5495 * @brief This function Processes the Final Allocations
5496 * made by the RB Allocator against the requested.
5500 * Function: rgSCHSc1UlAllocFnlz
5501 * Purpose: This function Processes the Final Allocations
5502 * made by the RB Allocator against the requested.
5504 * Invoked by: Common Scheduler
5506 * @param[in] RgSchCellCb *cell
5507 * @param[in] RgSchCmnDlRbAllocInfo *allocInfo
5512 PUBLIC Void rgSCHSc1UlAllocFnlz
5515 RgSchCmnUlRbAllocInfo *allocInfo
5518 PUBLIC Void rgSCHSc1UlAllocFnlz(cell, allocInfo)
5520 RgSchCmnUlRbAllocInfo *allocInfo;
5523 TRC2(rgSCHSc1UlAllocFnlz);
5525 rgSCHSc1UlContResAllocFnlz(cell, allocInfo);
5526 rgSCHSc1UlDatTransAllocFnlz(cell, allocInfo);
5533 * @brief Scheduler invocation
5537 * Function: rgSCHSc1UlActvtUe
5538 * Purpose: Put back the UE in to appropriate Qs.
5540 * Invoked by: Common Scheduler
5542 * @param[in] RgSchCellCb *cell
5543 * @param[in] RgSchUeCb *ue
5547 PUBLIC Void rgSCHSc1UlActvtUe
5553 PUBLIC Void rgSCHSc1UlActvtUe(cell, ue)
5558 TRC2(rgSCHSc1UlActvtUe);
5560 rgSCHSc1UlPosnUeInQ(cell, ue);
5565 * @brief Scheduler invocation
5569 * Function: rgSCHSc1UlHndlInActUes
5570 * Purpose: The list of inactive UEs present in inactvLst should
5571 * be removed from the scheduling Qs.
5572 * But store the information pertaining to which Qs,
5573 * were they belonging to. This information shall be used
5574 * to put them back in appropriate Qs when their Activation
5577 * Invoked by: Common Scheduler (TTI processing)
5579 * @param[in] RgSchCellCb *cell
5580 * @param[out] CmLListCp *inactvLst
5584 PUBLIC Void rgSCHSc1UlHndlInActUes
5587 CmLListCp *inactvLst
5590 PUBLIC Void rgSCHSc1UlHndlInActUes(cell, inactvLst)
5592 CmLListCp *inactvLst;
5597 RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
5598 CmLList *node = inactvLst->first;
5600 TRC2(rgSCHSc1UlHndlInActUes);
5604 ue = (RgSchUeCb *)node->node;
5606 ulUe = RG_GET_SC1_UE_UL(ue, cell);
5607 if(ulUe->txLnk.node)
5609 cmLListDelFrm(&(cellUl->ueTxLst[ulUe->qId]), &(ulUe->txLnk));
5610 /* This is required as lcg bs might change during
5611 * inactivity to activity. So we need to recompute
5613 ulUe->txLnk.node = NULLP;
5615 /* Do not remove UE from contResLst */
5620 * @brief Scheduler invocation
5624 * Function: rgSCHSc1DlProcRmvFrmRetx
5625 * Purpose: To remove the Harq process from the cell and from the UE
5626 * retransmission list
5628 * Invoked by: Common Scheduler (TTI processing)
5630 * @param[in] RgSchCellCb *cell
5631 * @param[in] RgSchUeCb *ue;
5632 * @param[in] RgSchDlHqProcCb *hqP
5637 PUBLIC Void rgSCHSc1DlProcRmvFrmRetx(
5640 RgSchDlHqProcCb *hqP
5643 PUBLIC Void rgSCHSc1DlProcRmvFrmRetx(cell, ue, hqP)
5646 RgSchDlHqProcCb *hqP;
5649 TRC2(rgSCHSc1DlProcRmvFrmRetx);
5650 /* Remove the HqP from retx Queue.
5652 rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
5653 rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
5660 /**********************************************************************
5663 **********************************************************************/