[Epic-ID: ODUHIGH-464][Task-ID: ODUHIGH-483] Memeory related fix in FDD and TDD mode
[o-du/l2.git] / src / 5gnrsch / rg_sch_sc1.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /************************************************************************
20  
21      Name:     LTE-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for scheduler 1
26   
27      File:     rg_sch_sc1.c
28   
29 **********************************************************************/
30
31 /** @file rg_sch_sc1.c
32 @brief The scheduling functionality is implemented in this file.
33 */
34
35
36 /* header include files -- defines (.h) */
37 #include "common_def.h"
38 #include "lrg.h"
39 #include "rgr.h"
40 #include "rgm.h"
41 #include "tfu.h"
42 #include "rg_env.h"
43 #include "rg_sch_inf.h"
44 #include "rg_sch_err.h"
45 #include "rg_sch.h"
46 #include "rg_sch_cmn.h"
47 #include "rg_sch_sc1.h"
48
49 /* header/extern include files (.x) */
50 #include "tfu.x"           /* RGU types */
51 #include "lrg.x"           /* layer management typedefs for MAC */
52 #include "rgr.x"           /* layer management typedefs for MAC */
53 #include "rgm.x"           /* layer management typedefs for MAC */
54 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
55 #include "rg_sch.x"        /* typedefs for Scheduler */
56 #include "rg_sch_cmn.x"
57 #include "rg_sch_sc1.x"    /* typedefs for SC1 Scheduler */
58
59
60
61
62 #ifdef __cplusplus
63 extern "C" {
64 #endif /* __cplusplus */
65
66 /* Functions called from outside */
67 static S16 rgSCHSc1RgrDlCellRecfg ARGS((
68 RgSchCellCb             *cell,
69 RgrCellRecfg            *recfg,
70 RgSchErrInfo            *err
71 ));
72
73 /*--------------------------*
74  * DL SCHED STATIC declarations START
75  *---------------------------*/
76 static Void rgSCHSc1DlSvcAddToSchd ARGS((
77 RgSchCellCb                *cell,
78 RgSchDlLcCb                *svc
79 ));
80 static Void rgSCHSc1DlAdd2UeSchdSvcs ARGS((
81 RgSchCellCb                *cell,
82 RgSchUeCb          *ue,
83 RgSchDlLcCb        *svc
84 ));
85 static Void rgSCHSc1DlRmvUeFrmPrioQs ARGS((
86 RgSchCellCb  *cell,
87 RgSchUeCb    *ue
88 ));
89 static Void rgSCHSc1DlSuspendUe ARGS((
90 RgSchCellCb  *cell,
91 RgSchUeCb    *ue
92 ));
93 static Void rgSCHSc1DlInactvtUe ARGS((
94 RgSchCellCb  *cell,
95 RgSchUeCb    *ue
96 ));
97 static Void rgSCHSc1DlProcRmvFrmCellRetx ARGS((
98 RgSchCellCb                *cell,
99 RgSchDlHqProcCb            *hqP
100 ));
101 static Void rgSCHSc1DlProcRmvFrmUeRetx ARGS((
102 RgSchCellCb                *cell,
103 RgSchUeCb                  *ue,
104 RgSchDlHqProcCb            *hqP
105 ));
106 static Void rgSCHSc1DlMngPrio0SvcPosn ARGS((
107 RgSchCellCb                *cell,
108 RgSchUeCb                  *ue,
109 RgSchDlLcCb                *svc
110 ));
111 static Void rgSCHSc1DlMngGbrSvcPosn ARGS((
112 RgSchCellCb                *cell,
113 RgSchUeCb                  *ue,
114 RgSchDlLcCb                *svc
115 ));
116 static Void rgSCHSc1DlMngAmbrSvcPosn ARGS((
117 RgSchCellCb                *cell,
118 RgSchUeCb                  *ue,
119 RgSchDlLcCb                *svc
120 ));
121 static Void rgSCHSc1DlMngSvcPosn ARGS((
122 RgSchCellCb                *cell,
123 RgSchUeCb                  *ue,
124 RgSchDlLcCb                *svc
125 ));
126 static Void rgSCHSc1DlUeAddToSchd ARGS((
127 RgSchCellCb                *cell,
128 RgSchUeCb                  *ue
129 ));
130 static Void rgSCHSc1DlTaCmd ARGS((
131 RgSchCellCb           *cell,
132 RgSchCmnDlRbAllocInfo *allocInfo
133 ));
134 static Void rgSCHSc1DlInitQueues ARGS((
135 RgSchSc1DlCell *cellDl
136 ));
137 static Void rgSCHSc1DlDeinitQueues ARGS((
138 RgSchSc1DlCell *cellDl
139 ));
140 static Void rgSCHSc1DlAdd2UeLcsWithData ARGS((
141 RgSchCellCb                *cell,
142 RgSchUeCb                  *ue,
143 RgSchDlLcCb                *svc
144 ));
145 static Void rgSCHSc1DlRmFrmUeLcsWithData ARGS((
146 RgSchCellCb                *cell,
147 RgSchUeCb                  *ue,
148 RgSchDlLcCb                *svc
149 ));
150 /*--------------------------*
151  * UL SCHED STATIC declarations START
152  *---------------------------*/
153 static Void rgSCHSc1UlPosnUeInQ ARGS((
154 RgSchCellCb         *cell,
155 RgSchUeCb           *ue
156 ));
157 static Void rgSCHSc1UlSchdUeTxLst ARGS((
158 RgSchCellCb         *cell,
159 CmLListCp             *ueTxLst,
160 RgSchCmnUlRbAllocInfo *allocInfo,
161 uint8_t                    *remUe
162 ));
163 static Void rgSCHSc1DlProcRmvFrmRetx ARGS((
164 RgSchCellCb                *cell,
165 RgSchUeCb                  *ue,
166 RgSchDlHqProcCb            *hqP
167 ));
168 Void rgSCHSc1DlScanUpdPdbPrio ARGS((
169 RgSchCellCb *cell
170 ));
171 S16 rgSCHSc1DlFillFlowCntrlInfo ARGS(( 
172 RgSchCellCb    *cell,
173 RgInfSfAlloc   *sfAlloc
174 ));
175
176 static Void rgSCHSc1DlPreSchd ARGS ((
177 RgSchCellCb   *cell
178 ));
179 static Void rgSCHSc1DlPstSchd ARGS ((
180  Inst       schInst
181 ));
182 #ifdef __cplusplus
183 }
184 #endif /* __cplusplus */
185
186
187
188
189 /***************** SC1 DL SCHEDULER FUNCTION DEFNs START HERE ********/
190 \f
191 /***********************************************************
192  *
193  *     Func : rgSCHSc1DlUeReset 
194  *        
195  *     Desc : Out of Meas Gap. Reposition the UEs Retx Hq Procs,
196  *            and Svc in respective Prio Qs.
197  *            
198  *
199  *     Ret  : Void 
200  *
201  *     Notes:
202  *
203  *     File : 
204  *
205  **********************************************************/
206 Void rgSCHSc1DlUeReset(RgSchCellCb *cell,RgSchUeCb *ue)
207 {
208
209    rgSCHSc1DlSuspendUe(cell, ue);
210
211    return;
212 }
213
214 \f
215 /***********************************************************
216  *
217  *     Func : rgSCHSc1DlActvtUe
218  *        
219  *     Desc : Out of Meas Gap. Reposition the UEs Retx Hq Procs,
220  *            and Svc in respective Prio Qs.
221  *            
222  *
223  *     Ret  : Void 
224  *
225  *     Notes:
226  *
227  *     File : 
228  *
229  **********************************************************/
230 Void rgSCHSc1DlActvtUe(RgSchCellCb *cell,RgSchUeCb  *ue)
231 {
232    RgSchSc1DlUe    *ueDl = RG_GET_SC1_UE_DL(ue, cell);
233    CmLListCp       *lst;
234    CmLList         *node;
235    RgSchDlHqProcCb *hqP;
236    RgSchDlLcCb     *svc;
237    uint8_t         idx;
238
239    /* Add UE's HqProcs From UERetxLst to CellRetxLst */
240    lst = &ueDl->retxHqProcs;
241    node = lst->first;
242    while(node)
243    {
244       hqP = (RgSchDlHqProcCb *)node->node;
245       node = node->next;
246       rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
247       rgSCHSc1DlProcAddToCellRetx(cell, hqP);
248    }
249
250    /* Iterate over all the Services if bo != 0 then add */
251    for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx)
252    {
253       svc = ue->dl.lcCb[idx];
254       if (svc == NULLP)
255       {
256          continue;
257       }
258       rgSCHSc1DlMngSvcPosn(cell, ue, svc);
259    } 
260
261    /* Add UE to AMBR Prio Q */
262    if (ueDl->ambrSvc)
263    {
264       rgSCHSc1DlUeAddToSchd(cell, ue);
265    }
266
267    return;
268 }
269
270 \f
271 /***********************************************************
272  *
273  *     Func : rgSCHSc1DlUeRefresh
274  *        
275  *     Desc : Handle 'refresh' for Downlink
276  *            (ie UE's downlink AMBR and downlink GBR LCGs are
277  *            refreshed at this point)
278  *
279  *     Ret  : Void 
280  *
281  *     Notes:
282  *
283  *     File : 
284  *
285  **********************************************************/
286 Void rgSCHSc1DlUeRefresh(RgSchCellCb *cell,RgSchUeCb *ue)
287 {
288    RgSchSc1DlUe   *ueDl = RG_GET_SC1_UE_DL(ue, cell);
289                            /*cell added as part of CA dev*/
290    RgSchCmnDlSvc *svcCmn;
291    RgSchSc1DlSvc  *svcSc1;
292    CmLListCp   *lst;
293    CmLList     *node;
294    RgSchDlLcCb *svc;
295
296    if (ue->dl.ambrCfgd)
297    {
298       ueDl->ambr = ue->dl.ambrCfgd;
299    }
300    else
301    {
302       ueDl->ambr = RG_SC1_MAX_DL_AMBR;
303    }
304
305    if (ueDl->ambrSvc != NULLP)
306    {
307       ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, ueDl->ambrSvc->bo);
308       /* Update UEs position in the Queue */
309       rgSCHSc1DlUeAddToSchd(cell, ue);
310    }
311
312    lst = &ueDl->gbrSvcs;
313    node = lst->first;
314    while (node != NULLP)
315    {
316       svc   = (RgSchDlLcCb *)node->node;
317       svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
318       svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
319       node = node->next;
320       svcSc1->gbr   = svcCmn->gbr;
321       svcSc1->mbr   = svcCmn->mbr;
322       /* Update the SVC's positioning in the Queue */
323       rgSCHSc1DlMngGbrSvcPosn(cell, ue, svc);
324    }
325    return;
326 }
327
328 \f
329 /**
330  * @brief This function removes a HARQ process from the retx
331  *
332  * @details
333  *
334  *     Function: rgSCHSc1DlProcRmvFrmCellRetx
335  *     Purpose:  This function removes a HARQ process from retransmission
336  *               queue. This may be performed when a HARQ ack is successful
337  *               for a retransmission or when the scheduling determines
338  *               to throw out the process due to poor conditions
339  *     
340  *     Invoked by: LIM and Scheduler
341  *     
342  *  @param[in]  RgSchSc1Cb*      cell
343  *  @param[in]  RgDlHqProc*   hqP  
344  *  @return  Void
345  *
346  **/
347 static Void rgSCHSc1DlProcRmvFrmCellRetx(RgSchCellCb *cell,RgSchDlHqProcCb  *hqP)
348 {
349    RgSchSc1DlCell       *cellDl = RG_GET_SC1_CELL_DL(cell);
350    RgSchCmnDlHqProc     *hqProcDl = RG_SCH_CMN_GET_DL_HQP(hqP);
351
352    if (hqProcDl->retxLnk.node != NULLP)
353    {
354       cmLListDelFrm(&cellDl->retxLst[((RgSchSc1DlHqProc *)\
355                     (hqProcDl->schSpfc))->prio], &(hqProcDl->retxLnk));
356       hqProcDl->retxLnk.node = NULLP;
357    }
358    return;
359 }
360
361 \f
362 /**
363  * @brief This function removes a HARQ process from the UE retx
364  *
365  * @details
366  *
367  *     Function: rgSCHSc1DlProcRmvFrmUeRetx
368  *     Purpose:  This function removes a HARQ process from UE retransmission
369  *               queue. 
370  *     
371  *     Invoked by: LIM and Scheduler
372  *     
373  *  @param[in]  RgSchUeCb*    ue
374  *  @param[in]  RgDlHqProc*   hqP  
375  *  @return  Void
376  *
377  **/
378 static Void rgSCHSc1DlProcRmvFrmUeRetx(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchDlHqProcCb *hqP)
379 {
380    RgSchSc1DlUe            *sc1Ue = RG_GET_SC1_UE_DL(ue, cell);
381    RgSchSc1DlHqProc     *hqProcDl = RG_GET_SC1_HQP_DL(hqP);
382
383    if (hqProcDl->retxLnkUe.node != NULLP)
384    {
385       cmLListDelFrm(&sc1Ue->retxHqProcs,
386                   &(hqProcDl->retxLnkUe));
387       hqProcDl->retxLnkUe.node = NULLP;
388    }
389    return;
390 }
391
392 \f
393 /**
394  * @brief This function adds a HARQ process for UEs retxLst
395  *
396  * @details
397  *
398  *     Function: rgSCHSc1DlProcAddToUeRetx
399  *     Purpose:  This function adds a HARQ process to UE retransmission
400  *               queue. This is performed when UE is suspended due
401  *               to measurement gap.
402  *     
403  *     Invoked by: HARQ feedback processing
404  *     
405  *  @param[in]  RgSchUeCb*       ue
406  *  @param[in]  RgSchDlHqProc*   hqP  
407  *  @return  Void
408  *
409  **/
410 static Void rgSCHSc1DlProcAddToUeRetx(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlHqProcCb *hqP)
411 {
412    RgSchSc1DlUe            *sc1Ue = RG_GET_SC1_UE_DL(ue, cell);
413    RgSchSc1DlHqProc     *cmnHqDl = RG_GET_SC1_HQP_DL(hqP);
414
415    cmLListAdd2Tail(&sc1Ue->retxHqProcs, 
416                     &(cmnHqDl->retxLnkUe));
417    cmnHqDl->retxLnkUe.node = (PTR)hqP;
418    return;
419 }
420
421 \f
422 /**
423  * @brief This function adds a HARQ process for retx
424  *
425  * @details
426  *
427  *     Function: rgSCHSc1DlProcAddToCellRetx
428  *     Purpose:  This function adds a HARQ process to retransmission
429  *               queue. This may be performed when a HARQ ack is
430  *               unsuccessful.
431  *     
432  *     Invoked by: HARQ feedback processing
433  *     
434  *  @param[in]  RgSchCellCb*     cell 
435  *  @param[in]  RgSchDlHqProc*   hqP  
436  *  @return  Void
437  *
438  **/
439 Void rgSCHSc1DlProcAddToCellRetx(RgSchCellCb *cell,RgSchDlHqProcCb  *hqP)
440 {
441    RgSchSc1DlCell          *sc1CellDl = RG_GET_SC1_CELL_DL(cell);
442    RgSchCmnDlHqProc     *cmnHqDl = RG_SCH_CMN_GET_DL_HQP(hqP);
443
444
445    if (!RG_SCH_CMN_DL_IS_UE_ACTIVE(hqP->hqE->ue))
446    {
447       rgSCHSc1DlProcAddToUeRetx(cell, hqP->hqE->ue, hqP);
448       return;
449    }
450    cmLListAdd2Tail(&sc1CellDl->retxLst[((RgSchSc1DlHqProc *)\
451                   (cmnHqDl->schSpfc))->prio], &(cmnHqDl->retxLnk));
452    cmnHqDl->retxLnk.node = (PTR)hqP;
453    return;
454 }
455
456 \f
457 /**
458  * @brief This function implements DL RETRANSMISSION allocation
459  *
460  * @details
461  *
462  *     Function: rgSCHSc1DlRetxAlloc
463  *     Purpose:  This function implements downlink scheduler's
464  *               retransmission allocation.
465  *     
466  *     Invoked by: Scheduler
467  *     
468  *  @param[in]  RgSchCellCb           *cell
469  *  @param[in]  RgSchDlSf             *subFrm
470  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo 
471  *  @return  Void
472  *
473  **/
474 static Void rgSCHSc1DlRetxAlloc(RgSchCellCb *cell,RgSchDlSf *subFrm,RgSchCmnDlRbAllocInfo *allocInfo)
475 {
476    uint8_t              i;
477    CmLListCp            *retxLst;
478    CmLList              *node;
479    RgSchDlHqProcCb      *hqP;
480    RgSchSc1DlCell       *sc1CellDl;
481    RgSchSc1DlUe         *sc1DlUe;
482    RgSchCmnDlUe         *cmnUeDl;
483 #if (defined(LTEMAC_SPS) || (!defined(LTE_TDD)))
484    CmLteTimingInfo      schdTime;
485 #endif
486    uint32_t             effBo;
487    RgSchUeCb            *ue = NULLP;
488 #ifdef LTEMAC_HDFDD
489    Bool                 dlAllowed = FALSE;
490 #endif
491    RgSchDlRbAlloc *dlAllocCb;
492
493    sc1CellDl = RG_GET_SC1_CELL_DL(cell);
494 #if (defined(LTEMAC_SPS) || (!defined(LTE_TDD)))
495    schdTime = cell->crntTime;
496
497    /* Increment by DL DELTA to determine the time for which scheduling
498     * is done */
499    RGSCH_INCR_SUB_FRAME(schdTime, RG_SCH_CMN_DL_DELTA);
500 #endif
501    for (i = 0; i < RG_SCH_SC1_DL_PRIOS; i++)
502    {
503       retxLst = &sc1CellDl->retxLst[i];
504       /* allocate bw for the retransmission..should be same are previous */
505       /* If CQI gets worse, as we cannot find same TB size for another   */
506       /* MCS, we just remove this from the retransmission queue          */
507       node = retxLst->first;
508       while (node != NULLP)
509       {
510          hqP = (RgSchDlHqProcCb *)node->node;
511          node = node->next;
512          ue = hqP->hqE->ue;
513
514 #ifndef LTE_TDD
515          if((0 == schdTime.slot) || (5 == schdTime.slot))
516          {
517             Bool reTxAllw;
518             rgSCHCmnChkRetxAllowDtx(cell, ue, hqP, &reTxAllw);
519             if(FALSE == reTxAllw)
520             {
521                continue;
522             }
523          }
524 #endif
525 #ifdef LTEMAC_HDFDD
526          if (ue->hdFddEnbld)
527          {
528             rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed);
529             if (dlAllowed == FALSE)
530             {
531                continue;
532             }
533          }
534 #endif
535          /* This UE is already scheduled for transmission */
536          cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
537                    /*cell added as part of CA dev*/
538 #ifdef LTEMAC_SPS
539          if (RG_SCH_CMN_IS_UE_SPS_SCHDLD(ue, cell, schdTime))
540          {
541             continue;
542          }
543 #endif
544          if (RG_SCH_CMN_IS_UE_SCHDLD(ue, cell))
545          {
546             continue;
547          }
548          effBo = 0;
549          /* Extra check: indicate if there is furtherScope for NewTx
550           * addition for a HqProc. This information will
551           * be utilized by common scheduler, in case of SM
552           * UEs with only one of the TBs retransmitting and the 
553           * other TB can be used for clubbing new TX. */
554          sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
555          dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
556          if (sc1DlUe->lcsWithData.first != NULLP)
557          {
558             dlAllocCb->mimoAllocInfo.hasNewTxData = TRUE; 
559          }
560          /* 3.1 MIMO : last parameter changed */
561          if (rgSCHCmnDlAllocRetxRb(cell, subFrm, ue, 0, &effBo, hqP, allocInfo) !=\
562                ROK)
563          {
564             /* SF/RETX Bandwidth expired */
565             return;
566          }
567          if (effBo == 0)
568          {
569             continue;
570          }
571
572          if ((hqP->tbInfo[0].state == HQ_TB_ACKED)
573             && (hqP->tbInfo[1].state == HQ_TB_ACKED))
574          {
575             rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
576             return;
577          }
578
579          cmnUeDl->proc = hqP;
580          /* 3.1 MIMO moving this call in cmn scheduler */
581          /*rgSCHCmnDlRbInfoAddUeRetx(allocInfo, ue);*/
582       }
583    }
584    return;
585 }
586
587 /***********************************************************
588  *
589  *     Func : rgSCHSc1RlsHqProc
590  *        
591  *     Desc : Toggles the NDI and releases the harq proc.
592  *
593  *     Ret  : Void
594  *
595  *     Notes: 
596  *
597  *     File : 
598  *
599  **********************************************************/
600 static Void rgSCHSc1RlsHqProc(RgSchDlHqProcCb *hqProc)
601 {
602    rgSCHDhmRlsHqProc(hqProc);
603    return;
604 }
605 \f
606 /**
607  * @brief This function implements dedicated logical channel data scheduling
608  *
609  * @details
610  *
611  *     Function: rgSCHSc1DlDedSvcAlloc 
612  *     Purpose:  This function implements dedicated logical 
613  *               channel data scheduling 
614  *     
615  *     Invoked by: Scheduler
616  *     
617  *  @param[in]  RgSchCellCb            *cell
618  *  @param[in]  RgSchDlSf              *subFrm
619  *  @param[in]  RgSchDlLcCb            *svc
620  *  @param[in]  uint32_t                    bo
621  *  @param[in]  RgSchCmnDlRbAllocInfo  *allocInfo
622  *  @return  S16 
623  *
624  **/
625 static S16 rgSCHSc1DlDedSvcAlloc(RgSchCellCb *cell,RgSchDlSf *subFrm,RgSchDlLcCb *svc,uint32_t bo,RgSchCmnDlRbAllocInfo *allocInfo)
626 {
627    RgSchUeCb               *ue;
628    RgSchDlHqProcCb         *proc;
629    uint16_t                rlcHdrEstmt;
630    uint32_t                effBo;
631    RgSchCmnDlCell          *cmnCellDl = RG_SCH_CMN_GET_DL_CELL(cell);
632    RgSchCmnDlSvc           *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
633    RgSchSc1DlSvc           *svcSc1;
634    RgSchCmnDlUe            *ueDl;
635    RgSchSc1DlHqProc        *sc1HqDl;
636    RgSchCmnDlHqProc        *cmnHqDl;
637 #ifdef LTEMAC_SPS
638    CmLteTimingInfo      schdTime;
639 #endif
640 #ifdef LTEMAC_HDFDD
641    Bool                 dlAllowed = FALSE;
642 #endif
643    S16                  ret;
644
645
646    /* Get the UE to which this service belongs to */
647    ue = svc->ue;
648 #ifdef LTEMAC_HDFDD
649       if (ue->hdFddEnbld)
650       {
651          rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed);
652          if (dlAllowed == FALSE)
653          {
654             return ROK;
655          }
656       }
657 #endif
658    ueDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
659           /*cell added as part of CA dev*/ 
660 #ifdef LTEMAC_SPS
661    schdTime = cell->crntTime;
662
663    /* Increment by DL DELTA to determine the time for which scheduling
664     * is done */
665    RGSCH_INCR_SUB_FRAME(schdTime, RG_SCH_CMN_DL_DELTA);
666    if (RG_SCH_CMN_IS_UE_SPS_SCHDLD(ue, cell, schdTime))
667    {
668       return ROK;
669    }
670 #endif
671    if (RG_SCH_CMN_IS_UE_SCHDLD(ue, cell))
672    {
673       proc = (RgSchDlHqProcCb *)(ueDl->proc);
674       /* This UE is selected for retransmission. Hence no further */
675       /* scheduling may be done for this UE                       */
676       if (RG_SCH_CMN_PROC_SLCTD_FOR_RETX(proc))
677       {
678          DU_LOG("\nERROR  -->  SCH : CRNTI:%d rgSCHSc1DlDedSvcAlloc():"
679             "Ue retransmitting",ue->ueId);
680          return ROK;
681       }
682       /* UE is scheduled for either other services or TA */
683       sc1HqDl = RG_GET_SC1_HQP_DL(proc);
684       cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc);
685       if (sc1HqDl->prio > svcCmn->prio)
686       {
687          sc1HqDl->prio = svcCmn->prio;
688       }
689    }
690    else /* First consideration of this UE for scheduling */
691    {
692       if (rgSCHDhmGetAvlHqProc(cell, ue, cmnCellDl->time, &proc) != ROK)
693       {
694          DU_LOG("\nERROR  -->  SCH : CRNTI:%d rgSCHSc1DlDedSvcAlloc():"
695             " No HARQ Proc available", ue->ueId);
696          return ROK;
697       }
698       sc1HqDl = RG_GET_SC1_HQP_DL(proc);
699       cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc);
700       cmnHqDl->totBytes = 0;
701       /* Initialize some of the parameters of the HQ proc */
702       sc1HqDl->prio     = svcCmn->prio;
703    }
704
705    /* Including each SDU's header size */
706    RG_SCH_CMN_DL_GET_HDR_EST(svc, rlcHdrEstmt);
707    bo += rlcHdrEstmt;
708    effBo = 0;
709    ret = rgSCHCmnDlAllocTxRb(cell, subFrm, ue, bo, &effBo, proc, allocInfo);
710    if ((ret != ROK) || (effBo == 0))
711    {
712       /* If no allocations so far, meaning proc obtained now */
713       if (cmnHqDl->totBytes == 0)
714       {
715          rgSCHSc1RlsHqProc(proc);
716          /* Added the handling for removing
717           * UE from txHqPLst and resetting outStndAlloc.*/
718          if(proc->reqLnk.node != (PTR)NULLP)
719          {
720             cmLListDelFrm(&allocInfo->dedAlloc.txHqPLst, &proc->reqLnk);
721             proc->reqLnk.node = (PTR)NULLP;
722          }
723          /*Re-set the outstanding alloc information.*/
724          ueDl->outStndAlloc = 0;
725
726          /* ccpu00126519: proc should be set to NULLP in UE's DL scratch pad info as well. */
727          ueDl->proc = NULLP;
728       }
729       return (ret);
730    }
731    svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
732    svcSc1->hdrEstimate = rlcHdrEstmt;
733    svcSc1->reqBytes = bo;
734    ueDl->proc = proc;
735    cmnHqDl->totBytes += effBo;
736
737    rgSCHSc1DlAdd2UeSchdSvcs(cell, ue, svc);
738    /* 3.1 MIMO moving this call to cmn scheduler */
739    /*rgSCHCmnDlRbInfoAddUeTx(allocInfo, ue); */
740    return ROK;
741 }
742
743 /**
744  * @brief This function adds a SVC to UE's schdSvcsLst. 
745  *
746  * @details
747  *
748  *     Function: rgSCHSc1DlAdd2UeSchdSvcs
749  *     Purpose:  This function adds a SVC to UE's schdSvcsLst. 
750  *     
751  *     Invoked by: Specific Scheduler 
752  *     
753  *  @param[out] RgSchUeCb          *ue
754  *  @param[in]  RgSchDlLcCb        *svc
755  *  @return  Void
756  *
757  **/
758 static Void rgSCHSc1DlAdd2UeSchdSvcs(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
759 {
760    RgSchSc1DlSvc  *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
761    RgSchSc1DlUe   *ueSc1 = RG_GET_SC1_UE_DL(ue, cell);
762
763    /* checking SVC's presence in this lst is unnecessary */
764    cmLListAdd2Tail(&ueSc1->schdSvcs, &svcSc1->schdSvcLnk);
765    svcSc1->schdSvcLnk.node = (PTR)svc;
766    return;
767 }
768
769 \f
770 /**
771  * @brief This function performs new allocations for UEs
772  *
773  * @details
774  *
775  *     Function: rgSCHSc1DlDedTx
776  *     Purpose:  This function implements scheduler for DL allocation for
777  *               new transmissions of UEs.
778  *               1. It performs across 9 priorities that it supports - 
779  *                   This is from 3GPP specifications
780  *               2. There are known number of GBR/MBR queues
781  *               3. The first queue is highest priority queue and is 
782  *                  satisfied completely prior to any other queues. This
783  *                  queue is for RRC signalling.
784  *               4. Futher GBR/MBR queues are satisfied for GBR and then MBR
785  *               5. Subsequently all other queues are looked at for AMBR
786  *     
787  *     Invoked by: Scheduler
788  *     
789  *  @param[in]  RgSchCellCb*     cell
790  *  @param[in]  RgSchDlSf             *subFrm
791  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo 
792  *  @return  Void
793  *
794  **/
795 static Void rgSCHSc1DlDedTx(RgSchCellCb *cell,RgSchDlSf *subFrm,RgSchCmnDlRbAllocInfo *allocInfo)
796 {
797    CmLListCp            *lst;
798    CmLList              *node;
799    RgSchUeCb            *ue = NULLP;
800    RgSchDlLcCb          *svc;
801    uint8_t              i;
802    RgSchSc1DlSvc        *svcSc1;
803    RgSchSc1DlUe         *ueDl;
804    RgSchSc1DlCell       *sc1CellDl = RG_GET_SC1_CELL_DL(cell);
805    
806
807    /* Process the first queue that is for RRC signalling and is of */
808    /* highest priority.                                            */
809    lst  = &sc1CellDl->prioLst[0];
810    node = lst->first;
811    while(node != NULLP)
812    {
813       /* Getting service instead of UE */
814       svc   = (RgSchDlLcCb *)node->node;
815       ue = svc->ue;
816       svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
817       node = node->next;
818       if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, svcSc1->bo, allocInfo) != ROK) 
819       {
820          /* sf bw expired */
821          return;
822       }
823    }
824
825    /* Perform allocation for the GBR transmissions */
826    for(i = RG_SCH_SC1_DL_GBR_PRIO_START; i <= RG_SCH_SC1_DL_GBR_PRIO_END; i++)
827    {
828       lst  = &sc1CellDl->prioLst[i];
829       node = lst->first;
830       while(node != NULLP)
831       {
832          /* Getting service instead of UE */
833          svc   = (RgSchDlLcCb *)node->node;
834          ue = svc->ue;
835          svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
836          node = node->next;
837          if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, svcSc1->effMbr, allocInfo) != ROK) 
838          {
839             /* sf bw expired */
840             return;
841          }
842       }
843    }
844
845    /* To implement AMBR svc scheduling */
846    for(i = RG_SCH_SC1_DL_GBR_PRIO_END + 1; i < RG_SCH_SC1_DL_PRIOS; i++)
847    {
848       lst  = &sc1CellDl->prioLst[i];
849       node = lst->first;
850       while(node != NULLP)
851       {
852          ue = (RgSchUeCb *)node->node;
853          ueDl = RG_GET_SC1_UE_DL(ue, cell);
854          node = node->next;
855          /* Get the Curr ambr svc for which allocation is to be made */
856          svc = ueDl->ambrSvc;
857          if (rgSCHSc1DlDedSvcAlloc(cell, subFrm, svc, ueDl->effAmbr, allocInfo) != ROK) 
858          {
859             /* sf bw expired */
860             return;
861          }
862       }
863    }
864    return;
865 }
866
867 /**
868  * @brief scheduling for a cell
869  *
870  * @details
871  *
872  *     Function : rgSCHSc1DlPreSchd
873  *
874  *     Processing Steps:
875  *     - Nothing to be done in case of RR
876  *
877  *  @param[in]  Inst      schInst
878  *  @return  Void
879  **/
880 static Void rgSCHSc1DlPreSchd( RgSchCellCb   *cell)
881 {
882    
883    return;
884 }
885 /**
886  * @brief scheduling for a cell
887  *
888  * @details
889  *
890  *     Function : rgSCHSc1DlPstSchd
891  *
892  *     Processing Steps:
893  *     - Nothing to be done in case of RR
894  *
895  *  @param[in]  Inst      schInst
896  *  @return  Void
897  **/
898 static Void rgSCHSc1DlPstSchd(Inst  schInst)
899 {
900    
901    return;
902 }
903
904 \f
905 /**
906  * @brief This function implements scheduler DL allocation
907  *
908  * @details
909  *
910  *     Function: rgSCHSc1DlDedNewTx
911  *     Purpose:  This function implements scheduler for DL allocation for
912  *               UEs.
913  *     
914  *     Invoked by: Scheduler
915  *     
916  *  @param[in]  RgSchCellCb           *cell
917  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
918  *  @return  Void
919  *
920  **/
921 static Void rgSCHSc1DlDedNewTx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
922 {
923    RgSchDlSf            *subFrm = allocInfo->dedAlloc.dedDlSf;
924    DU_LOG("\nDEBUG  -->  SCH : rgSCHSc1DlDedNewTx\n");
925
926    /* Now perform the new UE selections */
927    rgSCHSc1DlDedTx(cell, subFrm, allocInfo);
928
929   /* Stack Crash problem for TRACE5 changes. Added the return below */
930   return;
931
932 }
933 /**
934  * @brief This function implements scheduler DL allocation
935  *
936  * @details
937  *
938  *     Function: rgSCHSc1DlDedRetx
939  *     Purpose:  This function implements scheduler for DL allocation for
940  *               UEs.
941  *     
942  *     Invoked by: Scheduler
943  *     
944  *  @param[in]  RgSchCellCb           *cell
945  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo
946  *  @return  Void
947  *
948  **/
949 static Void rgSCHSc1DlDedRetx(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
950 {
951    RgSchDlSf  *subFrm = allocInfo->dedAlloc.dedDlSf;
952    DU_LOG("\nDEBUG  -->  SCH : rgSCHSc1DlDedRetx\n");
953
954    rgSCHSc1DlRetxAlloc(cell, subFrm, allocInfo);
955
956    return;
957
958 }
959
960
961 \f
962 /**
963  * @brief This function adds a service to scheduler
964  *
965  * @details
966  *
967  *     Function: rgSCHSc1DlSvcAddToSchd
968  *     Purpose:  This function adds a service to the list of services
969  *               based on the priority of the services.
970  *     
971  *     Invoked by: BO and Scheduler
972  *     
973  *  @param[in]  RgSchCellCb*  cell
974  *  @param[in]  RgSchUeCb*    ue   
975  *  @return  Void
976  *
977  **/
978 static Void rgSCHSc1DlSvcAddToSchd(RgSchCellCb *cell,RgSchDlLcCb  *svc)
979 {
980    CmLListCp            *lst;
981    CmLList              *node;
982    RgSchDlLcCb          *lSvc;
983    RgSchSc1DlSvc        *svcSc1;
984    RgSchSc1DlSvc        *lSvcSc1;
985    RgSchSc1DlCell       *sc1CellDl = RG_GET_SC1_CELL_DL(cell);
986    RgSchCmnDlSvc        *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
987
988
989    svcSc1 = RG_GET_SC1_SVC_DL(svc->ue,svc,cell);
990    /* The service is already in the scheduler */
991    if (svcSc1->prioLnk.node != NULLP)
992    {
993       return;
994    }
995
996    /* If the priority = 0, it is the highest priority with infinite */
997    /* allowance and the priority is time bound and hence just place */
998    /* it at the end of the queue                                    */
999    if (svcCmn->prio == 0)
1000    {
1001       lst  = &(sc1CellDl->prioLst[0]);
1002       cmLListAdd2Tail(lst, &svcSc1->prioLnk);
1003       svcSc1->prioLnk.node = (PTR)svc;
1004       /* If a svc is put in to cell wide priority Qs
1005        * then add the same to UE's lcsWithData List */
1006       rgSCHSc1DlAdd2UeLcsWithData(cell, svc->ue, svc);
1007       return;
1008    }
1009
1010    /* Handle GBR services. We have them of next importance */
1011    /* check changed from .._START to  .._END */
1012    if (svcCmn->prio <= RG_SCH_SC1_DL_GBR_PRIO_END)
1013    {
1014       if (!RG_SC1_SVC_HAS_DATA(svc,cell))
1015          return;
1016       lst  = &(sc1CellDl->prioLst[svcCmn->prio]);
1017       node = lst->first;
1018       while(node)
1019       {
1020          lSvc = (RgSchDlLcCb *)(node->node);
1021          lSvcSc1 = RG_GET_SC1_SVC_DL(lSvc->ue,lSvc,cell);
1022          if (((svcSc1->effGbr > 0) && 
1023                   (lSvcSc1->effGbr <= svcSc1->effGbr)) ||
1024                ((lSvcSc1->effGbr == 0) && (svcSc1->effMbr > 0) && 
1025                 (lSvcSc1->effMbr <= svcSc1->effMbr)))
1026          {
1027             break;
1028          }
1029          node = node->next;
1030       }
1031       if (node == NULLP)
1032       {
1033          /* We have come to the end of the queue. Let's place it */
1034          /* here irresepctive of effGbr or effMBr                */
1035          cmLListAdd2Tail(lst, &svcSc1->prioLnk);
1036          svcSc1->prioLnk.node = (PTR)svc;
1037       }
1038       else
1039       {
1040          lst->crnt = node;
1041          cmLListInsCrnt(lst, &svcSc1->prioLnk);
1042          svcSc1->prioLnk.node = (PTR)svc;
1043       }
1044       /* If a svc is put in to cell wide priority Qs
1045        * then add the same to UE's lcsWithData List */
1046       rgSCHSc1DlAdd2UeLcsWithData(cell, svc->ue, svc);
1047    }
1048    return;
1049 }
1050
1051
1052 \f
1053 /**
1054  * @brief This function removes a UE from scheduler Queue
1055  *
1056  * @details
1057  *
1058  *     Function: rgSCHSc1DlUeRmvFrmSchd
1059  *     Purpose:  This function removes a UE from the list of UEs
1060  *               based on the priority of the UEs Current AMBR SVC.
1061  *     
1062  *     Invoked by: BO and Scheduler
1063  *     
1064  *  @param[in]  RgSchCellCb*  cell
1065  *  @param[in]  RgSchUeCb*    ue   
1066  *  @return  Void
1067  *
1068  **/
1069 static Void rgSCHSc1DlUeRmvFrmSchd(RgSchCellCb *cell,RgSchUeCb *ue)
1070 {
1071    RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1072    RgSchSc1DlUe   *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1073    CmLListCp   *lst;
1074
1075
1076    lst  = &cellDl->prioLst[ueDl->prio];
1077    if (ueDl->prioLnk.node != NULLP)
1078    {
1079       cmLListDelFrm(lst, &ueDl->prioLnk);
1080       ueDl->prioLnk.node = (PTR)NULLP;
1081       /* If a svc is removed from cell wide priority Qs
1082        * then remove the same from UE's lcsWithData List */
1083       rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, ueDl->ambrSvc);
1084    }
1085    return;
1086 }
1087
1088 \f
1089 /**
1090  * @brief This function removes a SVC from UEs AMBR LIST 
1091  *
1092  * @details
1093  *
1094  *     Function: rgSCHSc1DlSvcRmvFrmUeAmbrLst
1095  *     Purpose:  This function removes a SVC from UEs AMBR List.
1096  *     
1097  *     Invoked by: BO and Scheduler
1098  *     
1099  *  @param[in]  RgSchUeCb*    ue   
1100  *  @param[in]  RgSchDlLcCb*  svc
1101  *  @return  Void
1102  *
1103  **/
1104 static Void rgSCHSc1DlSvcRmvFrmUeAmbrLst(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchDlLcCb  *svc)
1105 {
1106    RgSchSc1DlUe *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1107    RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1108    CmLListCp            *lst;
1109
1110    lst  = &ueDl->ambrLst;
1111    if (svcSc1->prioLnk.node != NULLP)
1112    {
1113       cmLListDelFrm(lst, &svcSc1->prioLnk);
1114       svcSc1->prioLnk.node = (PTR)NULLP;
1115    }
1116    return;
1117 }
1118
1119 \f
1120 /**
1121  * @brief This function adds a SVC to UEs AMBR LIST 
1122  *
1123  * @details
1124  *
1125  *     Function: rgSCHSc1DlSvcAddToUeAmbrLst
1126  *     Purpose:  This function adds a SVC to UEs AMBR List.
1127  *     
1128  *     Invoked by: BO and Scheduler
1129  *     
1130  *  @param[in]  RgSchUeCb*    ue   
1131  *  @param[in]  RgSchDlLcCb*  svc
1132  *  @return  Void
1133  *
1134  **/
1135 static Void rgSCHSc1DlSvcAddToUeAmbrLst(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1136 {
1137    RgSchSc1DlUe    *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1138    CmLList         *node;
1139    RgSchDlLcCb     *lsvc;
1140    RgSchSc1DlSvc   *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1141    RgSchCmnDlSvc   *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1142
1143
1144    /* If svc already present in AMBR List return */
1145    if (svcSc1->prioLnk.node != NULLP)
1146       return;
1147
1148    node = ueDl->ambrLst.first;
1149    while(node)
1150    {
1151       lsvc = (RgSchDlLcCb *)(node->node);
1152       if (((RgSchCmnDlSvc*)(lsvc->sch))->prio > svcCmn->prio)
1153       {
1154          break;
1155       }
1156       node = node->next;
1157    }
1158    if (node == NULLP)
1159    {
1160       cmLListAdd2Tail(&ueDl->ambrLst, &svcSc1->prioLnk);
1161       svcSc1->prioLnk.node = (PTR)svc;
1162    }
1163    else
1164    {
1165       ueDl->ambrLst.crnt = node;
1166       cmLListInsCrnt(&ueDl->ambrLst, &svcSc1->prioLnk);
1167       svcSc1->prioLnk.node = (PTR)svc;
1168    }
1169    
1170    return;
1171 }
1172
1173 \f
1174 /**
1175  * @brief This function removes a service from scheduler
1176  *
1177  * @details
1178  *
1179  *     Function: rgSCHSc1DlSvcRmvFrmSchd
1180  *     Purpose:  This function removes the SVC from the scheduler Qs.
1181  *     
1182  *     Invoked by: BO and Scheduler
1183  *     
1184  *  @param[in]  RgSchCellCb*  cell
1185  *  @param[in]  RgSchUeCb*    ue   
1186  *  @return  Void
1187  *
1188  **/
1189 static Void rgSCHSc1DlSvcRmvFrmSchd(RgSchCellCb *cell,RgSchDlLcCb  *svc)
1190 {
1191    RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1192    RgSchSc1DlSvc *svcDl = RG_GET_SC1_SVC_DL(svc->ue,svc,cell);
1193    RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1194    CmLListCp    *lst;
1195
1196
1197    lst = &(cellDl->prioLst[svcCmn->prio]);
1198    if (svcDl->prioLnk.node != NULLP)
1199    {
1200       cmLListDelFrm(lst, &svcDl->prioLnk);
1201       svcDl->prioLnk.node = NULLP;
1202       /* If a svc is removed from cell wide priority Qs
1203        * then remove the same from UE's lcsWithData List */
1204       rgSCHSc1DlRmFrmUeLcsWithData(cell, svc->ue, svc);
1205    }
1206    return;
1207 }
1208
1209 \f
1210 /**
1211  * @brief This function adds a service to scheduler for a UE
1212  *
1213  * @details
1214  *
1215  *     Function: rgSCHSc1DlSvcAdd
1216  *     Purpose:  This function is made available through a FP for 
1217  *               making scheduler aware of a service added to UE
1218  *     
1219  *     Invoked by: BO and Scheduler
1220  *     
1221  *  @param[in]  RgSchUeCb*        ue   
1222  *  @param[in]  RgSchDlLcCb*      svc   
1223  *  @param[in]  CrgDlLchCfg*   qos
1224  *  @return                    Void 
1225  *
1226  **/
1227 static Void rgSCHSc1DlSvcAdd(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc,RgrDlLchCfg *cfg)
1228 {
1229    RgSchSc1DlUe  *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1230    RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1231    RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1232
1233    UNUSED(cfg);
1234
1235    if (RG_SCH_CMN_SVC_IS_GBR(svc))
1236    {
1237       svcSc1->gbr   = svcCmn->gbr;
1238       svcSc1->mbr   = svcCmn->mbr;
1239       cmLListAdd2Tail(&ueDl->gbrSvcs, &svcSc1->gbrLnk);
1240       svcSc1->gbrLnk.node = (PTR)svc;
1241    }
1242    return;
1243 }
1244
1245 \f
1246 /**
1247  * @brief This function deletes a service from scheduler
1248  *
1249  * @details
1250  *
1251  *     Function: rgSCHSc1DlLcRmv
1252  *     Purpose:  This function is made available through a FP for 
1253  *               making scheduler aware of a service being deleted from UE
1254  *     
1255  *     Invoked by: BO and Scheduler
1256  *     
1257  *  @param[in]  RgSchCellCb*  cell
1258  *  @param[in]  RgSchUeCb*    ue   
1259  *  @param[in]  RgSchDlLcCb*  svc   
1260  *  @return  Void
1261  *
1262  **/
1263 Void rgSCHSc1DlLcRmv(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1264 {
1265    RgSchSc1DlUe  *ueDl;
1266    RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1267    RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1268
1269
1270    if (svcSc1 == NULLP)
1271    {
1272       return;
1273    }
1274    ueDl = RG_GET_SC1_UE_DL(ue, cell);
1275
1276    if (svcCmn->prio == 0)
1277    {
1278       rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1279    }
1280    else if (RG_SCH_CMN_SVC_IS_GBR(svc))
1281    {
1282       if (svcSc1->gbrLnk.node != NULLP)
1283       {
1284          cmLListDelFrm(&ueDl->gbrSvcs, &svcSc1->gbrLnk);
1285          svcSc1->gbrLnk.node = NULLP;
1286       }
1287       rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1288    }
1289    else /* if AMBR service */
1290    {
1291       if (ueDl->ambrSvc == svc)
1292       {
1293          rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1294          rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1295          ueDl->ambrSvc = NULLP;
1296          if (ueDl->ambrLst.first != NULLP)
1297          {
1298             ueDl->ambrSvc = (RgSchDlLcCb *)(ueDl->ambrLst.first->node);
1299             ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svc->bo);
1300             if(ueDl->effAmbr)
1301             {
1302                rgSCHSc1DlUeAddToSchd(cell, ue);
1303             }
1304          }
1305       }
1306       else
1307       {
1308          rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1309       }
1310    }
1311    /* ccpu00117052 - MOD - Passing double pointer
1312    for proper NULLP assignment*/
1313    rgSCHUtlFreeSBuf(cell->instIdx, 
1314          (Data**)(&(RG_SCH_CMN_GET_LC_SCH_SPFC(ue,svc,cell))), (sizeof(RgSchSc1DlSvc)));
1315    return;
1316 }
1317
1318 /**
1319  * @brief This function is invoked as part of SVC reconfig 
1320  *
1321  * @details
1322  *
1323  *     Function: rgSCHSc1DlSvcMod
1324  *     Purpose:  This function is made available through a FP for 
1325  *               making scheduler aware of a service reconfiguration. 
1326  *     
1327  *     Invoked by: Scheduler
1328  *     
1329  *  @param[in]  RgSchDlLcCb*      svc   
1330  *  @param[in]  CrgLchRecfg*   recfg
1331  *  @return     Void 
1332  *
1333  **/
1334 static Void rgSCHSc1DlSvcMod(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc,RgrLchRecfg  *recfg)
1335
1336    RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1337    RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1338
1339    if (RG_SCH_CMN_SVC_IS_GBR(svc))
1340    {
1341       /* Convert the QOS to handle the refresh duration */
1342       svcSc1->gbr   = svcCmn->gbr;
1343       svcSc1->mbr   = svcCmn->mbr;
1344    }
1345    return;
1346 }
1347
1348 /**
1349  * @brief This function adds UE to scheduler for an AMBR service
1350  *
1351  * @details
1352  *
1353  *     Function: rgSCHSc1DlUeAddToSchd
1354  *     Purpose:  This function adds a UE to scheduler for the AMBR
1355  *               service of highest priority.
1356  *     
1357  *     Invoked by: BO and Scheduler
1358  *     
1359  *  @param[in]  RgSchCellCb*      cell
1360  *  @param[in]  RgSchUeCb*        ue   
1361  *  @return                    Void
1362  *
1363  **/
1364 static Void rgSCHSc1DlUeAddToSchd(RgSchCellCb *cell,RgSchUeCb *ue)
1365 {
1366    RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1367    RgSchSc1DlUe   *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1368    RgSchSc1DlUe   *lueDl;
1369    CmLList        *node;
1370    CmLListCp      *lst;
1371    RgSchUeCb      *nodeUe = NULLP;
1372
1373    ueDl->prio = ((RgSchCmnDlSvc *)(ueDl->ambrSvc->sch))->prio;
1374    lst  = &cellDl->prioLst[ueDl->prio]; 
1375    /* if UE already in list, remove and
1376     * readjust */
1377    if (ueDl->prioLnk.node != NULLP)
1378    {
1379       cmLListDelFrm(lst, &ueDl->prioLnk);
1380       ueDl->prioLnk.node = NULLP;
1381       /* If a svc is removed from cell wide priority Qs
1382        * then remove the same from UE's lcsWithData List */
1383       rgSCHSc1DlRmFrmUeLcsWithData(cell, ue, ueDl->ambrSvc);
1384    }
1385    node = lst->first;
1386    while(node)
1387    {
1388       nodeUe = (RgSchUeCb *)(node->node);
1389       lueDl = RG_GET_SC1_UE_DL(nodeUe, cell);
1390       if (lueDl->effAmbr < ueDl->effAmbr)
1391          break;
1392       node = node->next;
1393    }
1394    if (node == NULLP)
1395    {
1396       cmLListAdd2Tail(lst, &ueDl->prioLnk);
1397       ueDl->prioLnk.node = (PTR)ue;
1398    }
1399    else
1400    {
1401       lst->crnt = node;
1402       cmLListInsCrnt(lst, &ueDl->prioLnk);
1403       ueDl->prioLnk.node = (PTR)ue;
1404    }
1405    /* If a svc is put in to cell wide priority Qs
1406     * then add the same to UE's lcsWithData List */
1407    rgSCHSc1DlAdd2UeLcsWithData(cell, ue, ueDl->ambrSvc);
1408    return;
1409 }
1410
1411 \f
1412 /**
1413  * @brief This function implements managing BO for an ABMR service
1414  *
1415  * @details
1416  *
1417  *     Function: rgSCHSc1DlMngAmbrSvcPosn
1418  *     Purpose:  This function should be called whenever there is a 
1419  *               change BO for a AMBR service.
1420  *     
1421  *     Invoked by: BO and Scheduler
1422  *     
1423  *  @param[in]  RgSchCellCb*  cell
1424  *  @param[in]  RgSchUeCb*    ue   
1425  *  @param[in]  RgSchDlLcCb*  svc
1426  *  @return  Void
1427  *
1428  **/
1429 static Void rgSCHSc1DlMngAmbrSvcPosn(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1430 {
1431    RgSchSc1DlUe    *ueDl = RG_GET_SC1_UE_DL(ue, cell);
1432    RgSchSc1DlSvc   *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1433
1434    if (svcSc1->bo == 0)
1435    {
1436       if (ueDl->ambrSvc == svc)
1437       {
1438          rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1439          rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1440          ueDl->ambrSvc = NULLP;
1441          if (ueDl->ambrLst.first != NULLP)
1442          {
1443             ueDl->ambrSvc = (RgSchDlLcCb *)(ueDl->ambrLst.first->node);
1444             ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svcSc1->bo);
1445             if(ueDl->effAmbr)
1446             {
1447                rgSCHSc1DlUeAddToSchd(cell, ue);
1448             }
1449          }
1450       }
1451       else
1452       {
1453          rgSCHSc1DlSvcRmvFrmUeAmbrLst(cell, ue, svc);
1454       }
1455    }
1456    else /* svcSc1->bo != 0 */
1457    {
1458       if (svcSc1->prioLnk.node != NULLP)
1459       {
1460          if (svc == ueDl->ambrSvc)
1461          {
1462             ueDl->effAmbr = RGSCH_MIN(svcSc1->bo, ueDl->ambr);
1463             /* Update UE's position in the scheduler */
1464             if(ueDl->effAmbr)
1465             {
1466                rgSCHSc1DlUeAddToSchd(cell, ue);
1467             }
1468             else
1469             {
1470                rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1471             }
1472          }
1473          return;
1474       }
1475       rgSCHSc1DlSvcAddToUeAmbrLst(cell, ue, svc);
1476       /* Current ambr svc is always the first node of ambrLst.*/ 
1477       if (ueDl->ambrLst.first->node == (PTR)svc)
1478       {
1479          if(ueDl->ambrSvc != svc)
1480          {
1481             if(ueDl->ambrSvc)
1482             {
1483                rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1484             }
1485             ueDl->ambrSvc = svc;
1486             ueDl->effAmbr = RGSCH_MIN(ueDl->ambr, svcSc1->bo);
1487             if(ueDl->effAmbr)
1488             {
1489                rgSCHSc1DlUeAddToSchd(cell, ue);
1490             }
1491          }
1492       }
1493    }
1494    return;
1495 }
1496
1497 \f
1498 /**
1499  * @brief This function updates the scheduler with service for a UE
1500  *
1501  * @details
1502  *
1503  *     Function: rgSCHSc1DlLcBoUpd
1504  *     Purpose:  This function should be called whenever there is a 
1505  *               change BO for a service.
1506  *     
1507  *     Invoked by: BO and Scheduler
1508  *     
1509  *  @param[in]  RgSchCellCb*  cell
1510  *  @param[in]  RgSchUeCb*    ue   
1511  *  @param[in]  RgSchDlLcCb*  svc
1512  *  @return  Void
1513  *
1514  **/
1515 Void rgSCHSc1DlLcBoUpd(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchDlLcCb *svc)
1516 {
1517    RgSchSc1DlSvc   *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1518
1519    if (svcSc1->bo == svc->bo)
1520    {
1521       return;
1522    }
1523    svcSc1->bo = svc->bo;
1524    if (!RG_SCH_CMN_DL_IS_UE_ACTIVE(ue))
1525    {
1526       return;
1527    }
1528    rgSCHSc1DlMngSvcPosn(cell, ue, svc);
1529
1530   /* Stack Crash problem for TRACE5 changes. Added the return below */
1531   return;
1532
1533 }
1534
1535 \f
1536 /**
1537  * @brief This function updates the scheduler with Prio0 service for a UE
1538  *
1539  * @details
1540  *
1541  *     Function: rgSCHSc1DlMngPrio0SvcPosn 
1542  *     Purpose:  This func shall be triggered whenever there is a
1543  *     change in the "Bo yet to be satisfied" field of the service.
1544  *     Appropriately positions the svc in its prio Q.
1545  *     Removes the SVC from the Q if BO is completely satisfied.
1546  *     
1547  *     Invoked by: BO and Scheduler
1548  *     
1549  *  @param[in]  RgSchCellCb*  cell
1550  *  @param[in]  RgSchUeCb*    ue   
1551  *  @param[in]  RgSchDlLcCb*  svc
1552  *  @return  Void
1553  *
1554  **/
1555 static Void rgSCHSc1DlMngPrio0SvcPosn(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchDlLcCb  *svc)
1556
1557    RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1558
1559    /* In this priority, we just add or remove to the queue */
1560    if (svcSc1->bo > 0)
1561    {
1562       rgSCHSc1DlSvcAddToSchd(cell, svc);
1563    }
1564    else
1565    {
1566       rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1567    }
1568    return;
1569 }
1570
1571 \f
1572 /**
1573  * @brief This function updates the scheduler with GBR service for a UE
1574  *
1575  * @details
1576  *
1577  *     Function: rgSCHSc1DlMngGbrSvcPosn 
1578  *     Purpose:  This func shall be triggered whenever there is a
1579  *     change in the "Bo yet to be satisfied" field of the service.
1580  *     Appropriately positions the svc in its prio Q.
1581  *     Removes the SVC from the Q if BO is completely satisfied.
1582  *     
1583  *     Invoked by: BO and Scheduler
1584  *     
1585  *  @param[in]  RgSchCellCb*  cell
1586  *  @param[in]  RgSchUeCb*    ue   
1587  *  @param[in]  RgSchDlLcCb*  svc
1588  *  @return  Void
1589  *
1590  **/
1591 static Void rgSCHSc1DlMngGbrSvcPosn(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1592
1593    RgSchSc1DlSvc *svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
1594
1595    /* Handle a GBR service. */
1596    svcSc1->effGbr = RGSCH_MIN(svcSc1->bo, svcSc1->gbr);
1597    svcSc1->effMbr = RGSCH_MIN(svcSc1->bo, svcSc1->mbr);
1598    /* Adjust the SVC priority within the queue */
1599    rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1600    rgSCHSc1DlSvcAddToSchd(cell, svc);
1601    return;
1602 }
1603
1604 \f
1605 /**
1606  * @brief This function updates the scheduler with service for a UE
1607  *
1608  * @details
1609  *
1610  *     Function: rgSCHSc1DlMngSvcPosn 
1611  *     Purpose:  This func shall be triggered whenever there is a
1612  *     change in the "Bo yet to be satisfied" field of the service.
1613  *     Appropriately positions the svc in its prio Q.
1614  *     Removes the SVC from the Q if BO is completely satisfied.
1615  *     
1616  *     Invoked by: BO and Scheduler
1617  *     
1618  *  @param[in]  RgSchCellCb*  cell
1619  *  @param[in]  RgSchUeCb*    ue   
1620  *  @param[in]  RgSchDlLcCb*  svc
1621  *  @return  Void
1622  *
1623  **/
1624 static Void rgSCHSc1DlMngSvcPosn(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchDlLcCb *svc)
1625
1626    RgSchCmnDlSvc *svcCmn = RG_SCH_CMN_GET_DL_SVC(svc);
1627    RgSchSc1DlCell *cellDl = RG_GET_SC1_CELL_DL(cell);
1628
1629    (cellDl->svcMngFunc[svcCmn->prio])(cell, ue, svc);
1630    return; 
1631 }
1632
1633 /*--------------------------*
1634  * DL specific functions END
1635  *---------------------------*/
1636
1637
1638 \f
1639 /**
1640  * @brief Scheduler processing on cell configuration
1641  *
1642  * @details
1643  *
1644  *     Function : rgSCHSc1RgrDlCellCfg
1645  *     
1646  *     This function does requisite initialisation 
1647  *     and setup for scheduler1 when a cell is
1648  *     configured
1649  *
1650  *  @param[in]  RgSchCellCb   *cell
1651  *  @param[in]  RgrCellCfg    *cellCfg
1652  *  @param[out] RgSchErrInfo  *err
1653  *  @return  S16
1654  *      -# ROK 
1655  *      -# RFAILED 
1656  **/
1657 S16 rgSCHSc1RgrDlCellCfg(RgSchCellCb *cell,RgrCellCfg *cellCfg,RgSchErrInfo *err)
1658 {
1659    S16         ret;
1660    RgSchSc1DlCell *cellDl;
1661
1662    if((ret = rgSCHUtlAllocSBuf(cell->instIdx, 
1663       (Data**)&(((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc), \
1664       (sizeof(RgSchSc1DlCell)))) != ROK)
1665    {
1666       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED");
1667       err->errCause = RGSCHERR_SCH_SC1_DL_CFG;
1668       return (ret);
1669    }
1670
1671    cellDl = RG_GET_SC1_CELL_DL(cell);
1672    /* Now perform downlink Queues related initializations  */
1673    rgSCHSc1DlInitQueues(cellDl);
1674    return ROK;
1675 }  /* rgSCHSc1RgrDlCellCfg */
1676
1677 /***********************************************************
1678  *
1679  *     Func : rgSCHSc1DlDeinitQueues
1680  *        
1681  *     Desc : De-initialise downlink scheduler queues
1682  *
1683  *     Ret  : Void
1684  *
1685  *     Notes: 
1686  *
1687  *     File : 
1688  *
1689  **********************************************************/
1690 static Void rgSCHSc1DlDeinitQueues(RgSchSc1DlCell *cellDl)
1691 {
1692    uint8_t i;
1693
1694    for (i = 0; i < RG_SC1_DL_NUM_Q; ++i)
1695    {
1696       cmLListInit(&cellDl->prioLst[i]);
1697       cmLListInit(&cellDl->retxLst[i]);
1698    } 
1699    return;
1700 }
1701
1702
1703 /**
1704  * @brief Scheduler processing for cell delete
1705  *
1706  * @details
1707  *
1708  *     Function : rgSCHSc1DlCellDel
1709  *     
1710  *     This functions de-initialises and frees memory
1711  *     taken up by scheduler1 for the entire cell.
1712  *
1713  *  @param[in]  RgSchCellCb  *cell
1714  *  @return  Void
1715  **/
1716 Void rgSCHSc1DlCellDel(RgSchCellCb  *cell)
1717 {
1718
1719    if (((RgSchSc1DlCell *)((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc) \
1720        == NULLP)
1721    {
1722       return;
1723    }
1724       
1725    /* Perform the deinit for the DL scheduler */
1726    rgSCHSc1DlDeinitQueues(RG_GET_SC1_CELL_DL(cell));
1727    /* ccpu00117052 - MOD - Passing double pointer
1728    for proper NULLP assignment*/
1729    rgSCHUtlFreeSBuf(cell->instIdx, 
1730       (Data**)(&(((RgSchCmnCell*)((cell)->sc.sch))->dl.schSpfc)),
1731       (sizeof(RgSchSc1DlCell)));
1732    return;
1733 }  /* rgSCHSc1DlCellDel */
1734
1735 /**
1736  * @brief UE initialisation for scheduler
1737  *
1738  * @details
1739  *
1740  *     Function : rgSCHSc1RgrDlUeCfg
1741  *     
1742  *     This functions intialises UE specific scheduler
1743  *     information
1744  *
1745  *  @param[in]  RgSchCellCb  *cell
1746  *  @param[in]  RgSchUeCb    *ue
1747  *  @param[int] RgrUeCfg     *ueCfg
1748  *  @param[out] RgSchErrInfo *err
1749  *  @return  S16
1750  *      -# ROK 
1751  *      -# RFAILED 
1752  **/
1753 S16 rgSCHSc1RgrDlUeCfg(RgSchCellCb  *cell,RgSchUeCb *ue,RgrUeCfg *ueCfg,RgSchErrInfo *err)
1754 {
1755    RgSchCmnUe         *ueSchCmn = RG_SCH_CMN_GET_UE(ue, cell);
1756    Inst               inst = cell->instIdx;
1757    RgSchSc1DlUe       *ueDl;
1758
1759
1760    if((rgSCHUtlAllocSBuf(inst, 
1761                (Data**)&(ueSchCmn->dl.schSpfc), (sizeof(RgSchSc1DlUe))) != ROK))
1762    {
1763       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED"
1764                "CRNTI:%d",ue->ueId);
1765       err->errCause = RGSCHERR_SCH_SC1_DL_CFG;
1766       return RFAILED;
1767    }
1768    ueDl = (RgSchSc1DlUe *)ueSchCmn->dl.schSpfc;
1769    if (ue->dl.ambrCfgd)
1770    {
1771       ueDl->ambr = ue->dl.ambrCfgd;
1772    }
1773    else
1774    {
1775       ueDl->ambr = RG_SC1_MAX_DL_AMBR;
1776    }
1777    cmLListInit(&ueDl->lcsWithData);
1778    cmLListInit(&ueDl->gbrSvcs);
1779    cmLListInit(&ueDl->ambrLst);
1780    cmLListInit(&ueDl->schdSvcs);
1781    cmLListInit(&ueDl->retxHqProcs);
1782    return ROK;
1783 }  /* rgSCHSc1RgrDlUeCfg */
1784
1785
1786 /**
1787  * @brief Dl Harq Entity initialization for SC1
1788  *
1789  * @details
1790  *
1791  *     Function : rgSCHSc1DlUeHqEntInit
1792  *
1793  *     Processing Steps:
1794  *      - Create SC1 related information per Harq Entity
1795  *
1796  *  @param[in]  RgrSchCellCb     *cell
1797  *  @param[in]  RgSchUeCb        *ue
1798  *  @return  S16
1799  *      -# ROK
1800  *      -# RFAILED
1801  **/
1802 S16 rgSCHSc1DlUeHqEntInit(RgSchCellCb *cell,RgSchDlHqEnt *hqEnt)
1803 {
1804    RgSchSc1DlHqProc   *hqSpcSch;
1805    RgSchDlHqProcCb    *hqP;
1806    uint8_t            cnt;
1807    /* making use of hqE->sch for one shot allocation 
1808     * of RgSchSc1DlHqProc structures */
1809    if (rgSCHUtlAllocSBuf(cell->instIdx, 
1810             (Data**)&(hqEnt->sch),
1811             (hqEnt->numHqPrcs * sizeof(RgSchSc1DlHqProc))) != ROK)
1812    {
1813       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED CRNTI:%d",hqEnt->ue->ueId);
1814       return RFAILED;
1815    }
1816    hqSpcSch = (RgSchSc1DlHqProc *)(hqEnt->sch);
1817    for(cnt = 0; cnt < hqEnt->numHqPrcs; cnt++)
1818    {
1819       hqP = &hqEnt->procs[cnt];
1820       ((RgSchCmnDlHqProc *)((hqP)->sch))->schSpfc = \
1821                                                     hqSpcSch++;
1822    }
1823    return ROK;
1824 }
1825
1826 /**
1827  * @brief Dl Harq Entity deletion for Sc1
1828  *
1829  * @details
1830  *
1831  *     Function : rgSCHSc1DlUeHqEntDeInit 
1832  *
1833  *     Processing Steps:
1834  *      - Free SC1 related information per Harq Entity
1835  *
1836  *  @param[in]  RgrSchCellCb     *cell
1837  *  @param[in]  RgSchDlHqEnt     *hqE 
1838  *  @return  Void
1839  **/
1840 S16 rgSCHSc1DlUeHqEntDeInit(RgSchCellCb *cell,RgSchDlHqEnt *hqE)
1841 {
1842
1843    if(hqE->sch)
1844    {
1845       rgSCHUtlFreeSBuf(cell->instIdx,
1846       (Data**)(&(hqE->sch)),
1847       (hqE->numHqPrcs * sizeof(RgSchSc1DlHqProc)));
1848    }
1849    else
1850    {
1851       return RFAILED;
1852    }
1853    return ROK;
1854 }
1855 /**
1856  * @brief UE reconfiguration for scheduler
1857  *
1858  * @details
1859  *
1860  *     Function : rgSCHSc1RgrDlUeRecfg
1861  *     
1862  *     This functions updates UE specific scheduler
1863  *     information upon UE reconfiguration
1864  *
1865  *  @param[in]  RgSchCellCb  *cell
1866  *  @param[in]  RgSchUeCb    *ue
1867  *  @param[int] RgrUeRecfg   *ueRecfg
1868  *  @param[out] RgSchErrInfo *err
1869  *  @return  S16
1870  *      -# ROK 
1871  *      -# RFAILED 
1872  **/
1873 S16 rgSCHSc1RgrDlUeRecfg(RgSchCellCb  *cell,RgSchUeCb  *ue,RgrUeRecfg  *ueRecfg,RgSchErrInfo *err)
1874 {
1875    RgSchSc1DlUe *ueDl     = RG_GET_SC1_UE_DL(ue, cell);
1876    RgSchCmnDlUe *ueCmnDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
1877                            /*cell added as part of CA dev*/
1878    RgSchDlHqEnt          *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
1879
1880    if (ue->dl.ambrCfgd)
1881    {
1882       ueDl->ambr = ue->dl.ambrCfgd;
1883    }
1884    else
1885    {
1886       ueDl->ambr = RG_SC1_MAX_DL_AMBR;
1887    }
1888
1889    /* Discarding TB2's context from scheduling Queues.
1890     * Since TB2 transmission needs signalling using 
1891     * TM specific formats. And since during this transient
1892     * period of UE TM Recfg, SCH always uses Format 1A,
1893     * the TB2s are discarded. */
1894    if (ueCmnDl->mimoInfo.forceTD & RG_SCH_CMN_TD_TXMODE_RECFG)
1895    {
1896       /* If HqP is in retx queue only for TB2 retx scheduling
1897        * then remove the harp proc from retx Queue */
1898
1899       /* If Hqp is in retx queue for retx allocation of 
1900        * both TB1 and TB2, then reset TB2's state as ACKED */
1901       RgSchDlHqProcCb    *hqP;
1902       Pst                pst;
1903       RgInfRlsHqInfo     *rlsHqBufs = &(cell->rlsHqArr[cell->crntHqIdx]);
1904       uint8_t                 i;
1905
1906       /* Prepare TB2 release information to be sent to MAC */
1907       rlsHqBufs->numUes = 0;
1908       for(i = 0; i < hqEnt->numHqPrcs; i++)
1909       {
1910          hqP = &hqEnt->procs[i];
1911          rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].rnti = ue->ueId;
1912          rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].hqProcId = hqP->procId;
1913          if (hqP->tbInfo[1].state == HQ_TB_NACKED)
1914          {
1915             if (hqP->tbInfo[0].state != HQ_TB_NACKED)
1916             {
1917                /* Remove the HqP from retx Queue.
1918                   Release HqP.*/
1919                rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
1920                rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
1921             }
1922             rgSCHDhmRlsHqpTb(hqP, 1, TRUE);
1923             rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].tbId[0] = 2;
1924             rlsHqBufs->ueHqInfo[rlsHqBufs->numUes].numOfTBs = 1;
1925          }
1926          rlsHqBufs->numUes++;
1927       }
1928       /* Send the hqProc list for MAC to clear TB1 contents */
1929       if (rlsHqBufs->numUes)
1930       {
1931          rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
1932          RgSchMacRlsHq (&pst, rlsHqBufs);
1933       }
1934    }
1935    return ROK;
1936 }  /* rgSCHSc1RgrDlUeRecfg */
1937
1938 /**
1939  * @brief Removes UEs context from Priority Qs.
1940  *
1941  * @details
1942  *
1943  *     Function : rgSCHSc1DlRmvUeFrmPrioQs
1944  *     
1945  *
1946  *  @param[in]  RgSchCellCb  *cell
1947  *  @param[in]  RgSchUeCb    *ue
1948  *  @return  Void
1949  **/
1950 static Void rgSCHSc1DlRmvUeFrmPrioQs(RgSchCellCb  *cell,RgSchUeCb    *ue)
1951 {
1952    RgSchSc1DlUe         *sc1Ue;
1953    RgSchDlLcCb          *svc;
1954    uint32_t             idx;
1955
1956
1957    sc1Ue = RG_GET_SC1_UE_DL(ue, cell);
1958
1959    /* Remove UE From DL priority queues */
1960    if (sc1Ue->ambrSvc != NULLP)
1961    {
1962       rgSCHSc1DlUeRmvFrmSchd(cell, ue);
1963    }
1964
1965    for (idx = 0; idx < RGSCH_MAX_LC_PER_UE; ++idx)
1966    {
1967       svc = ue->dl.lcCb[idx];
1968       if (svc == NULLP)
1969       {
1970          continue;
1971       }
1972       rgSCHSc1DlSvcRmvFrmSchd(cell, svc);
1973    }
1974    
1975    return;
1976 }  /* rgSCHSc1DlRmvUeFrmPrioQs */
1977
1978 /**
1979  * @brief Inactivate UE reason : measgap, acknaprept, poInactv.
1980  *
1981  * @details
1982  *
1983  *     Function : rgSCHSc1DlInactvtUe
1984  *     
1985  *
1986  *  @param[in]  RgSchCellCb  *cell
1987  *  @param[in]  RgSchUeCb    *ue
1988  *  @return  Void
1989  **/
1990 static Void rgSCHSc1DlInactvtUe(RgSchCellCb  *cell,RgSchUeCb    *ue)
1991 {
1992    RgSchSc1DlCell       *cellDl = RG_GET_SC1_CELL_DL(cell);
1993    RgSchDlHqProcCb      *hqP;
1994    RgSchCmnDlHqProc     *hqProcDl;
1995    uint8_t              i;
1996    RgSchDlHqEnt         *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
1997
1998
1999    /* ccpu00130170: UE related HARQ Procs are cleared only 
2000       if UE's Re-establishment procedure is not in progress*/
2001    if(!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE))
2002    {
2003       /* remove all in use HARQ processes from the subframes.
2004        * Store them in UEs hqProc Lst. Add back to cell's
2005        * retx lst when UE is activated again. */
2006       for(i = 0; i < hqEnt->numHqPrcs; i++)
2007       {
2008          hqP = &hqEnt->procs[i];
2009          hqProcDl = RG_SCH_CMN_GET_DL_HQP(hqP);
2010          /* Remove retx procs from cell's list and 
2011           * add them to UE's List */
2012          if(
2013 #ifdef LTEMAC_SPS
2014             !(RG_SCH_CMN_SPS_DL_IS_SPS_HQP(hqP)) &&
2015 #endif
2016             hqProcDl->retxLnk.node != NULLP)
2017          {
2018             cmLListDelFrm(&cellDl->retxLst[((RgSchSc1DlHqProc *)\
2019                        (hqProcDl->schSpfc))->prio], &(hqProcDl->retxLnk));
2020             hqProcDl->retxLnk.node = NULLP;
2021             rgSCHSc1DlProcAddToUeRetx(cell, ue, hqP);
2022          }
2023       }
2024    }
2025
2026    rgSCHSc1DlRmvUeFrmPrioQs(cell, ue);
2027
2028    return;
2029 }  /* rgSCHSc1DlInactvtUe */
2030
2031
2032 /**
2033  * @brief UE suspension.
2034  *
2035  * @details
2036  *
2037  *     Function : rgSCHSc1DlSuspendUe 
2038  *     
2039  *     Removes UE, its SVCs and its HqPs from CELL WIDE
2040  *     PrioQs and Retx Qs Respectively.
2041  *
2042  *  @param[in]  RgSchCellCb  *cell
2043  *  @param[in]  RgSchUeCb    *ue
2044  *  @return  Void
2045  **/
2046 static Void rgSCHSc1DlSuspendUe(RgSchCellCb  *cell,RgSchUeCb    *ue)
2047 {
2048    RgSchDlHqProcCb      *hqP;
2049    uint8_t              i;
2050    uint8_t              j;
2051    RgSchDlHqEnt         *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
2052
2053
2054    /* remove all in use HARQ processes from the subframes.
2055     * Store them in UEs hqProc Lst. Add back to cell's
2056     * retx lst when UE is activated again. */
2057    for(i = 0; i < hqEnt->numHqPrcs; i++)
2058    {
2059       hqP = &hqEnt->procs[i];
2060       rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
2061       rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
2062       /* Removing the Harq Proc from subframes list */
2063       if (hqP->hqPSfLnk.node != NULLP)
2064       {
2065          if (hqP->pdcch )
2066          {
2067             cmLListDelFrm(&hqP->subFrm->pdcchInfo.pdcchs, 
2068                   &hqP->pdcch->lnk);
2069             cmLListAdd2Tail(&cell->pdcchLst, &hqP->pdcch->lnk);
2070             hqP->pdcch = NULLP;
2071          }
2072          /*CA DEV Start */
2073          rgSCHUtlDlHqPTbRmvFrmTx(hqP->subFrm,hqP,0,FALSE);
2074          /*CA DEV End*/ 
2075          for (j = 0; j < 2; j++)
2076          {
2077             if (hqP->tbInfo[j].state == HQ_TB_WAITING)
2078             {
2079               rgSCHDhmRlsHqpTb(hqP, j, TRUE);
2080             }
2081          }
2082       }
2083    }
2084    rgSCHSc1DlRmvUeFrmPrioQs(cell, ue);
2085
2086    return;
2087 }  /* rgSCHSc1DlSuspendUe */
2088
2089 /***********************************************************
2090  *
2091  *     Func : rgSCHSc1DlScanUpdPdbPrio
2092  *
2093  *     Desc : Increment the pivot and reposition the LCs under the pivot to 
2094  *            new location according to thieir PDB and elapsed time.
2095  *
2096  *     Ret  : Void
2097  *
2098  *     Notes:
2099  *
2100  *     File :
2101  *
2102  **********************************************************/
2103 Void rgSCHSc1DlScanUpdPdbPrio(RgSchCellCb *cell)
2104 {
2105    
2106    return;
2107 }
2108
2109 /**
2110  * @brief Function to update Flow control information 
2111  *        to be sent to MAC.
2112  *
2113  * @details
2114  *
2115  *     Function: rgSCHSc1DlFillFlowCntrlInfo
2116  *
2117  *              update Flow control information 
2118  *
2119  *     Invoked by: 
2120  *         SCHD
2121  *
2122  *     Processing Steps:
2123  *           
2124  *  @param[in] RgSchCellCb       *cell
2125                RgInfSfAlloc    *sfAlloc;
2126  *  @return  S16
2127  *      -# ROK 
2128  **/
2129 S16 rgSCHSc1DlFillFlowCntrlInfo(RgSchCellCb    *cell,RgInfSfAlloc   *sfAlloc)
2130 {
2131   return ROK;
2132 }
2133 /**
2134  * @brief UE deletion for scheduler
2135  *
2136  * @details
2137  *
2138  *     Function : rgSCHSc1DlUeDel
2139  *     
2140  *     This functions deletes all scheduler information
2141  *     pertaining to a UE
2142  *
2143  *  @param[in]  RgSchCellCb  *cell
2144  *  @param[in]  RgSchUeCb    *ue
2145  *  @return  Void
2146  **/
2147 Void rgSCHSc1DlUeDel(RgSchCellCb  *cell,RgSchUeCb    *ue)
2148 {
2149    RgSchDlHqEnt          *hqEnt = RG_SCH_CMN_GET_UE_HQE(ue, cell);
2150    RgSchSc1DlUe *sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
2151
2152
2153    if (sc1DlUe == NULLP)
2154    {
2155       return;
2156    }
2157    if( hqEnt)
2158    {
2159       /* Remove UEs scheduler context */
2160       rgSCHSc1DlSuspendUe(cell, ue);
2161
2162       /* Free all SC1 specific control blocks */
2163       if (hqEnt->sch != NULLP)
2164       {
2165          /* ccpu00117052 - MOD - Passing double pointer
2166             for proper NULLP assignment*/
2167          rgSCHUtlFreeSBuf(cell->instIdx, 
2168                (Data**)(&(hqEnt->sch)), 
2169                (hqEnt->numHqPrcs * sizeof(RgSchSc1DlHqProc)));
2170       }
2171    }
2172
2173    /* ccpu00117052 - MOD - Passing double pointer
2174    for proper NULLP assignment*/
2175    rgSCHUtlFreeSBuf(cell->instIdx, (Data**)(&sc1DlUe), (sizeof(RgSchSc1DlUe))); 
2176
2177    return;
2178 }  /* rgSCHSc1DlUeDel */
2179
2180 /**
2181  * @brief Scheduler invocation on Downlink logical channel addition
2182  *
2183  * @details
2184  *
2185  *     Function : rgSCHSc1RgrLcCfg
2186  *     
2187  *     This functions does required processing when a new
2188  *     (dedicated) logical channel is added. 
2189  *
2190  *  @param[in]  RgSchCellCb  *cell
2191  *  @param[in]  RgSchUeCb    *ue
2192  *  @param[in]  RgSchDlLcCb  *dlLc
2193  *  @param[int] RgrLchCfg    *lcCfg
2194  *  @param[out] RgSchErrInfo *err
2195  *  @return  S16
2196  *      -# ROK 
2197  *      -# RFAILED 
2198  **/
2199 S16 rgSCHSc1RgrLcCfg(RgSchCellCb  *cell,RgSchUeCb    *ue,RgSchDlLcCb  *dlLc,RgrLchCfg *lcCfg,RgSchErrInfo *err)
2200 {
2201    S16      ret;
2202
2203    ret = rgSCHUtlAllocSBuf(cell->instIdx, 
2204       (Data**)&(RG_SCH_CMN_GET_LC_SCH_SPFC(ue,dlLc,cell)), \
2205       (sizeof(RgSchSc1DlSvc)));
2206    if (ret != ROK)
2207    {
2208       DU_LOG("\nERROR  -->  SCH : rgSCHSc1CrgLcCfg():"
2209       "SCH struct alloc failed CRNTI:%d LCID:%d",ue->ueId,lcCfg->lcId);
2210       err->errCause = RGSCHERR_SCH_SC1_DL_CFG;
2211       return (ret);
2212    }
2213
2214    rgSCHSc1DlSvcAdd(cell, ue, dlLc, &lcCfg->dlInfo);
2215    return ROK;
2216 }  /* rgSCHSc1RgrLcCfg */
2217
2218
2219 /**
2220  * @brief Scheduler invocation on logical channel addition
2221  *
2222  * @details
2223  *
2224  *     Function : rgSCHSc1RgrLcRecfg
2225  *     
2226  *     This functions does required processing when an existing
2227  *     (dedicated) logical channel is reconfigured. Assumes lcg
2228  *     pointer in ulLc is set to the old value.
2229  *     Independent of whether new LCG is meant to be configured,
2230  *     the new LCG scheduler info is accessed and possibly modified.
2231  *
2232  *  @param[in]  RgSchCellCb  *cell
2233  *  @param[in]  RgSchUeCb    *ue
2234  *  @param[in]  RgSchDlLcCb  *dlLc
2235  *  @param[int] RgrLchRecfg  *lcRecfg
2236  *  @param[out] RgSchErrInfo *err
2237  *  @return  S16
2238  *      -# ROK 
2239  *      -# RFAILED 
2240  **/
2241 S16 rgSCHSc1RgrLcRecfg(RgSchCellCb  *cell,RgSchUeCb  *ue,RgSchDlLcCb  *dlLc,RgrLchRecfg  *lcRecfg,RgSchErrInfo *err)
2242 {
2243
2244    UNUSED(err);
2245
2246    rgSCHSc1DlSvcMod(cell,ue,dlLc, lcRecfg);
2247
2248    return ROK;
2249 }  /* rgSCHSc1RgrLcRecfg */
2250
2251 \f
2252 /**
2253  * @brief This function handles the reconfiguration of cell 
2254  *
2255  * @details
2256  *
2257  *     Function: rgSCHSc1RgrDlCellRecfg
2258  *     Purpose:  Update the reconfiguration parameters.
2259  *     
2260  *     Invoked by: Scheduler
2261  *     
2262  *  @param[in]  RgSchCellCb*  cell
2263  *  @return  Void
2264  *
2265  **/
2266 static S16 rgSCHSc1RgrDlCellRecfg(RgSchCellCb *cell,RgrCellRecfg *recfg,RgSchErrInfo *err)
2267 {
2268    return ROK;
2269 }
2270
2271
2272 \f
2273 /**
2274  * @brief This function implements scheduler DL allocation
2275  *
2276  * @details
2277  *
2278  *     Function: rgSCHSc1DlTaCmd
2279  *     Purpose:  This function implements scheduler for TA cmd alloc for
2280  *               UEs. The hq proc availed as part of this alloc can be used 
2281  *               by the UEs Dedicated CH transmission allocation.
2282  *     
2283  *     Invoked by: Scheduler
2284  *     
2285  *  @param[in]  RgSchCellCb*     cell
2286  *  @param[out] RgSchCmnDlRbAllocInfo *allocInfo 
2287  *  @return  Void
2288  *
2289  **/
2290 static Void rgSCHSc1DlTaCmd(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2291 {
2292    CmLListCp            *lst;
2293    CmLList              *node;
2294    RgSchDlHqProcCb      *proc;
2295    RgSchUeCb            *ue;
2296    uint32_t             effBo;
2297    RgSchCmnDlCell       *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
2298    RgSchCmnDlUe         *cmnUeDl; 
2299    RgSchSc1DlUe         *ueDl;
2300    RgSchCmnDlHqProc     *cmnHqDl;
2301    RgSchDlSf            *subFrm = allocInfo->dedAlloc.dedDlSf;
2302 #ifdef LTEMAC_HDFDD
2303    Bool                 dlAllowed = FALSE;
2304 #endif
2305
2306    lst  = &cellCmnDl->taLst;
2307    node = lst->first;
2308    while(node)
2309    {
2310       ue = (RgSchUeCb *)node->node;
2311       node = node->next;
2312 #ifdef LTEMAC_HDFDD
2313       if (ue->hdFddEnbld)
2314       {
2315          rgSCHCmnHdFddChkDlAllow ( cell, ue, &dlAllowed);
2316          if (dlAllowed == FALSE)
2317          {
2318             continue;
2319          }
2320       }
2321 #endif
2322       /* If Ue is inactive in DL then ignore */
2323       if (ue->dl.dlInactvMask)
2324       {
2325          continue;
2326       }
2327       cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
2328                 /*cell added as part of CA dev*/
2329       ueDl = RG_GET_SC1_UE_DL(ue, cell);
2330
2331       if (rgSCHDhmGetAvlHqProc(cell, ue, cellCmnDl->time, &proc) != ROK)
2332       {
2333          continue;    
2334       }
2335       /* Initialize some of the parameters of the HQ proc */
2336       cmnHqDl = RG_SCH_CMN_GET_DL_HQP(proc);
2337
2338       effBo = 0;
2339       /* 3.1 MIMO */
2340       cmnHqDl->totBytes = 0;
2341       rgSCHCmnDlAllocTxRb(cell, subFrm, ue, RGSCH_TA_SIZE, &effBo, proc, allocInfo);
2342       if (effBo == 0)
2343       {
2344          /* If no allocations so far, meaning proc obtained now */
2345          if (cmnHqDl->totBytes == 0)
2346          {
2347             rgSCHSc1RlsHqProc(proc);
2348             /* Added the handling for removing
2349              * UE from txHqPLst and resetting outStndalloc.*/
2350             if(proc->reqLnk.node != (PTR)NULLP)
2351             {
2352                cmLListDelFrm(&allocInfo->dedAlloc.txHqPLst, &proc->reqLnk);
2353                proc->reqLnk.node = (PTR)NULLP;
2354             }
2355             /*Re-set the outstanding alloc information.*/
2356             cmnUeDl->outStndAlloc = 0;
2357          }
2358          /* Avl BW could not satisfy even TA so break */
2359          break;
2360       }
2361       ueDl->taReqBytes = RGSCH_TA_SIZE;
2362       cmnUeDl->proc = proc;
2363       cmnHqDl->totBytes += effBo;
2364       /* 3.1 MIMO moving this call to cmn scheduler */
2365       /*rgSCHCmnDlRbInfoAddUeTx(allocInfo, ue);*/
2366    }
2367    return;
2368 }
2369
2370 /**
2371  * @brief Scheduler invocation
2372  *
2373  * @details
2374  *
2375  *     Function: rgSCHSc1DlHndlInActUes
2376  *     Purpose:  The list of inactive UEs present in inactvLst should
2377  *               be removed from the scheduling Qs.
2378  *     
2379  *     Invoked by: Common Scheduler (TTI processing)
2380  *     
2381  *  @param[in]  RgSchCellCb *cell
2382  *  @param[out] CmLListCp   *inactvLst
2383  *  @return  Void
2384  **/
2385 Void rgSCHSc1DlHndlInActUes(RgSchCellCb *cell,CmLListCp *inactvLst)
2386 {
2387    CmLList   *node;
2388    RgSchUeCb *ue;
2389
2390    node = inactvLst->first;
2391    while(node)
2392    {
2393       ue = (RgSchUeCb *)node->node;
2394       node = node->next;
2395       /* Suspend this UE from further scheduling
2396        * till it is activated again. */
2397       rgSCHSc1DlInactvtUe(cell, ue);
2398    }
2399    return;
2400 }
2401 \f
2402 /**
2403  * @brief This function initializes all the data for the scheduler
2404  *
2405  * @details
2406  *
2407  *     Function: rgSCHSc1DlInit
2408  *     Purpose:  This function initializes the following information
2409  *               1. Efficiency table
2410  *               2. CQI to table index - It is one row for upto 3 RBs
2411  *                  and another row for greater than 3 RBs
2412  *     
2413  *               currently extended prefix is compiled out.
2414  *     Invoked by: MAC intialization code..may be ActvInit
2415  *     
2416  *  @return  Void
2417  *
2418  **/
2419 Void rgSCHSc1DlInit(RgDlSchdApis *rgSchDlApis)
2420 {
2421    /* Init the function pointers */
2422    rgSchDlApis->rgSCHRgrDlUeCfg        = rgSCHSc1RgrDlUeCfg;
2423    rgSchDlApis->rgSCHRgrDlUeRecfg      = rgSCHSc1RgrDlUeRecfg;
2424    rgSchDlApis->rgSCHFreeDlUe          = rgSCHSc1DlUeDel;
2425    rgSchDlApis->rgSCHRgrDlCellCfg      = rgSCHSc1RgrDlCellCfg;
2426    rgSchDlApis->rgSCHRgrDlCellRecfg    = rgSCHSc1RgrDlCellRecfg; 
2427    rgSchDlApis->rgSCHFreeDlCell        = rgSCHSc1DlCellDel;
2428    rgSchDlApis->rgSCHRgrDlLcCfg        = rgSCHSc1RgrLcCfg;
2429    rgSchDlApis->rgSCHRgrDlLcRecfg      = rgSCHSc1RgrLcRecfg;
2430    rgSchDlApis->rgSCHFreeDlLc          = rgSCHSc1DlLcRmv;
2431    rgSchDlApis->rgSCHDlNewSched        = rgSCHSc1DlDedNewTx;
2432    rgSchDlApis->rgSCHDlPreSched        = rgSCHSc1DlPreSchd;
2433    rgSchDlApis->rgSCHDlPstSched        = rgSCHSc1DlPstSchd;
2434    rgSchDlApis->rgSCHDlRetxSched       = rgSCHSc1DlDedRetx;
2435    rgSchDlApis->rgSCHDlCeSched         = rgSCHSc1DlTaCmd;
2436    rgSchDlApis->rgSCHDlDedBoUpd        = rgSCHSc1DlLcBoUpd;
2437    rgSchDlApis->rgSCHDlProcAddToRetx   = rgSCHSc1DlProcAddToCellRetx;
2438    rgSchDlApis->rgSCHDlAllocFnlz       = rgSCHSc1DlAllocFnlz;
2439    rgSchDlApis->rgSCHDlCqiInd          = rgSCHSc1DlCqiInd;
2440    rgSchDlApis->rgSCHDlUeRefresh       = rgSCHSc1DlUeRefresh;
2441    rgSchDlApis->rgSCHDlUeReset         = rgSCHSc1DlUeReset;
2442    rgSchDlApis->rgSCHDlActvtUe         = rgSCHSc1DlActvtUe;
2443    rgSchDlApis->rgSCHDlInactvtUes      = rgSCHSc1DlHndlInActUes;
2444    rgSchDlApis->rgSCHDlUeHqEntInit     = rgSCHSc1DlUeHqEntInit;
2445    rgSchDlApis->rgSCHDlUeHqEntDeInit   = rgSCHSc1DlUeHqEntDeInit;
2446    rgSchDlApis->rgSCHDlProcRmvFrmRetx  = rgSCHSc1DlProcRmvFrmRetx; 
2447    rgSchDlApis->rgSCHDlTickForPdbTrkng = rgSCHSc1DlScanUpdPdbPrio;
2448    rgSchDlApis->rgSCHDlFillFlwCtrlInfo = rgSCHSc1DlFillFlowCntrlInfo; 
2449
2450    return;
2451 }
2452
2453
2454
2455
2456 /***********************************************************
2457  *
2458  *     Func : rgSCHSc1DlInitQueues
2459  *        
2460  *     Desc : Initial downlink scheduler queues
2461  *
2462  *     Ret  : Void
2463  *
2464  *     Notes: 
2465  *
2466  *     File : 
2467  *
2468  **********************************************************/
2469 static Void rgSCHSc1DlInitQueues(RgSchSc1DlCell *cellDl)
2470 {
2471    uint8_t i;
2472
2473    for (i = 0; i < RG_SC1_DL_NUM_Q; ++i)
2474    {
2475       cmLListInit(&cellDl->prioLst[i]);
2476       cmLListInit(&cellDl->retxLst[i]);
2477    }
2478    /* Set appropriate "manage svc positioning" function based on
2479     * svc priority as array index */
2480    /* for DCCH svcs */
2481    for (i = 0; i < RG_SCH_SC1_DL_GBR_PRIO_START; i++)
2482    {
2483       cellDl->svcMngFunc[i] = rgSCHSc1DlMngPrio0SvcPosn;
2484    }
2485    /* for GBR svcs */
2486    for (i = RG_SCH_SC1_DL_GBR_PRIO_START; i <= RG_SCH_SC1_DL_GBR_PRIO_END; i++)
2487    {
2488       cellDl->svcMngFunc[i] = rgSCHSc1DlMngGbrSvcPosn;
2489    }
2490    /* for Non-GBR svcs */
2491    for (i = RG_SCH_SC1_DL_GBR_PRIO_END+1; i <= RG_SCH_CMN_MAX_PRIO; i++)
2492    {
2493       cellDl->svcMngFunc[i] = rgSCHSc1DlMngAmbrSvcPosn;
2494    }
2495    return;
2496 }
2497
2498
2499
2500 \f
2501 /**
2502  * @brief This function Processes the Final Allocations
2503  *        made by the RB Allocator against the requested
2504  *        RETX allocations. 
2505  *
2506  * @details
2507  *
2508  *     Function: rgSCHSc1DlRetxAllocFnlz 
2509  *     Purpose : Remove the Retx Hq Proc from the Cell's
2510  *     Retx list, if allocation is successful.
2511  *     Fill the HqProc and PDCCH and append it to the SubFrm.
2512  *     
2513  *               
2514  *     
2515  *     Invoked by: Common Scheduler 
2516  *     
2517  *  @param[in]  RgSchCellCb           *cell
2518  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
2519  *  @return  Void
2520  *
2521  **/
2522 static Void rgSCHSc1DlRetxAllocFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2523 {
2524    CmLList          *node;
2525    RgSchUeCb        *ue;
2526    RgSchDlHqProcCb  *hqP;
2527    RgSchDlRbAlloc *dlAllocCb = NULLP;
2528
2529    node = allocInfo->dedAlloc.schdRetxHqPLst.first;
2530    while(node)
2531    {
2532       hqP = (RgSchDlHqProcCb *)node->node;
2533       ue = hqP->hqE->ue;
2534       node = node->next;
2535       /* Fill PDCCH and assign it to HqP */
2536       dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
2537
2538       rgSCHCmnFillHqPPdcch(cell, dlAllocCb, hqP);
2539 #ifdef LTEMAC_HDFDD
2540       if (ue->hdFddEnbld)
2541       {
2542          rgSCHCmnHdFddUpdDLMark(cell, ue);
2543       }
2544 #endif
2545       /* Extra Check: Retain the hqProc in the RETX Queue if one/more
2546        * TBs of the HqProc are yet to be scheduled for RETX.
2547        * Note: Here we are not tracking at TB Level, the priority Q
2548        * to which it belongs to. The retx prio of transmission is still
2549        * being maintained at hqProc level, rather than at TB level */
2550       if ((hqP->tbInfo[0].state != HQ_TB_NACKED) && 
2551             (hqP->tbInfo[1].state != HQ_TB_NACKED)) {
2552          rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
2553       }
2554       /* reset the UE allocation Information */
2555       rgSCHCmnDlUeResetTemp(ue, hqP);
2556    }
2557
2558    /* Traverse the nonSchdTxUeLst and reset the UE allocation Info */
2559    node = allocInfo->dedAlloc.nonSchdRetxHqPLst.first;
2560    while(node)
2561    {
2562       hqP = (RgSchDlHqProcCb *)node->node;
2563       ue = hqP->hqE->ue;
2564       node = node->next;
2565       /* reset the UE allocation Information */
2566       rgSCHCmnDlUeResetTemp(ue, hqP);
2567    }
2568    return;
2569 }
2570
2571 /* 3.1 MIMO Alloc distribution functions being performed
2572  * TB wise */
2573
2574 \f
2575 /***********************************************************
2576  *
2577  *     Func : rgSCHSc1DlSprTxTbDstn 
2578  *        
2579  *     Desc : Perform Actual allocation distribution among
2580  *     UEs schd svcs and TA for a given spare TB "tbInfo" allocation.
2581  *     spare TB allocation is as a result of 1 RETX TB allocation, when
2582  *     conditions are favourable for 2 TB spatial multiplexing.
2583  *
2584  *     Ret  : Void 
2585  *
2586  *     Notes:
2587  *
2588  *     File : 
2589  *
2590  **********************************************************/
2591 static Void rgSCHSc1DlSprTxTbDstn(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlHqTbCb  *tbInfo,uint32_t  *effAlloc,CmLList **node)
2592 {
2593    RgSchDlLcCb        *svc;
2594    RgSchSc1DlSvc      *svcSc1;
2595    RgSchSc1DlUe       *ueDl = RG_GET_SC1_UE_DL(ue, cell);
2596    uint32_t           bytes;
2597    RgSchLchAllocInfo  lchSchdData;
2598    uint32_t           effBo;
2599    uint32_t           rlcHdrEstmt;
2600
2601
2602    while((*node) && (*effAlloc > 0))
2603    {
2604       svc = (RgSchDlLcCb *)(*node)->node;
2605       *node = (*node)->next;
2606       svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
2607       
2608       RG_SCH_CMN_DL_GET_HDR_EST(svc, rlcHdrEstmt);
2609       /* Update the SVC QOS Param */
2610       if (RG_SCH_CMN_SVC_IS_GBR(svc))
2611       {
2612          effBo = svcSc1->effMbr + rlcHdrEstmt;
2613          bytes = RGSCH_MIN(*effAlloc, effBo);
2614          /* Determine How much BO is satisfied */
2615          if (bytes <= rlcHdrEstmt)
2616          {
2617             break; 
2618          }
2619          (svcSc1->bo <= bytes-rlcHdrEstmt)?\
2620            (svcSc1->bo = 0):\
2621            (svcSc1->bo -= bytes-rlcHdrEstmt);
2622          svc->bo = svcSc1->bo;
2623
2624          /* L2_COUNTERS */
2625 #ifdef LTE_L2_MEAS
2626          /* Increment qciActiveLCs once since this LCs buffer will be present
2627             in Harq process */
2628          if (svc->lcType == CM_LTE_LCH_DTCH)
2629          {
2630             ue->qciActiveLCs[svc->qciCb->qci]++;
2631          }
2632
2633          if ((svc->bo == 0) && (svc->lcType == CM_LTE_LCH_DTCH))
2634          {
2635             if (ue->qciActiveLCs[svc->qciCb->qci])
2636             {
2637                ue->qciActiveLCs[svc->qciCb->qci]--;
2638             }
2639             if (!(ue->qciActiveLCs[svc->qciCb->qci]))
2640             {
2641                svc->qciCb->dlUeCount--;
2642             }
2643          }
2644 #endif
2645          (svcSc1->gbr <= bytes)? (svcSc1->gbr = 0):
2646                                     (svcSc1->gbr -= bytes);
2647          (svcSc1->mbr <= bytes)? (svcSc1->mbr = 0):
2648                                     (svcSc1->mbr -= bytes);
2649       }
2650       else if(RG_SCH_CMN_SVC_IS_AMBR(svc))
2651       {
2652          effBo = ueDl->effAmbr + rlcHdrEstmt;
2653          bytes = RGSCH_MIN(*effAlloc, effBo);
2654          /* Determine How much BO is satisfied */
2655          if (bytes <= rlcHdrEstmt)
2656          {
2657             break; 
2658          }
2659          (svcSc1->bo <= bytes-rlcHdrEstmt)?\
2660            (svcSc1->bo = 0):\
2661            (svcSc1->bo -= bytes-rlcHdrEstmt);
2662
2663          (ueDl->ambr <= bytes)? (ueDl->ambr = 0):
2664                                        (ueDl->ambr -= bytes);
2665       }
2666       else /* Prio 0 SVC */
2667       {
2668          effBo = svcSc1->bo + rlcHdrEstmt;
2669          bytes = RGSCH_MIN(*effAlloc, effBo);
2670          /* Determine How much BO is satisfied */
2671          if (bytes <= rlcHdrEstmt)
2672          {
2673             break; 
2674          }
2675          (svcSc1->bo <= bytes-rlcHdrEstmt)?\
2676            (svcSc1->bo = 0):\
2677            (svcSc1->bo -= bytes-rlcHdrEstmt);
2678       }
2679       /* Position the service accordingly */
2680       rgSCHSc1DlMngSvcPosn(cell, svc->ue, svc);
2681       /* Update effAlloc */
2682       *effAlloc -= bytes;
2683
2684       /* Update DHM for this SVC */
2685       lchSchdData.lcId     = svc->lcId;
2686       lchSchdData.schdData = bytes;
2687       rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, tbInfo);
2688    }
2689    return;
2690 }
2691
2692 \f
2693 /***********************************************************
2694  *
2695  *     Func : rgSCHSc1DlNewTxTbDstn 
2696  *        
2697  *     Desc : Perform Actual allocation distribution among
2698  *     UEs schd svcs and TA for a given TB "tbInfo" allocation.
2699  *     Assumption: TA is given higher priority in Alloc Distribution.
2700  *
2701  *     Ret  : Void 
2702  *
2703  *     Notes:
2704  *
2705  *     File : 
2706  *
2707  **********************************************************/
2708 static Void rgSCHSc1DlNewTxTbDstn(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlHqTbCb  *tbInfo,uint32_t *effAlloc,CmLList **node)
2709 {
2710    RgSchDlLcCb        *svc;
2711    RgSchSc1DlSvc      *svcSc1 = NULLP;
2712    RgSchSc1DlUe       *ueDl = RG_GET_SC1_UE_DL(ue, cell);
2713    uint32_t           bytes;
2714    RgSchLchAllocInfo  lchSchdData;
2715    CmLList            *prev = NULLP;
2716
2717
2718    if (ueDl->taReqBytes)
2719    {
2720       if (ueDl->taReqBytes < *effAlloc)
2721       {
2722          /*TA satisfied, hence remove from TA Lst */
2723          rgSCHCmnRmvFrmTaLst(cell, ue);
2724          /* Indicate to DHM that TA has been scheduled */
2725          rgSCHDhmSchdTa(ue, tbInfo);
2726          *effAlloc -= ueDl->taReqBytes;
2727       }
2728       /* Reset the TA Req Bytes Field */
2729       ueDl->taReqBytes = 0;
2730    }
2731    while((*node) && (*effAlloc > 0))
2732    {
2733       svc = (RgSchDlLcCb *)(*node)->node;
2734       prev = *node;
2735       *node = (*node)->next;
2736       svcSc1 = RG_GET_SC1_SVC_DL(ue,svc,cell);
2737       if (*effAlloc > svcSc1->reqBytes)
2738       {
2739          bytes = svcSc1->reqBytes;
2740          if (bytes <= svcSc1->hdrEstimate)
2741          {
2742             break; 
2743          }
2744          /* 3.1 MIMO updating the reqBytes field */
2745          svcSc1->reqBytes = 0;
2746          svcSc1->bo = 0;
2747       }
2748       else
2749       {
2750          bytes = *effAlloc;
2751          if (bytes <= svcSc1->hdrEstimate)
2752          {
2753             break; 
2754          }
2755          /* 3.1 MIMO updating the reqBytes field */
2756          svcSc1->reqBytes -= bytes;
2757          (svcSc1->bo <= bytes-svcSc1->hdrEstimate)?\
2758            (svcSc1->bo = 0):\
2759            (svcSc1->bo -= bytes-svcSc1->hdrEstimate);
2760       }
2761       svc->bo = svcSc1->bo;
2762
2763       /* L2_COUNTERS */
2764 #ifdef LTE_L2_MEAS
2765
2766       /* Increment qciActiveLCs once since this LCs buffer will be present
2767          in Harq process */
2768       if (svc->lcType == CM_LTE_LCH_DTCH)
2769       {
2770          ue->qciActiveLCs[svc->qciCb->qci]++;
2771       }
2772
2773       if ((svc->bo == 0) && (svc->lcType == CM_LTE_LCH_DTCH))
2774       {
2775          if (ue->qciActiveLCs[svc->qciCb->qci])
2776          {
2777             ue->qciActiveLCs[svc->qciCb->qci]--;
2778          }
2779          if (!(ue->qciActiveLCs[svc->qciCb->qci]))
2780          {
2781             svc->qciCb->dlUeCount--;
2782          }
2783       }
2784 #endif
2785
2786       /* Update the SVC QOS Param */
2787       if (RG_SCH_CMN_SVC_IS_GBR(svc))
2788       {
2789          (svcSc1->gbr <= bytes)? (svcSc1->gbr = 0):
2790                                     (svcSc1->gbr -= bytes);
2791          (svcSc1->mbr <= bytes)? (svcSc1->mbr = 0):
2792                                     (svcSc1->mbr -= bytes);
2793       }
2794       else if(RG_SCH_CMN_SVC_IS_AMBR(svc))
2795       {
2796          (ueDl->ambr <= bytes)? (ueDl->ambr = 0):
2797                                        (ueDl->ambr -= bytes);
2798       }
2799       /* Position the service accordingly */
2800       rgSCHSc1DlMngSvcPosn(cell, svc->ue, svc);
2801       /* Update effAlloc */
2802       *effAlloc -= bytes;
2803
2804       /* Update DHM for this SVC */
2805       lchSchdData.lcId     = svc->lcId;
2806       lchSchdData.schdData = bytes;
2807       rgSCHDhmAddLcData(cell->instIdx, &lchSchdData, tbInfo);
2808    }
2809    /* If no more scheduled LCs for TB data distribution
2810     * then distribute the spare TB data among the LCs
2811     * of the UE with non-zero BO. This is effective for 
2812     * schedulers work on LC level priorities rather than
2813     * UE level. */
2814    if ((*node == NULLP) && (svcSc1) && (svcSc1->reqBytes == 0))
2815    {
2816       rgSCHSc1DlSprTxTbDstn(cell, ue, tbInfo, effAlloc,
2817                             &ueDl->lcsWithData.first);
2818       *node = NULLP;
2819       return;
2820    }
2821    /* make sure node points to the svc not completely
2822     * satisfied.
2823     * make sure if not served completely then 
2824     * the other TB allocation accomodates the same */
2825    *node = prev;
2826    return;
2827 }
2828
2829
2830 \f
2831 /***********************************************************
2832  *
2833  *     Func : rgSCHSc1DlNewTxUeFnlz 
2834  *        
2835  *     Desc : Perform allocation Distribution from scheduled TB
2836  *            among the list of services considered for scheduling.
2837  *
2838  *     Ret  : Void 
2839  *
2840  *     Notes:
2841  *
2842  *     File : 
2843  *
2844  **********************************************************/
2845 static Void rgSCHSc1DlNewTxUeFnlz (RgSchCellCb  *cell,RgSchCmnDlRbAllocInfo *allocInfo,RgSchUeCb *ue)
2846 {
2847    CmLList            *node;
2848    RgSchSc1DlUe       *ueDl = RG_GET_SC1_UE_DL(ue, cell);
2849    RgSchCmnDlUe       *cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
2850                                  /*cell added as part of CA dev*/
2851    /* 3.1 MIMO Distribute data of each TB across services */
2852    RgSchDlRbAlloc *dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
2853    uint32_t           remTb1Bytes = dlAllocCb->tbInfo[0].bytesAlloc;
2854    uint32_t           remTb2Bytes = dlAllocCb->tbInfo[1].bytesAlloc;
2855    uint32_t           effAlloc = 0;
2856    /*ccpu00120365-ADD-added to code to check if second TB is utilized */
2857    uint32_t           tb2Bytes = 0;
2858
2859
2860
2861    /* 3.1 MIMO Consider the allocation of New TX TB for distribution */
2862    /* Handle schd services */
2863    node = ueDl->schdSvcs.first;
2864    if (remTb1Bytes){
2865       effAlloc += remTb1Bytes;
2866       rgSCHSc1DlNewTxTbDstn(cell, ue, &cmnUeDl->proc->tbInfo[0],\
2867             &remTb1Bytes, &node);
2868       /* In the event that TB1 is not completely filled by the DL LCs
2869        * BO, consider the reducing the iMcs for increasing redundancy
2870        * and hence reception quality at UE */
2871       rgSCHCmnRdcImcsTxTb(dlAllocCb, 0, 
2872             dlAllocCb->tbInfo[0].bytesAlloc - remTb1Bytes);
2873    }
2874    
2875    /*ccpu00120365-ADD-assigning value of remTb2Bytes before utilization */
2876    tb2Bytes = remTb2Bytes;
2877    
2878    /* Extra check for a non SM UE allocation */
2879    if (remTb2Bytes){
2880       effAlloc += remTb2Bytes;
2881       rgSCHSc1DlNewTxTbDstn(cell, ue, &cmnUeDl->proc->tbInfo[1],\
2882             &remTb2Bytes, &node);
2883       /* In the event that TB2 is not completely filled by the DL LCs
2884        * BO, consider the reducing the iMcs for increasing redundancy
2885        * and hence reception quality at UE */
2886       rgSCHCmnRdcImcsTxTb(dlAllocCb, 1, 
2887             dlAllocCb->tbInfo[1].bytesAlloc - remTb2Bytes);
2888    }
2889
2890    /* ccpu00120365-ADD-Disable the second TB as the second TB is not
2891     * utilized */
2892    if ( remTb2Bytes && ( tb2Bytes == remTb2Bytes) )
2893    {
2894       dlAllocCb->mimoAllocInfo.precIdxInfo = 0;
2895       dlAllocCb->mimoAllocInfo.numTxLyrs   = 1;
2896       dlAllocCb->tbInfo[1].schdlngForTb    = FALSE;
2897       dlAllocCb->tbInfo[1].isDisabled      = TRUE;
2898    }
2899
2900    if (effAlloc == (remTb1Bytes + remTb2Bytes))
2901    {
2902       /* Allocation such that Nothing could be satisfied */
2903       /* Return the grabbed PDCCH */
2904       rgSCHUtlPdcchPut(cell, &dlAllocCb->dlSf->pdcchInfo, 
2905             dlAllocCb->pdcch);
2906       rgSCHSc1RlsHqProc(cmnUeDl->proc);
2907       return;
2908    }
2909
2910    /* Fill PDCCH and assign it to HqP */
2911    rgSCHCmnFillHqPPdcch(cell, dlAllocCb, cmnUeDl->proc);
2912
2913    return;
2914 }
2915
2916 \f
2917 /**
2918  * @brief This function Processes the Final Allocations
2919  *        made by the RB Allocator against the requested
2920  *        New TX allocations. 
2921  *
2922  * @details
2923  *
2924  *     Function: rgSCHSc1DlNewTxAllocFnlz 
2925  *     Purpose : Distribute the allocation among the Scheduled SVCs.
2926  *     Fill pdcch and HqP for UEs will allocations.
2927  *     Release HqP for UE with no allocation.
2928  *
2929  *     Invoked by: Common Scheduler 
2930  *     
2931  *  @param[in]  RgSchCellCb           *cell
2932  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
2933  *  @return  Void
2934  *
2935  **/
2936 static Void rgSCHSc1DlNewTxAllocFnlz (RgSchCellCb  *cell,RgSchCmnDlRbAllocInfo *allocInfo)
2937 {
2938    CmLList          *node;
2939    RgSchUeCb        *ue;
2940    RgSchCmnDlUe     *cmnUeDl;
2941    RgSchDlHqProcCb  *hqP;
2942
2943    node = allocInfo->dedAlloc.schdTxHqPLst.first;
2944    while(node)
2945    {
2946       hqP = (RgSchDlHqProcCb *)node->node;
2947       ue = hqP->hqE->ue;
2948       node = node->next;
2949       cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue,cell);
2950                 /*cell added as part of CA dev*/
2951
2952       rgSCHSc1DlNewTxUeFnlz(cell, allocInfo, ue);
2953 #ifdef LTEMAC_HDFDD
2954       if (ue->hdFddEnbld)
2955       {
2956          rgSCHCmnHdFddUpdDLMark(cell, ue);
2957       }
2958 #endif
2959       /* reset the UE allocation Information */
2960       cmLListInit(&((RgSchSc1DlUe *)(cmnUeDl->schSpfc))->schdSvcs);
2961       rgSCHCmnDlUeResetTemp(ue, hqP);
2962    }
2963
2964    /* Traverse the nonSchdTxUeLst and reset the UE allocation Info */
2965    node = allocInfo->dedAlloc.nonSchdTxHqPLst.first;
2966    while(node)
2967    {
2968       hqP = (RgSchDlHqProcCb *)node->node;
2969       ue = hqP->hqE->ue;
2970       node = node->next;
2971       cmnUeDl = RG_SCH_CMN_GET_DL_UE(ue, cell);
2972
2973       /* Release HqProc */
2974       rgSCHSc1RlsHqProc(hqP);
2975       /* reset the UE allocation Information */
2976       cmLListInit(&((RgSchSc1DlUe *)(cmnUeDl->schSpfc))->schdSvcs);
2977       rgSCHCmnDlUeResetTemp(ue, hqP);
2978    }
2979    return;
2980 }
2981
2982 /* 3.1 Added new function to handle TX+RETX alloc fnlz'n */
2983 \f
2984 /**
2985  * @brief This function Processes the Final Allocations
2986  *        made by the RB Allocator against the requested
2987  *        RETX+New TX allocations. The NewTx TB allocation
2988  *        is considered for distribution among LCs.
2989  *
2990  * @details
2991  *
2992  *     Function: rgSCHSc1DlRetxNewTxAllocFnlz 
2993  *     Purpose : 1. Reached here due to 1 RETX TB allocation for a 
2994  *                  SM UE, which is capable to accomodate a newTX
2995  *                  in the other TB.
2996  *               2. Distribute NewTX TB allocation among the
2997  *                  SVCs present in lcsWithData list of UE.
2998  *
2999  *
3000  *     Invoked by: Common Scheduler 
3001  *     
3002  *  @param[in]  RgSchCellCb           *cell
3003  *  @param[in]  RgSchCmnDlRbAllocInfo *cellAllocInfo
3004  *  @return  Void
3005  *
3006  **/
3007 static Void rgSCHSc1DlRetxNewTxAllocFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *cellAllocInfo)
3008 {
3009    CmLList          *node;
3010    RgSchUeCb        *ue;
3011    RgSchSc1DlUe     *sc1DlUe;
3012    RgSchDlHqProcCb  *hqP;
3013    RgSchDlHqTbCb    *newTxTbInfo;
3014    uint32_t         effAlloc;
3015    uint32_t         remTbBytes;
3016    RgSchDlRbAlloc   *ueAllocInfo; 
3017    RgSchDlRbAlloc   *dlAllocCb;
3018
3019    
3020    node = cellAllocInfo->dedAlloc.schdTxRetxHqPLst.first;
3021    while(node)
3022    {
3023       hqP = (RgSchDlHqProcCb *)node->node;
3024       ue = hqP->hqE->ue;
3025       node = node->next;
3026       sc1DlUe = RG_GET_SC1_UE_DL(ue, cell);
3027       ueAllocInfo = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
3028       dlAllocCb = RG_SCH_CMN_GET_ALLOCCB_FRM_UE(ue, cell);
3029       /* Index 0 of ueAllocInfo->tbInfo will always hold the 
3030        * RETX TB and index 1 will hold the NewTX TB in case of
3031        * RETX+TX allocation. */
3032       newTxTbInfo = ueAllocInfo->tbInfo[1].tbCb;
3033       effAlloc = remTbBytes  =  ueAllocInfo->tbInfo[1].bytesAlloc;
3034       rgSCHSc1DlSprTxTbDstn(cell, ue, newTxTbInfo,\
3035                      &remTbBytes, &(sc1DlUe->lcsWithData.first));
3036       /* Trying to reduce mcs of TX TB to increase reception quality at UE.
3037        * In case of RETX+TX allocation, TX TB allocation was irrespective
3038        * of actual requirement by UE, hence in case if consumption is 
3039        * less than allocation, consider reducing the iMcs of this TX TB. */
3040       rgSCHCmnRdcImcsTxTb(dlAllocCb, 1, effAlloc - remTbBytes);
3041       /* 3.1 MIMO Remove/Retain from/in cell RETX List */
3042       rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
3043       /* Fill PDCCH and assign it to HqP */
3044       rgSCHCmnFillHqPPdcch(cell, dlAllocCb, hqP);
3045 #ifdef LTEMAC_HDFDD
3046       if (ue->hdFddEnbld)
3047       {
3048          rgSCHCmnHdFddUpdDLMark(cell, ue);
3049       }
3050 #endif
3051       /* reset the UE allocation Information */
3052       rgSCHCmnDlUeResetTemp(ue, hqP);
3053    }
3054
3055    /* Traverse the nonSchdTxRetxHqPLst and reset the UE allocation Info */
3056    node = cellAllocInfo->dedAlloc.nonSchdTxRetxHqPLst.first;
3057    while(node)
3058    {
3059       hqP = (RgSchDlHqProcCb *)node->node;
3060       ue = hqP->hqE->ue;
3061       node = node->next;
3062       /* reset the UE allocation Information */
3063       rgSCHCmnDlUeResetTemp(ue, hqP);
3064    }
3065 }
3066
3067 \f
3068 /**
3069  * @brief This function Processes the Final Allocations
3070  *        made by the RB Allocator against the requested. 
3071  *
3072  * @details
3073  *
3074  *     Function: rgSCHSc1DlAllocFnlz
3075  *     Purpose:  This function Processes the Final Allocations
3076  *               made by the RB Allocator against the requested. 
3077  *               1. Loop through scheduled TX and RETX lists.
3078  *                  Fill in the corresponding PDCCH and HqProcs.
3079  *                  In case of TX If actual Alloc < requested, then perform
3080  *                     an appropriate distribution among the schdSvcs.
3081  *                     If TA is satisfied, then remove UE from TA Lst.
3082  *               2. Loop through UnScheduled TX and RETX Lists.
3083  *                  Release grabbed HqProcs.
3084  *                  Put back SVCs from schdSvcsLst to their corresponding Qs.
3085  *               
3086  *     
3087  *     Invoked by: Common Scheduler 
3088  *     
3089  *  @param[in]  RgSchCellCb           *cell
3090  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
3091  *  @return  Void
3092  *
3093  **/
3094 Void rgSCHSc1DlAllocFnlz(RgSchCellCb *cell,RgSchCmnDlRbAllocInfo *allocInfo)
3095 {
3096
3097    rgSCHSc1DlRetxAllocFnlz(cell, allocInfo);
3098
3099    rgSCHSc1DlNewTxAllocFnlz(cell, allocInfo);
3100
3101    /*3.1 MIMO new Function added to handle TX+RETX 
3102     * harq process scheduling finalization */
3103    rgSCHSc1DlRetxNewTxAllocFnlz(cell, allocInfo);
3104    return;
3105 }
3106
3107
3108 \f
3109 /**
3110  * @brief This function Updates the DL CQI for the UE. 
3111  *
3112  * @details
3113  *
3114  *     Function: rgSCHSc1DlCqiInd 
3115  *     Purpose:  Updates the DL CQI for the UE
3116  *     
3117  *     Invoked by: Common Scheduler. SC1 does nothing.
3118  *     
3119  *  @param[in]  RgSchCellCb        *cell
3120  *  @param[in]  RgSchUeCb          *ue
3121  *  @param[in]  TfuDlCqiRpt        *dlCqiRpt
3122  *  @return  Void
3123  *
3124  **/
3125 Void rgSCHSc1DlCqiInd(RgSchCellCb *cell,RgSchUeCb *ue,Bool isPucchInfo,Void *dlCqi)
3126 {
3127    return;
3128 }
3129
3130 \f
3131 /**
3132  * @brief This function adds a service to UE's list of lcsWithData. 
3133  *
3134  * @details
3135  *
3136  *     Function: rgSCHSc1DlAdd2UeLcsWithData
3137  *     Purpose:  1. This is to maintain a snapshot view of the 
3138  *               DL SVCs distributions among the cellwide priority
3139  *               queues. 
3140  *               2. This snapshot view is maintained in the order 
3141  *               of priority of the SVCs with in UE.
3142  *               3. Addition of SVC to a cellwide priority Queue
3143  *                  triggers this function.
3144  *     
3145  *     Invoked by: Functions of DL SC1 which add SVC or UE(for ambr svc)
3146  *                 to cellwide priority Queues.
3147  *     
3148  *  @param[in]  RgSchUeCb*    ue   
3149  *  @param[in]  RgSchDlLcCb*  svc 
3150  *  @return  Void
3151  *
3152  **/
3153 static Void rgSCHSc1DlAdd2UeLcsWithData(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
3154 {
3155    CmLListCp            *lst;
3156    CmLList              *node;
3157    RgSchCmnDlSvc        *cmnDlSvc = RG_SCH_CMN_GET_DL_SVC(svc);
3158    RgSchSc1DlSvc        *sc1DlSvc = RG_GET_SC1_SVC_DL(ue,svc,cell);
3159    RgSchSc1DlUe         *sc1DlUe  = RG_GET_SC1_UE_DL(ue, cell);
3160    RgSchCmnDlSvc        *cmnDlLstSvc;
3161
3162    
3163    lst  = &(sc1DlUe->lcsWithData);
3164    node = lst->first;
3165    while(node)
3166    {
3167       cmnDlLstSvc = RG_SCH_CMN_GET_DL_SVC(((RgSchDlLcCb *)(node->node)));
3168       if (cmnDlSvc->prio <= cmnDlLstSvc->prio)
3169       {
3170          break;
3171       }
3172       node = node->next;
3173    }
3174    if (node == NULLP)
3175    {
3176       cmLListAdd2Tail(lst, &sc1DlSvc->lcWithDataLnk);
3177       sc1DlSvc->lcWithDataLnk.node = (PTR)svc;
3178    }
3179    else
3180    {
3181       lst->crnt = node;
3182       cmLListInsCrnt(lst, &sc1DlSvc->lcWithDataLnk);
3183       sc1DlSvc->lcWithDataLnk.node = (PTR)svc;
3184    }
3185    return;
3186 }
3187
3188 \f
3189 /**
3190  * @brief This function adds a service to UE's list of lcsWithData. 
3191  *
3192  * @details
3193  *
3194  *     Function: rgSCHSc1DlRmFrmUeLcsWithData
3195  *     Purpose:  1. This is to maintain a snapshot view of the 
3196  *               DL SVCs distributions among the cellwide priority
3197  *               queues. 
3198  *               2. This snapshot view is maintained in the order 
3199  *               of priority of the SVCs with in UE.
3200  *               3. Addition of SVC to a cellwide priority Queue
3201  *                  triggers this function.
3202  *     
3203  *     Invoked by: Functions of DL SC1 which add SVC or UE(for ambr svc)
3204  *                 to cellwide priority Queues.
3205  *     
3206  *  @param[in]  RgSchUeCb*    ue   
3207  *  @param[in]  RgSchDlLcCb*  svc 
3208  *  @return  Void
3209  *
3210  **/
3211 static Void rgSCHSc1DlRmFrmUeLcsWithData(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb  *svc)
3212 {
3213    RgSchSc1DlSvc        *sc1DlSvc = RG_GET_SC1_SVC_DL(ue,svc,cell);
3214    RgSchSc1DlUe         *sc1DlUe  = RG_GET_SC1_UE_DL(ue, cell);
3215
3216    
3217    cmLListDelFrm(&(sc1DlUe->lcsWithData), &sc1DlSvc->lcWithDataLnk);
3218    sc1DlSvc->lcWithDataLnk.node = NULLP;
3219    return;
3220 }
3221 /***************** SC1 DL SCHEDULER FUNCTION DEFNs END HERE ****************/
3222
3223 /***************************************************************************/
3224
3225 /***************** SC1 UL SCHEDULER FUNCTION DEFNs START HERE **************/
3226
3227 /*--------------------------*
3228  * UL specific functions START
3229  *---------------------------*/
3230
3231 /**
3232  * @brief UE Lc Config for RR 
3233  *
3234  * @details
3235  *
3236  *     Function : rgSCHSc1UlLchCfg
3237  *
3238  *     Processing Steps:  Dummy function
3239  *
3240  *  @param[in]  RgrSchCellCb     *cell
3241  *  @param[in]  RgSchUeCb        *ue
3242  *  @param[in]  RgrLchCfg        *cfg 
3243  *  @param[in]  RgSchErrInfo     *err 
3244  *  @return  S16
3245  *      -# ROK
3246  **/
3247 S16 rgSCHSc1UlLchCfg 
3248 (
3249 RgSchCellCb      *cell,
3250 RgSchUeCb        *ue,
3251 RgrLchCfg        *cfg,
3252 RgSchErrInfo     *err
3253 )
3254 {
3255    return ROK;
3256 }
3257 /**
3258  * @brief UE Lc Reconfig for RR 
3259  *
3260  * @details
3261  *
3262  *     Function : rgSCHSc1UlLchRecfg
3263  *
3264  *     Processing Steps:  Dummy function
3265  *
3266  *  @param[in]  RgrSchCellCb     *cell
3267  *  @param[in]  RgSchUeCb        *ue
3268  *  @param[in]  RgrLchRecfg      *recfg 
3269  *  @param[in]  RgSchErrInfo     *err 
3270  *  @return  S16
3271  *      -# ROK
3272  **/
3273 S16 rgSCHSc1UlLchRecfg 
3274 (
3275 RgSchCellCb      *cell,
3276 RgSchUeCb        *ue,
3277 RgrLchRecfg      *recfg,
3278 RgSchErrInfo     *err
3279 )
3280 {
3281    return ROK;
3282 }
3283 /**
3284  * @brief LC deletion for PFS
3285  *
3286  * @details
3287  *
3288  *     Function : rgSCHSc1UlLchDel
3289  *
3290  *     Processing Steps: Dummy function
3291  *
3292  *  @param[in]  RgrSchCellCb     *cell
3293  *  @param[in]  RgSchUeCb        *ue
3294  *  @param[in]  CmLteLcId        lcId
3295  *  @return  S16
3296  *      -# ROK
3297  **/
3298 S16 rgSCHSc1UlLchDel(RgSchCellCb *cell,RgSchUeCb  *ue,CmLteLcId lcId,uint8_t lcgId)
3299 {
3300   return  (ROK);
3301 }
3302 \f
3303 /**
3304  * @brief This function initializes all the data for the scheduler
3305  *
3306  * @details
3307  *
3308  *     Function: rgSCHSc1UlInit
3309  *     Purpose:  This function initializes the following information
3310  *               1. Efficiency table
3311  *               2. CQI to table index - It is one row for upto 3 RBs
3312  *                  and another row for greater than 3 RBs
3313  *     
3314  *               currently extended prefix is compiled out.
3315  *     Invoked by: MAC intialization code..may be ActvInit
3316  *     
3317  *  @return  Void
3318  *
3319  **/
3320 Void rgSCHSc1UlInit(RgUlSchdApis *rgSchUlApis)
3321 {
3322    /* Init the function pointers */
3323    rgSchUlApis->rgSCHRgrUlUeCfg     = rgSCHSc1RgrUlUeCfg;
3324    rgSchUlApis->rgSCHRgrUlUeRecfg   = rgSCHSc1RgrUlUeRecfg;
3325    rgSchUlApis->rgSCHFreeUlUe       = rgSCHSc1UlUeDel;
3326    rgSchUlApis->rgSCHRgrUlCellCfg   = rgSCHSc1RgrUlCellCfg;
3327    rgSchUlApis->rgSCHRgrUlCellRecfg = rgSCHSc1RgrUlCellRecfg; 
3328    rgSchUlApis->rgSCHFreeUlCell     = rgSCHSc1UlCellDel;
3329    rgSchUlApis->rgSCHRgrUlLcCfg     = rgSCHSc1UlLchCfg;
3330    rgSchUlApis->rgSCHRgrUlLcRecfg   = rgSCHSc1UlLchRecfg;
3331    rgSchUlApis->rgSCHRgrUlLcgCfg    = rgSCHSc1RgrLcgCfg;
3332    rgSchUlApis->rgSCHRgrUlLcgRecfg  = rgSCHSc1RgrLcgRecfg;
3333    rgSchUlApis->rgSCHFreeUlLcg      = rgSCHSc1LcgDel;
3334    rgSchUlApis->rgSCHRgrUlLchDel    = rgSCHSc1UlLchDel;
3335    rgSchUlApis->rgSCHUlSched        = rgSCHSc1UlSched;
3336    rgSchUlApis->rgSCHUpdBsrShort    = rgSCHSc1UpdBsrShort;
3337    rgSchUlApis->rgSCHUpdBsrTrunc    = rgSCHSc1UpdBsrTrunc;
3338    rgSchUlApis->rgSCHUpdBsrLong     = rgSCHSc1UpdBsrLong;
3339    rgSchUlApis->rgSCHContResUlGrant = rgSCHSc1ContResUlGrant;
3340    rgSchUlApis->rgSCHSrRcvd         = rgSCHSc1SrRcvd;
3341    rgSchUlApis->rgSCHUlCqiInd       = rgSCHSc1UlCqiInd;
3342    rgSchUlApis->rgSCHUlUeRefresh    = rgSCHSc1UlUeRefresh;
3343    rgSchUlApis->rgSCHUlAllocFnlz    = rgSCHSc1UlAllocFnlz;
3344    rgSchUlApis->rgSCHUlInactvtUes   = rgSCHSc1UlHndlInActUes;
3345    rgSchUlApis->rgSCHUlActvtUe      = rgSCHSc1UlActvtUe;
3346    rgSchUlApis->rgSCHUlUeReset      = rgSCHSc1UlUeReset;
3347    rgSchUlApis->rgSCHRgrUlLcgUpd    = rgSCHSc1UlLcgUpd;
3348    return;
3349 }
3350
3351 /**
3352  * @brief UE initialisation for scheduler
3353  *
3354  * @details
3355  *
3356  *     Function : rgSCHSc1RgrUlUeCfg
3357  *     
3358  *     This functions intialises UE specific scheduler
3359  *     information
3360  *
3361  *  @param[in]  RgSchCellCb  *cell
3362  *  @param[in]  RgSchUeCb    *ue
3363  *  @param[int] RgrUeCfg     *ueCfg
3364  *  @param[out] RgSchErrInfo *err
3365  *  @return  S16
3366  *      -# ROK 
3367  *      -# RFAILED 
3368  **/
3369 S16 rgSCHSc1RgrUlUeCfg(RgSchCellCb  *cell,RgSchUeCb *ue,RgrUeCfg  *ueCfg,RgSchErrInfo *err)
3370 {
3371   
3372    RgSchCmnUe *ueSchCmn = RG_SCH_CMN_GET_UE(ue, cell);
3373
3374    if(rgSCHUtlAllocSBuf(cell->instIdx, 
3375       (Data**)&(ueSchCmn->ul.schSpfc), (sizeof(RgSchSc1UlUe))) != ROK)
3376    {
3377       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED CRNTI:%d",ue->ueId);
3378       err->errCause = RGSCHERR_SCH_SC1_UL_CFG;
3379       return RFAILED;
3380    }
3381
3382    return ROK;
3383 }  /* rgSCHSc1RgrUlUeCfg */
3384
3385 /**
3386  * @brief UE reconfiguration for scheduler
3387  *
3388  * @details
3389  *
3390  *     Function : rgSCHSc1RgrUlUeRecfg
3391  *     
3392  *     This functions updates UE specific scheduler
3393  *     information upon UE reconfiguration
3394  *
3395  *  @param[in]  RgSchCellCb  *cell
3396  *  @param[in]  RgSchUeCb    *ue
3397  *  @param[int] RgrUeRecfg   *ueRecfg
3398  *  @param[out] RgSchErrInfo *err
3399  *  @return  S16
3400  *      -# ROK 
3401  *      -# RFAILED 
3402  **/
3403 S16 rgSCHSc1RgrUlUeRecfg(RgSchCellCb *cell,RgSchUeCb  *ue,RgrUeRecfg *ueRecfg,RgSchErrInfo *err)
3404 {
3405    return ROK;
3406 }  /* rgSCHSc1RgrUeRecfg */
3407
3408 /**
3409  * @brief UE deletion for scheduler
3410  *
3411  * @details
3412  *
3413  *     Function : rgSCHSc1UlUeDel
3414  *     
3415  *     This functions deletes all scheduler information
3416  *     pertaining to a UE
3417  *
3418  *  @param[in]  RgSchCellCb  *cell
3419  *  @param[in]  RgSchUeCb    *ue
3420  *  @return  Void
3421  **/
3422 Void rgSCHSc1UlUeDel(RgSchCellCb *cell,RgSchUeCb *ue)
3423 {
3424    RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
3425    RgSchSc1UlUe   *ueUl   = RG_GET_SC1_UE_UL(ue, cell);
3426    
3427
3428    if (ueUl == NULLP)
3429    {
3430       return;
3431    }
3432    if(ueUl->txLnk.node)
3433    {
3434       cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
3435       ueUl->txLnk.node = NULLP;
3436    }
3437    if(ueUl->contResLnk.node)
3438    {
3439       cmLListDelFrm(&(cellUl->contResLst), &(ueUl->contResLnk));
3440       ueUl->contResLnk.node = NULLP;
3441    }
3442    /* ccpu00117052 - MOD - Passing double pointer
3443    for proper NULLP assignment*/
3444    rgSCHUtlFreeSBuf(cell->instIdx,
3445       (Data**)(&(ueUl)), (sizeof(RgSchSc1UlUe)));
3446
3447    return;
3448 }  /* rgSCHSc1UlUeDel */
3449
3450 /**
3451  * @brief UE Reset for scheduler
3452  *
3453  * @details
3454  *
3455  *     Function : rgSCHSc1UlUeReset
3456  *     
3457  *     Remove this UE from all Scheduling Priority Qs
3458  *
3459  *  @param[in]  RgSchCellCb  *cell
3460  *  @param[in]  RgSchUeCb    *ue
3461  *  @return  Void
3462  **/
3463 Void rgSCHSc1UlUeReset(RgSchCellCb  *cell,RgSchUeCb    *ue)
3464 {
3465    RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
3466    RgSchSc1UlUe   *ueUl   = RG_GET_SC1_UE_UL(ue, cell);
3467    
3468
3469    ueUl->srRcvd = FALSE;
3470
3471    if(ueUl->txLnk.node)
3472    {
3473       cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
3474       ueUl->txLnk.node = NULLP;
3475    }
3476    if(ueUl->contResLnk.node)
3477    {
3478       cmLListDelFrm(&(cellUl->contResLst), &(ueUl->contResLnk));
3479       ueUl->contResLnk.node = NULLP;
3480    }
3481    return;
3482 }  /* rgSCHSc1UlUeReset */
3483
3484 \f
3485 /**
3486  * @brief Scheduler processing on cell configuration
3487  *
3488  * @details
3489  *
3490  *     Function : rgSCHSc1RgrUlCellCfg
3491  *     
3492  *     This function does requisite initialisation 
3493  *     and setup for scheduler1 when a cell is
3494  *     configured
3495  *
3496  *  @param[in]  RgSchCellCb   *cell
3497  *  @param[in]  RgrCellCfg    *cellCfg
3498  *  @param[out] RgSchErrInfo  *err
3499  *  @return  S16
3500  *      -# ROK 
3501  *      -# RFAILED 
3502  **/
3503 S16 rgSCHSc1RgrUlCellCfg(RgSchCellCb  *cell,RgrCellCfg  *cellCfg,RgSchErrInfo *err)
3504 {
3505    RgSchSc1UlCell     *cellUl; 
3506
3507    if((rgSCHUtlAllocSBuf(cell->instIdx, 
3508       (Data**)&(((RgSchCmnCell*)((cell)->sc.sch))->ul.schSpfc), \
3509       (sizeof(RgSchSc1UlCell))) != ROK))
3510    {
3511       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED");
3512       err->errCause = RGSCHERR_SCH_SC1_UL_CFG;
3513       return RFAILED;
3514    }
3515    cellUl = RG_GET_SC1_CELL_UL(cell);
3516    cmLListInit(&cellUl->contResLst);
3517    cmLListInit(&cellUl->ueTxLst[0]);
3518    cmLListInit(&cellUl->ueTxLst[1]);
3519
3520    return ROK;
3521 }  /* rgSCHSc1RgrUlCellCfg */
3522
3523 \f
3524 /**
3525  * @brief This function handles the reconfiguration of cell 
3526  *
3527  * @details
3528  *
3529  *     Function: rgSCHSc1RgrUlCellRecfg
3530  *     Purpose:  Update the reconfiguration parameters.
3531  *     
3532  *     Invoked by: Scheduler
3533  *     
3534  *  @param[in]  RgSchCellCb*  cell
3535  *  @return  Void
3536  *
3537  **/
3538 S16 rgSCHSc1RgrUlCellRecfg(RgSchCellCb *cell,RgrCellRecfg  *recfg,RgSchErrInfo  *err)
3539 {
3540    return ROK;
3541 }
3542
3543 /**
3544  * @brief Scheduler processing for cell delete
3545  *
3546  * @details
3547  *
3548  *     Function : rgSCHSc1UlCellDel
3549  *     
3550  *     This functions de-initialises and frees memory
3551  *     taken up by scheduler1 for the entire cell.
3552  *
3553  *  @param[in]  RgSchCellCb  *cell
3554  *  @return  Void
3555  **/
3556 Void rgSCHSc1UlCellDel(RgSchCellCb  *cell)
3557 {
3558    RgSchSc1UlCell *cellUl = RG_GET_SC1_CELL_UL(cell);
3559
3560
3561    if (cellUl == NULLP)
3562    {
3563       return;
3564    }
3565    /* ccpu00117052 - MOD - Passing double pointer
3566    for proper NULLP assignment*/
3567    rgSCHUtlFreeSBuf(cell->instIdx,
3568       (Data**)(&(cellUl)), (sizeof(RgSchSc1UlCell)));
3569
3570    return;
3571 }  /* rgSCHSc1UlCellDel */
3572
3573 /**
3574  * @brief Scheduler invocation on logical channel Group addition
3575  *
3576  * @details
3577  *
3578  *     Function : rgSCHSc1RgrLcgCfg
3579  *     
3580  *     This functions does required processing when a new
3581  *     (dedicated) logical channel is added. Assumes lcg
3582  *     pointer in ulLc is set.
3583  *
3584  *  @param[in]  RgSchCellCb  *cell
3585  *  @param[in]  RgSchUeCb    *ue
3586  *  @param[in]  RgSchLcgCb   *lcg
3587  *  @param[int] RgrLcgCfg    *lcgCfg
3588  *  @param[out] RgSchErrInfo *err
3589  *  @return  S16
3590  *      -# ROK 
3591  *      -# RFAILED 
3592  **/
3593 S16 rgSCHSc1RgrLcgCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgSchLcgCb *lcg,RgrLcgCfg *lcgCfg,RgSchErrInfo *err)
3594 {
3595    return ROK;
3596 }  /* rgSCHSc1RgrLcgCfg */
3597
3598 /**
3599  * @brief Scheduler invocation on logical channel addition
3600  *
3601  * @details
3602  *
3603  *     Function : rgSCHSc1RgrLcgRecfg
3604  *     
3605  *     This functions does required processing when an existing
3606  *     (dedicated) logical channel is reconfigured. Assumes lcg
3607  *     pointer in ulLc is set to the old value.
3608  *     Independent of whether new LCG is meant to be configured,
3609  *     the new LCG scheduler info is accessed and possibly modified.
3610  *
3611  *  @param[in]  RgSchCellCb  *cell,
3612  *  @param[in]  RgSchUeCb    *ue,
3613  *  @param[in]  RgSchLcgCb   *lcg,
3614  *  @param[in]  RgrLcgRecfg  *reCfg,
3615  *  @param[out] RgSchErrInfo *err
3616  *  @return  S16
3617  *      -# ROK 
3618  *      -# RFAILED 
3619  **/
3620 S16 rgSCHSc1RgrLcgRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgSchLcgCb *lcg,RgrLcgRecfg *reCfg,RgSchErrInfo *err)
3621 {
3622    return ROK;
3623 }  /* rgSCHSc1RgrLcgRecfg */
3624
3625 /***********************************************************
3626  *
3627  *     Func : rgSCHSc1LcgDel
3628  *        
3629  *     Desc : Scheduler handling for a (dedicated)
3630  *             uplink lcg being deleted
3631  *
3632  *     Ret  : 
3633  *
3634  *     Notes: 
3635  *
3636  *     File : 
3637  *
3638  **********************************************************/
3639 Void rgSCHSc1LcgDel(RgSchCellCb *cell,RgSchUeCb *ue,RgSchLcgCb *lcg)
3640 {
3641    rgSCHSc1UlPosnUeInQ(cell, ue);
3642    return;
3643 }
3644
3645 /**
3646  * @brief Perform alloction for this UE 
3647  *
3648  * @details
3649  *
3650  *     Function : rgSCHSc1UlSchdUe
3651  *
3652  *     Processing Steps: cater to as much as UE needs, with 
3653  *     a limitation on maxBits per scheduling instance(per TTI)
3654  *     per UE. Return failure, if UE is not considered 
3655  *     for scheduling (case, where it is already selected for a
3656  *     retransmission).
3657  *                   
3658  *
3659  *  @param[in]  RgSchUeCb        *ue
3660  *  @return  Void
3661  **/
3662 static Void rgSCHSc1UlSchdUe(RgSchUeCb *ue,RgSchCellCb *cell)
3663 {
3664    RgSchCmnUlUe      *cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue, cell);
3665                                 /*cell added as part of CA dev*/
3666    RgSchSc1UlUe      *ulUe    = RG_GET_SC1_UE_UL(ue, cell);
3667
3668
3669    if(ulUe->srRcvd == TRUE)
3670    {
3671       cmnUlUe->alloc.reqBytes = RGSCH_MAX(RG_SCH_CMN_UL_SR_BYTES, \
3672                                 ue->ul.effBsr);
3673       return;
3674    }
3675
3676    cmnUlUe->alloc.reqBytes = ue->ul.effBsr;
3677
3678    return;
3679 }
3680
3681 /**
3682  * @brief Scheduler invocation
3683  *
3684  * @details
3685  *
3686  *     Function: rgSCHSc1UlSchdForDataTrans
3687  *     Purpose:  Uplink Scheduling for UE data Transmission.
3688  *
3689  *     
3690  *     Invoked by: Scheduler
3691  *     
3692  *  @param[in]  RgSchCellCb           *cell
3693  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo 
3694  *  @param[in] uint8_t                     remUe 
3695  *  @return Void 
3696  **/
3697 static Void rgSCHSc1UlSchdForDataTrans(RgSchCellCb  *cell,RgSchCmnUlRbAllocInfo *allocInfo,uint8_t remUe)
3698 {
3699    RgSchSc1UlCell    *sc1UlCell  = RG_GET_SC1_CELL_UL(cell);
3700
3701    if (remUe == 0)
3702    {
3703       return;
3704    }
3705    /* Allocate UEs with LCG0 data pending */
3706    rgSCHSc1UlSchdUeTxLst(cell, &sc1UlCell->ueTxLst[0], allocInfo, &remUe);
3707
3708    if (remUe == 0)
3709    {
3710       return;
3711    }
3712    /* Allocate UEs with other LCGs data pending */
3713    rgSCHSc1UlSchdUeTxLst(cell, &sc1UlCell->ueTxLst[1], allocInfo, &remUe);
3714
3715    return;
3716 }
3717
3718 /**
3719  * @brief Scheduler invocation
3720  *
3721  * @details
3722  *
3723  *     Function: rgSCHSc1UlSchdUeTxLst
3724  *     Purpose:  Uplink Scheduling for UE data Transmission.
3725  *
3726  *     
3727  *     Invoked by: Scheduler
3728  *     
3729  *  @param[in]  CmLListCp             *ueTxLst
3730  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo 
3731  *  @param[in] uint8_t                     *remUe 
3732  *  @return Void 
3733  **/
3734 static Void rgSCHSc1UlSchdUeTxLst(RgSchCellCb *cell,CmLListCp *ueTxLst,RgSchCmnUlRbAllocInfo *allocInfo,uint8_t *remUe)
3735 {
3736    RgSchUeCb *ue;
3737    CmLList   *node;
3738 #ifdef LTEMAC_HDFDD
3739    Bool      ulAllowed = FALSE;
3740 #endif
3741
3742
3743    node = ueTxLst->first;
3744    while ((node) && (*remUe))
3745    {
3746       ue = (RgSchUeCb *)node->node;
3747       node = node->next;
3748 #ifdef LTEMAC_HDFDD
3749       if (ue->hdFddEnbld)
3750       {
3751          rgSCHCmnHdFddChkUlAllow (cell, ue, &ulAllowed);
3752          if (ulAllowed == FALSE)
3753          {
3754             continue;
3755          }
3756       }
3757 #endif
3758
3759       if (RG_SCH_CMN_IS_UL_UE_RETX(ue, cell))
3760       {
3761          /* UE already scheduled in this subframe (for retx) 
3762           * OR is inactive for UL Transmission.*/
3763          continue;
3764       }
3765       /* Added support for SPS*/
3766 #ifdef LTEMAC_SPS
3767          else if (RG_SCH_CMN_IS_SPS_SCHD(ue, cell))
3768          {
3769             /*-- Already Scheduled by SPS --*/
3770            continue;
3771          }
3772 #endif
3773
3774       rgSCHSc1UlSchdUe(ue,cell);/*cell added as part of CA dev*/
3775
3776       rgSCHCmnUlAdd2UeLst(cell, allocInfo, ue);
3777
3778       --(*remUe);
3779    }
3780
3781    return;
3782 }
3783
3784 /**
3785  * @brief Scheduler invocation
3786  *
3787  * @details
3788  *
3789  *     Function: rgSCHSc1UlSchdForContRes
3790  *     Purpose:  Uplink Scheduling for Contention Resolution.
3791  *
3792  *     
3793  *     Invoked by: Scheduler
3794  *     
3795  *  @param[in]  RgSchCellCb           *cell
3796  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo 
3797  *  @param[out] uint8_t                    *remUe 
3798  *  @return Void 
3799  **/
3800 static Void rgSCHSc1UlSchdForContRes(RgSchCellCb  *cell,RgSchCmnUlRbAllocInfo *allocInfo,uint8_t *remUe)
3801 {
3802    RgSchSc1UlCell    *sc1UlCell  = RG_GET_SC1_CELL_UL(cell);
3803    RgSchUeCb         *ue;
3804    CmLList           *node;
3805    RgSchCmnUlUe      *cmnUlUe;
3806 #ifdef LTEMAC_HDFDD
3807    Bool                 ulAllowed = FALSE;
3808 #endif
3809
3810
3811    node = sc1UlCell->contResLst.first;
3812    while ((node) && (*remUe))
3813    {
3814       ue = (RgSchUeCb *)node->node;
3815       cmnUlUe = RG_SCH_CMN_GET_UL_UE(ue, cell);
3816                 /*cell added as part of CA dev*/
3817       node = node->next;
3818 #ifdef LTEMAC_HDFDD
3819       if (ue->hdFddEnbld)
3820       {
3821          rgSCHCmnHdFddChkUlAllow (cell, ue,  &ulAllowed);
3822          if (ulAllowed == FALSE)
3823          {
3824             continue;
3825          }
3826       }
3827 #endif
3828       if (RG_SCH_CMN_IS_UL_UE_RETX(ue, cell))
3829       {
3830          /* UE already scheduled in this subframe (for retx) 
3831           * OR is inactive for UL Transmission.*/
3832          continue;
3833       }
3834       cmnUlUe->alloc.reqBytes = RG_SCH_CMN_MAX_UL_CONTRES_GRNT;
3835       rgSCHCmnUlAdd2CntResLst(allocInfo, ue);
3836       --(*remUe);
3837       /* Node removal deferred to ULAllocFinalization */
3838    }
3839
3840    return;
3841 }
3842
3843 /**
3844  * @brief Scheduler invocation
3845  *
3846  * @details
3847  *
3848  *     Function: rgSCHSc1UlNewTx
3849  *     Purpose:  Uplink Scheduling for New Transmissions.
3850  *
3851  *     
3852  *     Invoked by: Scheduler
3853  *     
3854  *  @param[in]  RgSchCellCb           *cell
3855  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo 
3856  *  @return Void 
3857  **/
3858 static Void rgSCHSc1UlNewTx(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
3859 {
3860    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
3861    uint8_t               remUe = cellUl->maxUeNewTxPerTti;
3862
3863
3864    rgSCHSc1UlSchdForContRes(cell, allocInfo, &remUe);
3865    rgSCHSc1UlSchdForDataTrans(cell, allocInfo, remUe);
3866    return;
3867 }
3868
3869 /**
3870  * @brief Scheduler invocation
3871  *
3872  * @details
3873  *
3874  *     Function: rgSCHSc1UlSched
3875  *     Purpose:  This function implements an UL scheduler for LTE. This is
3876  *               made available as a function pointer to be called
3877  *               at the time of TTI processing by the MAC.
3878  *     
3879  *     Invoked by: Common Scheduler (TTI processing)
3880  *     
3881  *  @param[in]  RgSchCellCb           *cell
3882  *  @param[out] RgSchCmnUlRbAllocInfo *allocInfo 
3883  *  @return Void 
3884  **/
3885 Void rgSCHSc1UlSched(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
3886 {
3887    rgSCHSc1UlNewTx(cell, allocInfo);
3888    return;
3889 }
3890
3891 /**
3892  * @brief UEs Buffer Status Has changed so reposition it. 
3893  *
3894  * @details
3895  *
3896  *     Function : rgSCHSc1UlInsUeInQ 
3897  *     
3898  *     In UE in the list in Descending order of effBsr.
3899  *     
3900  *
3901  *  @param[in]  CmLListCp    *lst
3902  *  @param[in]  RgSchUeCb    *ue
3903  *  @return  Void 
3904  **/
3905 static Void rgSCHSc1UlInsUeInQ(CmLListCp *lst,RgSchUeCb *ue,RgSchCellCb *cell)
3906 {
3907                               /*cell added as part of CA dev*/
3908    RgSchSc1UlUe    *ueUl    = RG_GET_SC1_UE_UL(ue, cell);
3909    RgSchUeCb       *lUe;
3910    CmLList         *node;
3911
3912
3913    node = lst->first;
3914    while(node)
3915    {
3916       lUe = (RgSchUeCb *)(node->node);
3917       if (lUe->ul.effBsr <= ue->ul.effBsr)
3918       {
3919          break;
3920       }
3921       node = node->next;
3922    }
3923    if (node == NULLP)
3924    {
3925       /* We have come to the end of the queue, so Append */
3926       cmLListAdd2Tail(lst, &ueUl->txLnk);
3927       ueUl->txLnk.node = (PTR)ue;
3928    }
3929    else
3930    {
3931       lst->crnt = node;
3932       cmLListInsCrnt(lst, &ueUl->txLnk);
3933       ueUl->txLnk.node = (PTR)ue;
3934    }
3935
3936    return;
3937 }
3938 /**
3939  * @brief UEs Buffer Status Has changed so reposition it. 
3940  *
3941  * @details
3942  *
3943  *     Function : rgSCHSc1UlPosnUeInQ
3944  *     
3945  *     -Ues bs value for its LCG has changed, due to either 
3946  *     allocation or BSR report OR the effUeBR, i.e the byteRate
3947  *     has changed due to some allocation, so add/reposition/remove
3948  *     it from Qs based on this new bs and/or effUeBR value.
3949  *     -If UE has non-zero lcg0 bs value, but the byteRate is 
3950  *     consumed totally, UE is still schedulable for this control data. 
3951  *     -If UE's LCG0 has pending bs then position this UE in 
3952  *     ueTxLst[0].
3953  *     -If Ue has pending BSR to be satisfied, but lcg0's BS
3954  *     is 0, then position it in ueTxLst[1].
3955  *     -In any of these 2 Qs, insertion is such that UEs are
3956  *     positioned in Descending order of their Pending BS.
3957  *     
3958  *
3959  *  @param[in]  RgSchCellCb  *cell
3960  *  @param[in]  RgSchUeCb    *ue
3961  *  @return  Void 
3962  **/
3963 static Void rgSCHSc1UlPosnUeInQ(RgSchCellCb *cell,RgSchUeCb *ue)
3964 {
3965    RgSchSc1UlUe    *ueUl   = RG_GET_SC1_UE_UL(ue, cell);
3966                               /*cell added as part of CA dev*/
3967    RgSchSc1UlCell  *cellUl = RG_GET_SC1_CELL_UL(cell);
3968    RgSchCmnLcg     *cmnLcg0 = RG_SCH_CMN_GET_UL_LCG(&ue->ul.lcgArr[0]);
3969    CmLListCp       *lst;
3970
3971
3972    if (!RG_SCH_CMN_UL_IS_UE_ACTIVE(ue))
3973    {
3974       return;
3975    }
3976                      
3977    /* Remove the UE from its existing position */
3978    if (ueUl->txLnk.node)
3979    {
3980       cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
3981       ueUl->txLnk.node = (PTR)NULLP;
3982    }
3983    /* If UE has still bs left for scheduling 
3984     * then reposition it */
3985    if ((ue->ul.effBsr > 0) || (ueUl->srRcvd == TRUE))
3986    {
3987       /* Select the Queue where UE would be Placed */
3988       if (cmnLcg0->bs > 0)
3989       {
3990          lst = &cellUl->ueTxLst[0];
3991          ueUl->qId = 0;
3992       }
3993       else
3994       {
3995          lst = &cellUl->ueTxLst[1];
3996          ueUl->qId = 1;
3997       }
3998       /* Insert the UE in the Q */
3999       rgSCHSc1UlInsUeInQ(lst, ue, cell);/*cell added as part of CA dev*/ 
4000    }
4001 #ifdef RGR_V1
4002    else if(ue->ul.totalBsr != 0)
4003    {
4004       if (ue->bsrTmr.tmrEvnt != TMR_NONE)
4005       {
4006          rgSCHTmrStopTmr(cell, ue->bsrTmr.tmrEvnt, ue); 
4007       }
4008       if (ue->ul.bsrTmrCfg.isPrdBsrTmrPres)
4009       {
4010          rgSCHTmrStartTmr(cell, ue, RG_SCH_TMR_BSR, 
4011                ue->ul.bsrTmrCfg.prdBsrTmr);
4012       }
4013    }
4014 #endif
4015
4016    return;
4017 }
4018
4019 /**
4020  * @brief Short BSR update
4021  *
4022  * @details
4023  *
4024  *     Function : rgSCHSc1UpdBsrShort
4025  *     
4026  *     This functions does requisite updates to handle short BSR reporting
4027  *
4028  *  @param[in]  RgSchCellCb  *cell
4029  *  @param[in]  RgSchUeCb    *ue
4030  *  @param[in]  RgSchLcgCb   *lcg
4031  *  @param[in]  uint8_t           bsr
4032  *  @return  Void
4033  **/
4034 Void rgSCHSc1UpdBsrShort(RgSchCellCb  *cell,RgSchUeCb    *ue,RgSchLcgCb   *lcg,uint8_t  bsr)
4035 {
4036    rgSCHSc1UlPosnUeInQ(cell, ue);
4037    return;
4038 }  /* rgSCHSc1UpdBsrShort */
4039
4040 /**
4041  * @brief Truncated BSR update
4042  *
4043  * @details
4044  *
4045  *     Function : rgSCHSc1UpdBsrTrunc
4046  *     
4047  *     This functions does required updates to handle truncated BSR report
4048  *     
4049  *           
4050  *  @param[in]  RgSchCellCb  *cell
4051  *  @param[in]  RgSchUeCb    *ue
4052  *  @param[in]  RgSchLcgCb   *lcg
4053  *  @param[in]  uint8_t           bsr
4054  *  @return  Void 
4055  **/
4056 Void rgSCHSc1UpdBsrTrunc(RgSchCellCb  *cell,RgSchUeCb    *ue,RgSchLcgCb   *lcg,uint8_t bsr)
4057 {
4058    rgSCHSc1UlPosnUeInQ(cell, ue);
4059    return;
4060 }  /* rgSCHSc1UpdBsrTrunc */
4061
4062 /**
4063  * @brief Long BSR update
4064  *
4065  * @details
4066  *
4067  *     Function : rgSCHSc1UpdBsrLong
4068  *
4069  *     - Update UE's position within/across uplink scheduling queues
4070  *
4071  *
4072  *  @param[in]  RgSchCellCb  *cell
4073  *  @param[in]  RgSchUeCb    *ue
4074  *  @param[in]  uint8_t bsArr[]
4075  *  @return  Void 
4076  **/
4077 Void rgSCHSc1UpdBsrLong(RgSchCellCb  *cell,RgSchUeCb *ue,uint8_t *bsArr)
4078 {
4079    rgSCHSc1UlPosnUeInQ(cell, ue);
4080    return;
4081 }  /* rgSCHSc1UpdBsrLong */
4082
4083 /**
4084  * @brief UL grant for contention resolution
4085  *
4086  * @details
4087  *
4088  *     Function : rgSCHSc1ContResUlGrant
4089  *     
4090  *     Add UE to another queue specifically for CRNTI based contention
4091  *     resolution
4092  *     
4093  *           
4094  *  @param[in]  RgSchCellCb  *cell
4095  *  @param[in]  RgSchUeCb    *ue
4096  *  @return Void 
4097  **/
4098 Void rgSCHSc1ContResUlGrant(RgSchCellCb  *cell,RgSchUeCb *ue)
4099 {
4100    RgSchSc1UlUe    *ueUl   = RG_GET_SC1_UE_UL(ue, cell);
4101    RgSchSc1UlCell  *cellUl = RG_GET_SC1_CELL_UL(cell);
4102
4103
4104    if (ueUl->contResLnk.node)
4105    {
4106       return;
4107    }
4108
4109    /* Remove the UE from other Qs */
4110    if(ueUl->txLnk.node)
4111    {
4112       cmLListDelFrm(&(cellUl->ueTxLst[ueUl->qId]), &(ueUl->txLnk));
4113       ueUl->txLnk.node = NULLP;
4114    }
4115
4116    cmLListAdd2Tail(&cellUl->contResLst, &ueUl->contResLnk);
4117    ueUl->contResLnk.node = (PTR)ue;
4118    return;
4119 }  /* rgSCHSc1ContResUlGrant */
4120
4121 /**
4122  * @brief SR reception handling
4123  *
4124  * @details
4125  *
4126  *     Function : rgSCHSc1SrRcvd
4127  *     Shift the UE with SrInd in to the lcgO queue.
4128  *
4129  *
4130  *  @param[in]  RgSchCellCb  *cell
4131  *  @param[in]  RgSchUeCb    *ue
4132  *  @return  Void
4133  **/
4134 Void rgSCHSc1SrRcvd(RgSchCellCb *cell,RgSchUeCb *ue)
4135 {
4136    RgSchSc1UlUe    *ulUe    = RG_GET_SC1_UE_UL(ue, cell);
4137    RgSchSc1UlCell  *ulCell  = RG_GET_SC1_CELL_UL(cell);
4138
4139
4140    ulUe->srRcvd = TRUE;
4141
4142    if (ulUe->txLnk.node != NULLP)
4143    {
4144       if (ulUe->qId == 0)
4145       {
4146          /* Already present in lcg0 Q */
4147          return;
4148       }
4149       cmLListDelFrm(&(ulCell->ueTxLst[ulUe->qId]), &(ulUe->txLnk));
4150    }
4151    /* Adding the UE to the LCG0 list for SR IND */
4152    cmLListAdd2Tail(&ulCell->ueTxLst[0], &ulUe->txLnk);
4153    ulUe->txLnk.node = (PTR)ue;
4154    ulUe->qId = 0;
4155
4156    return;
4157 }  /* rgSCHSc1SrRcvd */
4158
4159 /**
4160  * @brief Indication of UL CQI
4161  *
4162  * @details
4163  *
4164  *     Function : rgSCHSc1UlCqiInd 
4165  *
4166  *     - Common Scheduler. SC1 does nothing. 
4167  *
4168  *  @param[in]  RgSchCellCb         *cell
4169  *  @param[in]  RgSchUeCb           *ue
4170  *  @param[in]  TfuUlCqiRpt         *ulCqiInfo
4171  *  @return  Void
4172  **/
4173 Void rgSCHSc1UlCqiInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuUlCqiRpt *ulCqiInfo)
4174 {
4175
4176   /* Stack Crash problem for TRACE5 changes. Added the return below */
4177   return;
4178
4179 }
4180
4181 /**
4182  * @brief UL Lcg received data updation
4183  *
4184  * @details
4185  *
4186  *     Function : rgSCHSc1UlLcgUpd
4187  *
4188  *     Processing Steps:Sc1 Does nothing
4189  *
4190  *  @param[in]  RgSchCellCb         *cell
4191  *  @param[in]  RgSchUeCb          *ue
4192  *  @param[in]  RgInfUeDatInd      *datInd
4193  *  @return  S16
4194  **/
4195 S16 rgSCHSc1UlLcgUpd(RgSchCellCb *cell,RgSchUeCb *ue,RgInfUeDatInd  *datInd)
4196 {
4197
4198    return ROK;  
4199 }
4200
4201 \f
4202 /***********************************************************
4203  *
4204  *     Func : rgSCHSc1UlUeRefresh
4205  *        
4206  *     Desc : Handle 'refresh' for uplink part of a UE
4207  *            (ie UE's uplink AMBR and uplink GBR LCGs are
4208  *            refreshed at this point)
4209  *
4210  *     Ret  : 
4211  *
4212  *     Notes:
4213  *
4214  *     File : 
4215  *
4216  **********************************************************/
4217 Void rgSCHSc1UlUeRefresh(RgSchCellCb *cell,RgSchUeCb  *ue)
4218 {
4219    rgSCHSc1UlPosnUeInQ(cell, ue);
4220    return;
4221 }
4222
4223 /**
4224  * @brief This function Processes the Final Allocations
4225  *        made by the RB Allocator against the requested
4226  *        UE data Trans Allocations. 
4227  *
4228  * @details
4229  *
4230  *     Function: rgSCHSc1UlDatTransAllocFnlz
4231  *     Purpose:  This function Processes the Final Allocations
4232  *               made by the RB Allocator against the requested
4233  *               UE data Trans Allocations . 
4234  *     
4235  *     Invoked by: Scheduler 
4236  *     
4237  *  @param[in]  RgSchCellCb           *cell
4238  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
4239  *  @return  Void
4240  *
4241  **/
4242 static Void rgSCHSc1UlDatTransAllocFnlz(RgSchCellCb  *cell,RgSchCmnUlRbAllocInfo *allocInfo)
4243 {
4244    RgSchSc1UlUe      *ueUl;
4245    RgSchUeCb         *ue;
4246    CmLList           *node;
4247    RgSchDrxUeCb      *drxUe    = NULLP;
4248    CmLListCp         ulInactvLst; /* list of UE's becoming UL-inactive */
4249
4250    cmLListInit(&ulInactvLst);
4251    node = allocInfo->schdUeLst.first;
4252    while(node)
4253    {
4254       ue   = (RgSchUeCb *)node->node;
4255       node = node->next;
4256       ueUl = RG_GET_SC1_UE_UL(ue, cell);
4257
4258       if (ue->isDrxEnabled)
4259       {
4260          if(ueUl->srRcvd == TRUE)
4261          {
4262             drxUe = RG_SCH_DRX_GET_UE(ue);
4263             drxUe->drxUlInactvMask  |= RG_SCH_DRX_SR_BITMASK;
4264
4265             if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
4266             {
4267                ue->ul.ulInactvMask |= RG_DRX_INACTIVE;
4268                /* Add to Ul inactive List */
4269                ue->ulDrxInactvLnk.node  = (PTR)ue;
4270                cmLListAdd2Tail(&ulInactvLst,&(ue->ulDrxInactvLnk));
4271             }
4272             drxUe->srRcvd = FALSE;
4273          }
4274       }
4275       /* Reset no matter */
4276       ueUl->srRcvd = FALSE;
4277       /* Reposition UE in Qs */
4278       rgSCHSc1UlPosnUeInQ(cell, ue);
4279 #ifdef LTEMAC_HDFDD
4280       if (ue->hdFddEnbld)
4281       {
4282          rgSCHCmnHdFddUpdULMark (cell,ue);
4283       }
4284 #endif
4285       /* reset the UE UL allocation Information */
4286       rgSCHCmnUlUeResetTemp(cell, ue);
4287    }
4288    rgSCHSc1UlHndlInActUes(cell, &ulInactvLst);
4289    node = allocInfo->nonSchdUeLst.first;
4290    while(node)
4291    {
4292       ue   = (RgSchUeCb *)node->node;
4293       node = node->next;
4294       /* reset the UE UL allocation Information */
4295       rgSCHCmnUlUeResetTemp(cell, ue);
4296    }
4297
4298    return;
4299 }
4300
4301 /**
4302  * @brief This function Processes the Final Allocations
4303  *        made by the RB Allocator against the requested
4304  *        cont res Allocations. 
4305  *
4306  * @details
4307  *
4308  *     Function: rgSCHSc1UlContResAllocFnlz
4309  *     Purpose:  This function Processes the Final Allocations
4310  *               made by the RB Allocator against the requested
4311  *               cont res Allocations . 
4312  *     
4313  *     Invoked by: Scheduler 
4314  *     
4315  *  @param[in]  RgSchCellCb           *cell
4316  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
4317  *  @return  Void
4318  *
4319  **/
4320 static Void rgSCHSc1UlContResAllocFnlz(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
4321 {
4322    RgSchSc1UlCell    *sc1UlCell  = RG_GET_SC1_CELL_UL(cell);
4323    RgSchSc1UlUe      *ueUl;
4324    RgSchUeCb         *ue;
4325    CmLList           *node;
4326
4327    node = allocInfo->schdContResLst.first;
4328    while(node)
4329    {
4330       ue   = (RgSchUeCb *)node->node;
4331       node = node->next;
4332 #ifdef LTEMAC_HDFDD
4333       if (ue->hdFddEnbld)
4334       {
4335          rgSCHCmnHdFddUpdULMark (cell,ue);
4336       }
4337 #endif
4338       ueUl = RG_GET_SC1_UE_UL(ue, cell);
4339
4340       /* Remove UE from Cont Res Q */ 
4341       cmLListDelFrm(&sc1UlCell->contResLst,
4342       &ueUl->contResLnk);
4343       ueUl->contResLnk.node = NULLP;
4344       /* reset the UE UL allocation Information */
4345       rgSCHCmnUlUeResetTemp(cell, ue);
4346    }
4347
4348    node = allocInfo->nonSchdContResLst.first;
4349    while(node)
4350    {
4351       ue   = (RgSchUeCb *)node->node;
4352       node = node->next;
4353       /* reset the UE UL allocation Information */
4354       rgSCHCmnUlUeResetTemp(cell, ue);
4355    }
4356
4357    return;
4358 }
4359
4360 /**
4361  * @brief This function Processes the Final Allocations
4362  *        made by the RB Allocator against the requested. 
4363  *
4364  * @details
4365  *
4366  *     Function: rgSCHSc1UlAllocFnlz
4367  *     Purpose:  This function Processes the Final Allocations
4368  *               made by the RB Allocator against the requested. 
4369  *     
4370  *     Invoked by: Common Scheduler 
4371  *     
4372  *  @param[in]  RgSchCellCb           *cell
4373  *  @param[in]  RgSchCmnDlRbAllocInfo *allocInfo
4374  *  @return  Void
4375  *
4376  **/
4377 Void rgSCHSc1UlAllocFnlz(RgSchCellCb *cell,RgSchCmnUlRbAllocInfo *allocInfo)
4378 {
4379
4380    rgSCHSc1UlContResAllocFnlz(cell, allocInfo);
4381    rgSCHSc1UlDatTransAllocFnlz(cell, allocInfo);
4382
4383    return;
4384 }
4385
4386 \f
4387 /**
4388  * @brief Scheduler invocation
4389  *
4390  * @details
4391  *
4392  *     Function: rgSCHSc1UlActvtUe 
4393  *     Purpose:  Put back the UE in to appropriate Qs.
4394  *     
4395  *     Invoked by: Common Scheduler 
4396  *     
4397  *  @param[in]  RgSchCellCb *cell
4398  *  @param[in]  RgSchUeCb   *ue
4399  *  @return  Void
4400  **/
4401 Void rgSCHSc1UlActvtUe(RgSchCellCb *cell,RgSchUeCb *ue)
4402 {
4403
4404    rgSCHSc1UlPosnUeInQ(cell, ue);
4405    return;
4406 }
4407
4408 /**
4409  * @brief Scheduler invocation
4410  *
4411  * @details
4412  *
4413  *     Function: rgSCHSc1UlHndlInActUes
4414  *     Purpose:  The list of inactive UEs present in inactvLst should
4415  *               be removed from the scheduling Qs.
4416  *               But store the information pertaining to which Qs,
4417  *               were they belonging to. This information shall be used 
4418  *               to put them back in appropriate Qs when their Activation
4419  *               is initiated.
4420  *     
4421  *     Invoked by: Common Scheduler (TTI processing)
4422  *     
4423  *  @param[in]  RgSchCellCb *cell
4424  *  @param[out] CmLListCp   *inactvLst
4425  *  @return  Void
4426  **/
4427 Void rgSCHSc1UlHndlInActUes(RgSchCellCb *cell,CmLListCp  *inactvLst)
4428 {
4429    RgSchUeCb      *ue;
4430    RgSchSc1UlUe   *ulUe;
4431    RgSchSc1UlCell *cellUl  = RG_GET_SC1_CELL_UL(cell);
4432    CmLList        *node = inactvLst->first;
4433
4434    while (node)
4435    {
4436       ue = (RgSchUeCb *)node->node;
4437       node = node->next;
4438       ulUe = RG_GET_SC1_UE_UL(ue, cell);
4439       if(ulUe->txLnk.node)
4440       {
4441          cmLListDelFrm(&(cellUl->ueTxLst[ulUe->qId]), &(ulUe->txLnk));
4442          /* This is required as lcg bs might change during
4443           * inactivity to activity. So we need to recompute 
4444           * its position. */
4445          ulUe->txLnk.node = NULLP;
4446       }
4447       /* Do not remove UE from contResLst */
4448    }
4449    return;
4450 }
4451 /**
4452  * @brief Scheduler invocation
4453  *
4454  * @details
4455  *
4456  *     Function: rgSCHSc1DlProcRmvFrmRetx
4457  *     Purpose:  To remove the Harq process from the cell and from the UE 
4458  *                retransmission list
4459  *     
4460  *     Invoked by: Common Scheduler (TTI processing)
4461  *     
4462  *  @param[in]  RgSchCellCb *cell
4463  *  @param[in]  RgSchUeCb   *ue;
4464  *  @param[in] RgSchDlHqProcCb  *hqP
4465  *  @return  Void
4466  **/
4467
4468 Void rgSCHSc1DlProcRmvFrmRetx(
4469 RgSchCellCb                *cell,
4470 RgSchUeCb                  *ue,
4471 RgSchDlHqProcCb            *hqP
4472 )
4473 {
4474   
4475    /* Remove the HqP from retx Queue.
4476    Release HqP.*/
4477    rgSCHSc1DlProcRmvFrmCellRetx(cell, hqP);
4478    rgSCHSc1DlProcRmvFrmUeRetx(cell, ue, hqP);
4479    return;
4480 }
4481
4482
4483
4484 \f
4485 /**********************************************************************
4486  
4487          End of file
4488 **********************************************************************/