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