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