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