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