Initial commit
[o-du/l2.git] / src / 5gnrmac / rg_sch_scell.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 Round Robin functions
26
27      File:     rg_sch_scell.c
28
29 **********************************************************************/
30
31 /** @file rg_sch_rr.c
32 @brief This module handles the round robin scheduler functionality
33 */
34
35 /* header include files -- defines (.h) */
36 #include "envopt.h"        /* environment options */
37 #include "envdep.h"        /* environment dependent */
38 #include "envind.h"        /* environment independent */
39 #include "gen.h"           /* general layer */
40 #include "ssi.h"           /* system service interface */
41 #include "cm5.h"           /* common timers */
42 #include "cm_hash.h"       /* common hash list */
43 #include "cm_llist.h"      /* common linked list library */
44 #include "cm_err.h"        /* common error */
45 #include "cm_lte.h"        /* common LTE */
46 #include "lrg.h"
47 #include "rgr.h"
48 #include "rgm.h"
49 #include "tfu.h"
50 #include "rg_env.h"
51 #include "rg_sch_inf.h"
52 #include "rg_sch_err.h"
53 #include "rg_sch.h"
54 #include "rg_sch_cmn.h"
55
56 /* header/extern include files (.x) */
57 #include "gen.x"           /* general layer typedefs */
58 #include "ssi.x"           /* system services typedefs */
59 #include "cm5.x"           /* common timers */
60 #include "cm_hash.x"       /* common hash list */
61 #include "cm_lib.x"        /* common library */
62 #include "cm_llist.x"      /* common linked list */
63 #include "cm_mblk.x"       /* memory management */
64 #include "cm_tkns.x"       /* common tokens */
65 #include "cm_lte.x"        /* common tokens */
66 #include "tfu.x"           /* RGU types */
67 #include "lrg.x"           /* layer management typedefs for MAC */
68 #include "rgr.x"           /* layer management typedefs for MAC */
69 #include "rgm.x"           /* layer management typedefs for MAC */
70 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
71 #include "rg_sch.x"        /* typedefs for Scheduler */
72 #include "rg_sch_cmn.x"
73
74 #ifdef LTE_ADV
75
76 PUBLIC Void rgSCHSCellActivation ARGS((
77 RgSchUeCellInfo  *sCell
78 ));
79
80 PUBLIC Void rgSCHSCellSchdActDeactCe ARGS((
81 RgSchUeCb         *ueCb,
82 RgSchDlHqTbCb     *tbInfo
83 ));
84 PUBLIC Void rgSCHSCellAddToActDeactLst ARGS((
85 RgSchCellCb                *cell,
86 RgSchUeCb                  *ue
87 ));
88
89 PUBLIC Void rgSCHSCellRmvFrmActLst ARGS((
90 RgSchCellCb                *cell,
91 RgSchUeCb                  *ue
92 ));
93 PUBLIC S16 rgSCHSCellIsActive ARGS((
94 RgSchCellCb                *cell,
95 RgSchUeCb                  *ue
96 ));
97
98 PUBLIC Void rgSCHSCellHndlFdbkInd ARGS((
99 RgSchDlHqProcCb   *hqP,
100 U8                tbIdx,
101 U8                fdbk,
102 Bool              maxHqRetxReached
103 ));
104
105 #ifdef LTE_ADV
106 PUBLIC Void rgSCHSCellDeactTmrExpry ARGS((
107 RgSchUeCellInfo *sCell
108 ));
109 #endif
110
111 PUBLIC Void rgSCHSCellDelUeSCell ARGS((
112 RgSchCellCb  *cellCb,
113 RgSchUeCb    *ueCb,
114 U8            sCellIdx
115 ));
116
117 PUBLIC S16 rgSCHSCellDelUe ARGS((
118 RgSchCellCb  *cellCb,
119 RgSchUeCb    *ueCb
120 ));
121 #ifdef TFU_UPGRADE
122 PUBLIC S16 rgSCHSCellPCqiCfg ARGS((
123 RgSchCellCb  *priCellCb,
124 RgSchCellCb  *secCellCb,
125 RgSchUeCb    *ueCb,
126 RgrUePrdDlCqiCfg  *cqiCfg,
127 CmLteUeCategory   ueCat,
128 U8            sCellIdx
129 ));
130 #endif
131 PRIVATE S16 rgSCHSCellTrgMacHqEReset ARGS((
132 Inst          inst,
133 U16           secCellId,
134 U16           rnti
135 ));
136
137
138
139 /** * @brief Handler for scheduling Scell Activation CE.
140  *
141  * @details
142  *
143  *     Function : rgSCHDhmShcdSCellActCe
144  *     
145  *     This function is called by scheduler when resource allocation
146  *     for SCell Activation CE transmission is done.
147  *           
148  *  @param[in]  RgSchUeCb         *ue
149  *  @param[out] RgSchDlHqTbCb     *tbInfo
150  *  @return     Void
151  *      -# None.
152  **/
153 #ifdef ANSI
154 PUBLIC Void rgSCHSCellSchdActDeactCe
155 (
156 RgSchUeCb         *ueCb,
157 RgSchDlHqTbCb     *tbInfo
158 )
159 #else
160 PUBLIC Void rgSCHSCellSchdActDeactCe(ueCb, tbInfo)
161 RgSchUeCb         *ueCb;
162 RgSchDlHqTbCb     *tbInfo;
163 #endif
164 {
165
166    U8   bitVal = 0;
167    U8   sCellActDeactBitMask = 0;
168    TRC3(rgSCHSCellSchdActDeactCe);
169
170    /* Change the state of all Scells waiting for
171     * activation */
172
173    /* -------------------------
174     * | C7|C6|C5|C4|C3|C2|C1|R|
175     * -------------------------*/
176     /* 1 for activation
177      * 0 for deactivation
178      * */
179
180    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
181    {
182       if(ueCb->cellInfo[idx] != NULLP)
183       {
184          switch(ueCb->cellInfo[idx]->sCellState)
185          {
186             case RG_SCH_SCELL_TOBE_ACTIVATED:
187             case RG_SCH_SCELL_ACTVTN_IN_PROG:
188                {
189                   ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_ACTVTN_IN_PROG; 
190                   bitVal = 1;
191                }
192                break;
193             case RG_SCH_SCELL_ACTIVE:
194                {
195                   bitVal = 1;
196                }
197                break;
198             case RG_SCH_SCELL_TOBE_DEACTIVATED:
199             case RG_SCH_SCELL_DEACTVTN_IN_PROG:
200                {
201                   ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_DEACTVTN_IN_PROG; 
202                   bitVal = 0;
203                }
204                break;
205             case RG_SCH_SCELL_INACTIVE:
206             case RG_SCH_SCELL_READY:
207                {
208                   bitVal = 0;
209                }
210                break;
211          }
212       }
213       if(1 == bitVal)
214       {
215          sCellActDeactBitMask |= 1 << (idx);/* servCellIdx = idx + 1 */
216          bitVal = 0;
217       }
218    }
219    tbInfo->schdSCellActCe.pres    = PRSNT_NODEF;
220    tbInfo->schdSCellActCe.val     = sCellActDeactBitMask;
221
222    RETVOID;
223 } /* rgSCHSCellSchdActDeactCe */
224
225 \f
226 /**
227  * @brief Adds an UE to the Cell's SCell Activation list
228  *
229  * @details
230  *
231  *     Function: rgSCHSCellAddToActDeactLst
232  *     Purpose:  Adds an UE to Cell's SCEll Act list
233  *
234  *     Invoked by: Common Scheduler
235  *
236  *  @param[in]  RgSchCellCb*     cell
237  *  @param[in]  RgSchUeCb*       ue
238  *  @return  Void
239  *
240  **/
241 #ifdef ANSI
242 PUBLIC Void rgSCHSCellAddToActDeactLst
243 (
244 RgSchCellCb                *cell,
245 RgSchUeCb                  *ue
246 )
247 #else
248 PUBLIC Void rgSCHSCellAddToActDeactLst(cell, ue)
249 RgSchCellCb                *cell;
250 RgSchUeCb                  *ue;
251 #endif
252 {
253    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
254    TRC3(rgSCHSCellAddToActDeactLst);
255
256    if(NULLP == ue->sCellActLnk.node)
257    {/* Ue is not present in the list */
258       cmLListAdd2Tail(&cellCmnDl->secCellActCeLst, &ue->sCellActLnk);
259       ue->sCellActLnk.node = (PTR)ue;
260    }
261    else
262    {
263       RGSCHDBGINFONEW(cell->instIdx,(rgSchPBuf(cell->instIdx),
264             "SCell is already added in the Act List: ueId(%u)\n", ue->ueId));
265    }
266    
267    RETVOID;
268 }
269
270 \f
271 /**
272  * @brief Removes an UE from Cell's SCell Activation list
273  *
274  * @details
275  *
276  *     Function: rgSCHSCellRmvFrmActLst
277  *     Purpose:  Removes an UE from Cell's SCEll Act list
278  *
279  *     Invoked by: Specific Scheduler
280  *
281  *  @param[in]  RgSchCellCb*     cell
282  *  @param[in]  RgSchUeCb*       ue
283  *  @return  Void
284  *
285  **/
286 #ifdef ANSI
287 PUBLIC Void rgSCHSCellRmvFrmActLst
288 (
289 RgSchCellCb                *cell,
290 RgSchUeCb                  *ue
291 )
292 #else
293 PUBLIC Void rgSCHSCellRmvFrmActLst(cell, ue)
294 RgSchCellCb                *cell;
295 RgSchUeCb                  *ue;
296 #endif
297 {
298    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
299    TRC3(rgSCHSCellRmvFrmActLst);
300    if (NULLP != ue->sCellActLnk.node)
301    {
302       cmLListDelFrm(&cellCmnDl->secCellActCeLst, &ue->sCellActLnk);
303    }
304    ue->sCellActLnk.node = (PTR)NULLP;
305
306    RETVOID;
307 }
308 \f
309 /**
310  * @brief Handling of SCell Activation
311  *
312  * @details
313  *
314  *     Function: rgSCHSCellActivation
315  *     Purpose : Perform Activation of secondary cell
316  *             : Move the state to ACTIVE
317  *             : Start the procedure for PCQI/SRS for this scell
318  *
319  *     Invoked by:Cfg/Commn Scheduler 
320  *
321  *  @param[in]  RgSchUeCellInfo *sCellInfo
322  *
323  *  @return  ROK/RFAILED
324  *
325  **/
326 #ifdef ANSI
327 PUBLIC Void rgSCHSCellActivation
328 (
329 RgSchUeCellInfo  *sCellInfo
330 )
331 #else
332 PUBLIC Void rgSCHSCellActivation(sCellInfo)
333 RgSchUeCellInfo  *sCellInfo
334 #endif
335 {
336    RgSchCellCb  *sCell = sCellInfo->cell;
337    RgSchUeCb    *ueCb = sCellInfo->ue;
338    RgSchCmnCell *cellSch;
339 #ifdef TFU_UPGRADE
340 #ifdef DEBUGP
341    Inst   inst = ueCb->cell->instIdx;
342 #endif
343    U16    tempIdx; 
344    RgrUePrdDlCqiCfg  *cqiCfg;
345    U8     j;  /*Bandwidth Parts*/
346    U16    riTrInsTime; 
347    U16    periodicity; 
348    U16    cqiTrInstTime; 
349    RgSchUePCqiCb *cqiCb = NULLP;
350    CmLteTimingInfo timingInfo;
351    U16    crntTime;           
352 #endif
353
354    TRC3(rgSCHSCellActivation);
355
356    sCellInfo->sCellState = RG_SCH_SCELL_ACTIVE;
357 #ifdef TENB_STATS
358    ueCb->tenbStats->stats.persistent.numActivation++;
359 #endif
360
361 #ifdef CA_DBG 
362    printf("ueId is SCELL_ACTIVE\n ueCb->ueId = %d sCell->sCellIdx =%d, sCell->sCellId=%d, sCell->sCellState=%d \n", ueCb->ueId, sCellInfo->sCellIdx, sCellInfo->sCellId, sCellInfo->sCellState);
363 #endif
364    /* Start the sCellDeactivation timer if cfgd */
365    if(PRSNT_NODEF == ueCb->sCellDeactTmrVal.pres)
366    {
367       //rgSCHTmrStartTmr (sCell,sCellInfo ,RG_SCH_TMR_SCELL_DEACT,
368         //    ueCb->sCellDeactTmrVal.val);
369    }
370
371 #ifdef TFU_UPGRADE
372    /* Start receiving CQI for this SCell for this UE */
373    crntTime = (ueCb->cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G)+
374                   (ueCb->cell->crntTime.subframe);
375
376    cqiCb = &sCellInfo->cqiCb;
377    cqiCfg = &cqiCb->cqiCfg;
378    if (cqiCfg->type == RGR_SCH_PCQI_SETUP)
379    {
380       cqiTrInstTime = ((cqiCb->cqiPeri+crntTime) - cqiCb->cqiOffset)
381          %cqiCb->cqiPeri;
382       cqiCb->nCqiTrIdx = (crntTime + 
383             (cqiCb->cqiPeri - cqiTrInstTime));
384       /* Introduced timing delta for reception req
385        * in FDD*/
386       if(cqiCb->nCqiTrIdx  <= (crntTime + TFU_RECPREQ_DLDELTA))
387       {
388          cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx + cqiCb->cqiPeri;
389       }
390
391       timingInfo.sfn =  cqiCb->nCqiTrIdx/RGSCH_NUM_SUB_FRAMES_5G;
392       timingInfo.subframe =  cqiCb->nCqiTrIdx%RGSCH_NUM_SUB_FRAMES_5G;
393       if(cqiCb->cqiCfg.cqiSetup.cqiRepType == RGR_UE_PCQI_SB_REP)
394       {
395          rgSCHTomUtlPcqiSbCalcBpIdx(timingInfo,ueCb,cqiCb); 
396       }
397
398       cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx
399          %RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
400       RGSCHDBGINFONEW(inst, (rgSchPBuf(inst), "CQI Config: idx(%u) Periodicity %u"
401                "Offset %u uePosInQ (%u)\n", cqiCfg->cqiSetup.cqiPCfgIdx,
402                cqiCb->cqiPeri, cqiCb->cqiOffset,cqiCb->nCqiTrIdx));
403
404       cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst,
405             &cqiCb->cqiLstEnt);  
406
407       rgSCHUtlSCellHndlCqiCollsn(cqiCb);
408
409       RGSCHDBGINFO(inst,(rgSchPBuf(inst), 
410                "\n rgSCHCfgPCqiUeCfg():"
411                "  CrntTime=%d  Next CqiTrInstTime=%d  Index Stored at=%d  ",
412                crntTime, cqiTrInstTime, cqiCb->nCqiTrIdx));
413
414       if(cqiCfg->cqiSetup.riEna)
415       {
416          cqiCb->perRiVal = 1;
417          cqiCb->invalidateCqi = FALSE;
418
419          if(RGR_UE_PCQI_WB_REP == cqiCfg->cqiSetup.cqiRepType)
420          {
421             /* 
422                1. wideband RI reporting is configured 
423                (Mode 1-0 or 1-1)
424                (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )Mod(NCqiperiod
425              *MriPeriod)=0  
426              */ 
427             periodicity = cqiCb->cqiPeri * cqiCb->riPeri; 
428          }
429          else
430          {
431             /*
432              *  Where Widesband and Subband RI reporting is configured
433              *   (Mode 2-0 or 2-1 )
434              *   (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )
435              *   Mod(H. NCqiperiod *MriPeriod )=0 
436              *   where H= J * K +1;  J=Number of bandwidth parts(BW/subsize). 
437              *   K is RGR interf input 
438              */
439
440             RG_SCH_GET_CQI_J_VAL(sCell->bwCfg.dlTotalBw, j);
441             cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1;  
442             periodicity = cqiCb->h * cqiCb->cqiPeri * 
443                cqiCb->riPeri; 
444
445          }
446
447          /* In case of SFN wraparound, the SB CQI reporting cycle breaks
448           * and RI->WB CQI->SBCQI.. should resume. RI is repositioned 
449           * accordingly. WBCQI handling is naturally accomplished */
450          if (periodicity >= RGSCH_MAX_SUBFRM_5G)
451          {
452             periodicity = cqiCb->cqiOffset - cqiCb->riOffset + 
453                RGSCH_MAX_SUBFRM_5G - (crntTime);
454             tempIdx = crntTime + periodicity;
455          }
456          else
457          {
458             riTrInsTime = ((periodicity +crntTime )- \
459                   cqiCb->cqiOffset + cqiCb->riOffset)\
460                           % periodicity;
461             tempIdx = (crntTime + (periodicity -riTrInsTime));
462          }
463          if (tempIdx <= (crntTime + TFU_RECPREQ_DLDELTA))
464          {
465             tempIdx = tempIdx + periodicity; 
466          }
467          cqiCb->nRiTrIdx = tempIdx 
468             % RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
469          if(periodicity >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE)
470          {  
471             cqiCb->riDist = rgSCHUtlFindDist((U16)(crntTime + TFU_RECPREQ_DLDELTA),
472                   (U16) tempIdx);
473          }
474          else
475          {
476             cqiCb->riDist =0; 
477          }
478
479
480          /* Start receiving RI for this SCell for this UE */
481          cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst,
482                &cqiCb->riLstEnt);  
483          RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_ADD,
484             &ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst);
485
486          rgSCHUtlSCellHndlRiCollsn(cqiCb);
487          /*werror*/
488 #ifndef BIT_64
489          RGSCHDBGINFONEW(inst,(rgSchPBuf(inst), "SCel RI cfg:"
490                   "idx %u period %u Offset %u posInQ(%u) riDist(%u)lst count"
491                   "%lu\n", cqiCfg->cqiSetup.riCfgIdx, cqiCb->riPeri,
492                   cqiCb->riOffset, cqiCb->nRiTrIdx, cqiCb->riDist, 
493                   ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst.count));
494 #else
495          RGSCHDBGINFONEW(inst,(rgSchPBuf(inst), "SCel RI cfg:"
496                   "idx %u period %u Offset %u posInQ(%u) riDist(%u)lst count"
497                   "%u\n", cqiCfg->cqiSetup.riCfgIdx, cqiCb->riPeri,
498                   cqiCb->riOffset, cqiCb->nRiTrIdx, cqiCb->riDist, 
499                   ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst.count));
500
501
502 #endif
503
504          RGSCHDBGINFO(inst,(rgSchPBuf(inst),
505                   "\n rgSCHSCellActivation(): CrntTime=%d Next RiTrInstTime=%d"
506                   "Index Stored at=%d riDis=%d ",
507                   crntTime, riTrInsTime, cqiCb->nRiTrIdx, cqiCb->riDist));
508       }
509    }
510 #endif
511
512    cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell);
513    cellSch->apisDl->rgSCHDlSCellActv(sCellInfo->cell, sCellInfo->ue);
514
515    RETVOID;
516 }
517
518 #ifdef TFU_UPGRADE
519 \f
520 /**
521  * @brief Remove CQI from Scell Lst
522  *
523  * @details
524  *
525  *     Function: rgSCHCellClearScellLstOfCQI
526  *     Purpose : Remove CQI from Scell Lst
527  *              
528  *
529  *     Invoked by: Timer
530  *
531  *  @param[in]  RgSchUeCellInfo *sCellInfo
532  *  @return  Void
533  *
534  **/
535 #ifdef ANSI
536 PRIVATE Void rgSCHCellClearScellLstOfCQI
537 (
538 RgSchUeCellInfo *sCellInfo
539 )
540 #else
541 PRIVATE Void rgSCHCellClearScellLstOfCQI(sCellInfo)
542 RgSchUeCellInfo *sCellInfo;
543 #endif
544 {
545
546    TRC3(rgSCHCellClearScellLstOfCQI);
547    RgSchUePCqiCb *cqiRiCb = NULLP;
548    RgSchUeCb    *ueCb;
549    ueCb = sCellInfo->ue;
550    /* Clear CQI/RI entry for this SCELL */
551    cqiRiCb = &sCellInfo->cqiCb;
552    /* Delete Periodic CQI/PMI  Transmission Instance  */
553    if (cqiRiCb->nCqiTrIdx != RG_SCH_INVALID_IDX)
554    {
555       cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nCqiTrIdx].cqiLst, 
556             &cqiRiCb->cqiLstEnt); 
557       cqiRiCb->nCqiTrIdx = RG_SCH_INVALID_IDX;
558
559       if (ueCb->nPCqiCb == cqiRiCb)
560       {
561          rgSCHUtlSCellHndlCqiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb);
562       }
563       /* Delete Periodic  RI  Transmission Instance  */
564
565       if (cqiRiCb->nRiTrIdx != RG_SCH_INVALID_IDX)
566       {
567          cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst, 
568                &cqiRiCb->riLstEnt); 
569          RG_SCH_RECORD(&cqiRiCb->histElem,RGSCH_ACTION_DEL,
570             &ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst);
571          cqiRiCb->nRiTrIdx = RG_SCH_INVALID_IDX;
572          if (ueCb->nPRiCb == cqiRiCb)
573          {
574             rgSCHUtlSCellHndlRiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb);
575          }
576       }
577    }
578
579    RETVOID;
580 }
581 #endif/*TFU_UPGRADE*/
582 \f
583 /**
584  * @brief Handling of SCell DeActivation
585  *
586  * @details
587  *
588  *     Function: rgSCHSCellDeActivation
589  *     Purpose : Perform Deactivation of secondary cell
590  *             : Move the state to IN_ACTIVE
591  *             : Flush the harqEntity
592  *             : Trigger harqEntity flushing to MAC
593  *             : Remove  PCQI/SRS for this scell
594  *             : Stop Deactivation timer if running
595  *
596  *     Invoked by:Cfg/Commn Scheduler 
597  *
598  *  @param[in]  RgSchUeCellInfo *sCellInfo
599  *
600  *  @return  ROK/RFAILED
601  *
602  **/
603 #ifdef ANSI
604 PRIVATE S16 rgSCHSCellDeActivation
605 (
606 RgSchUeCellInfo *sCellInfo
607 )
608 #else
609 PRIVATE S16 rgSCHSCellDeActivation(sCellInfo)
610 RgSchUeCellInfo *sCellInfo
611 #endif
612 {
613    RETVALUE(ROK);
614    RgSchCmnCell *cellSch;
615    Inst inst = sCellInfo->cell->instIdx;
616
617    TRC3(rgSCHSCellDeActivation);
618    /* Stop the timer if running */
619
620    if(sCellInfo->deactTmr.tmrEvnt != TMR_NONE)
621    {
622       rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_DEACT, sCellInfo);
623    }
624
625    if (sCellInfo->actDelayTmr.tmrEvnt != TMR_NONE)
626    {
627       rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_ACT_DELAY, sCellInfo);
628    }
629
630    cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell);
631    cellSch->apisDl->rgSCHDlUeReset(sCellInfo->cell, sCellInfo->ue);
632
633    if(sCellInfo->ue->isDrxEnabled)
634    {   
635       rgSCHDrxUeHqReset(sCellInfo->ue->cell, sCellInfo->ue, 
636                         sCellInfo->hqEnt, sCellInfo->sCellIdx);
637    }
638
639    /* Flush the harqEntity at scheduler */
640    if(sCellInfo->hqEnt != NULLP) 
641    {
642       rgSCHDhmHqEntReset(sCellInfo->hqEnt);
643    }
644    /* Trigger harq flush req to MAC */
645
646
647    rgSCHSCellTrgMacHqEReset(inst,sCellInfo->sCellId,sCellInfo->ue->ueId);
648    
649    sCellInfo->sCellState = RG_SCH_SCELL_READY;
650 #ifdef TFU_UPGRADE
651    rgSCHCellClearScellLstOfCQI(sCellInfo);
652 #endif
653
654 #ifdef TENB_STATS
655    sCellInfo->ue->tenbStats->stats.persistent.numDeactivation++;
656 #endif
657
658    cellSch->apisDl->rgSCHDlSCellDeactv(sCellInfo->cell, sCellInfo->ue);
659
660 #ifdef CA_DBG 
661    printf("SCELL DEATIVATED  sCellInfo->ue->ueId =%d, sCellInfo->sCellId =%d\n", sCellInfo->ue->ueId, sCellInfo->sCellId);
662    //MSPD_DBG("SCELL DEATIVATED  sCellInfo->ue->ueId =%d, sCellInfo->sCellId =%d\n", sCellInfo->ue->ueId, sCellInfo->sCellId);
663 #endif
664    RETVALUE(ROK);
665 }
666
667 \f
668 /**
669  * @brief Triggering hqEntity reset to mac
670  *
671  * @details
672  *
673  *     Function: rgSCHSCellTrgMacHqEReset
674  *     Purpose: Frame the interface for mac to reset
675  *              the mac
676  *              Derive the macInstance corresponding
677  *              to the secondary cell going to be deactivated.
678  *              Triiger the msg to that macInstance
679  *
680  *     Invoked by: CommonScheduler
681  *
682  *  @param[in]  U16        sCellId
683  *  @param[in]  U16        rnti
684  *  @return  Void
685  *
686  **/
687 #ifdef ANSI
688 PRIVATE S16 rgSCHSCellTrgMacHqEReset
689 (
690 Inst          inst,
691 U16           secCellId,
692 U16           rnti
693 )
694 #else
695 PRIVATE S16 rgSCHSCellTrgMacHqEReset(inst,secCellId,rnti)
696 Inst          inst;
697 U16           secCellId;
698 U16           rnti;
699 #endif
700 {
701    Pst               pst;
702    RgSchCellCb      *secCellCb = NULLP;
703    RgInfResetHqEnt   hqEntRstInfo;
704
705    if((secCellCb = (RgSchCellCb *)rgSchUtlGetCellCb(inst, secCellId)) == NULLP)
706    {
707       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCell doesnt exists"));
708       RETVALUE(RFAILED);
709    }
710
711    hqEntRstInfo.cellId = secCellId;
712    hqEntRstInfo.crnti  = rnti;
713
714    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], secCellCb->macInst);
715
716    RgSchMacRstHqEnt(&pst, &hqEntRstInfo);
717
718    RETVALUE(ROK);
719 }
720 /*removed endif*/
721
722
723 \f
724 /**
725  * @brief Handling of harq feeback for SCell act CE txion
726  *
727  * @details
728  *
729  *     Function: rgSCHSCellHndlFdbkInd
730  *     Purpose:  Handling the harq feedback for SCell ACT ce txion
731  *               ACK:: Set the state as active for the Scells for which
732  *                     CE was sent
733  *               HQ FAILURE/DTX/NACK:: Perform retxion. Add to Act CE list
734  *                                   Set the state to TOBE_SCHEDULED
735  *               
736  *
737  *     Invoked by: CommonScheduler
738  *
739  *  @param[in]  RgSchCellCb*     cell
740  *  @param[in]  RgSchUeCb*       ue
741  *  @return  Void
742  *
743  **/
744 #ifdef ANSI
745 PUBLIC Void rgSCHSCellHndlFdbkInd
746 (
747 RgSchDlHqProcCb   *hqP,
748 U8                tbIdx,
749 U8                fdbk,
750 Bool              maxHqRetxReached
751 )
752 #else
753 PUBLIC Void rgSCHSCellHndlFdbkInd(hqP, tbIdx, fdbk,maxHqRetxReached)
754 RgSchDlHqProcCb   *hqP;
755 U8                tbIdx;
756 U8                fdbk;
757 Bool              maxHqRetxReached;
758 #endif
759 {
760
761    RgSchUeCb      *ueCb;
762    RgSchCellCb    *cell;
763    RgSchUeCellInfo *sCellInfo;
764
765    TRC3(rgSCHSCellHndlFdbkInd);
766
767    ueCb  = hqP->hqE->ue;
768    cell  = ueCb->cell;
769    switch(fdbk)
770    {
771       case TFU_HQFDB_ACK:
772          {
773             hqP->tbInfo[tbIdx].schdSCellActCe.pres =  FALSE;
774
775             for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
776             {
777                if(ueCb->cellInfo[idx] != NULLP) 
778                {
779                   if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG)
780                   {
781 #ifdef CA_DBG
782                      printf("\n starting delay timer...\n");
783 #endif                     
784                      rgSCHTmrStartTmr (cell,ueCb->cellInfo[idx] ,RG_SCH_TMR_SCELL_ACT_DELAY,
785                            RG_SCH_CMN_SCELL_ACT_DELAY_TMR);
786                   }
787                   else
788                   {
789                      if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG)
790                      {
791                         sCellInfo = ueCb->cellInfo[idx];
792                         rgSCHSCellDeActivation(sCellInfo);
793                      }
794                   }
795                }
796             }
797          }
798          break;
799       case TFU_HQFDB_NACK:
800       case TFU_HQFDB_DTX:
801          {
802             if(TRUE == maxHqRetxReached)
803             {
804                hqP->tbInfo[tbIdx].schdSCellActCe.pres =  FALSE;
805                for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
806                {
807                   if(ueCb->cellInfo[idx] != NULLP) 
808                   {
809                      if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG)
810                      {
811                         ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED;
812                      }
813                      else
814                      {
815                         if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG)
816                         {
817                            ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED;
818                         }
819                      }
820                   }
821                   /* Add to actDeactCe lst */
822                   rgSCHSCellAddToActDeactLst(cell,ueCb);
823                }
824             }
825          }
826          break;
827       default:
828          break;
829    }
830    RETVOID;
831 }
832
833 #ifdef LTE_ADV
834 /**
835  * @brief Handling of SCell Deactivation Tmr Expiry
836  *
837  * @details
838  *
839  *     Function: rgSCHSCellDeactTmrExpry
840  *     Purpose : Deactivating the SCell. a
841  *               Clear all the Harq Procs associated with this
842  *               scell.
843  *               Trigger Harq Reset to the respective MAC
844  *               Set the state of the cell to Inactive  
845  *              
846  *
847  *     Invoked by: Timer
848  *
849  *  @param[in]  RgSchUeCellInfo *sCellInfo
850  *  @return  Void
851  *
852  **/
853 #ifdef ANSI
854 PUBLIC Void rgSCHSCellDeactTmrExpry
855 (
856 RgSchUeCellInfo *sCellInfo
857 )
858 #else
859 PUBLIC Void rgSCHSCellDeactTmrExpry(sCellInfo)
860 RgSchUeCellInfo *sCellInfo;
861 #endif
862 {
863
864    TRC3(rgSCHSCellDeactTmrExpry);
865    if (sCellInfo->ue->isScellExplicitDeAct == TRUE)
866    {
867       /* Deactivation Timer is not configured (infinity), thus send deactivation CE explicitly */ 
868       /* No doing Deactivaiton of LAA Cell */
869       if (FALSE == rgSCHLaaSCellEnabled(sCellInfo->cell))
870       {
871          rgSCHSCellTrigActDeact(sCellInfo->ue->cell, sCellInfo->ue, sCellInfo->sCellIdx, RGR_SCELL_DEACT);
872       }
873       else
874       {
875          printf (" !!!!!! Avoiding DEACT for UE %d because of LAA Cell !!!!!!!!!!!!! \n",
876          sCellInfo->ue->ueId);
877       }
878
879    }
880    else
881    {
882       /* Deactivation Timer is configured, thus assume that UE has deactivated */ 
883       rgSCHSCellDeActivation(sCellInfo);
884    }
885    RETVOID;
886 }
887 #endif
888 \f
889 /**
890  * @brief This function handles the action of the SCell
891  *
892  * @details
893  *
894  *     Function: rgSCHSCellTrigActDeact
895  *     Purpose :  
896  *        1) Prepares SCELL ready for activation OR
897  *        2) Initiates activation of SCELL OR
898  *        3) Initiate deactivation of SCELL OR
899  *
900  *     Invoked by:Cfg/Commn Scheduler 
901  *
902  *  @param[in]  RgSchCellCb *cellCb
903  *  @param[in]  RgSchUeCb   *ueCb
904  *  @param[in]  U8           sCellIdx
905  *  @param[in]  U8           action
906  *
907  *  @return  ROK/RFAILED
908  *
909  **/
910 #ifdef ANSI
911 PUBLIC S16 rgSCHSCellTrigActDeact
912 (
913 RgSchCellCb  *cell,
914 RgSchUeCb    *ueCb,
915 U8            sCellIdx,
916 U8            action
917 )
918 #else
919 PUBLIC S16 rgSCHSCellTrigActDeact(cell,ueCb,sCellIdx,action)
920 RgSchCellCb  *cell,
921 RgSchUeCb    *ueCb;
922 U8            sCellIdx;
923 U8            action;
924 #endif
925 {
926    Inst inst = cell->instIdx;
927    S16 ret   = ROK;
928
929    TRC3(rgSCHSCellTrigActDeact);
930
931    if((sCellIdx < 1) ||
932       (sCellIdx > RGR_MAX_SCELL_PER_UE))
933    {
934       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n", \
935                sCellIdx));
936       RETVALUE(RFAILED);
937    }
938
939    if(ueCb->cellInfo[sCellIdx] == NULLP)
940    {
941       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Serv Cell not added to this Ue Scell Idx %d ueId %d\n", \
942               sCellIdx,ueCb->ueId));
943       RETVALUE(RFAILED);
944    }
945
946    switch (action)
947    {
948       case RGR_SCELL_READY:
949       {
950          if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_INACTIVE)
951          {
952             RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid state %u for preparing SCell Idx %u for UE %u\n", \
953                      ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId));
954             ret = RFAILED;
955          }
956          else
957          {
958             ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_READY;
959             //TODO_SID Activating the cell directly. Ignoring the ActCe procedure.
960             rgSCHSCellActivation(ueCb->cellInfo[sCellIdx]);
961             /* Setting allocCmnUlPdcch flag to FALSE, So that PDCCH allocation will be done 
962                from UE Searchspace */
963             ueCb->allocCmnUlPdcch = FALSE;
964             printf("\n***** SCellIdx=%d state Changed to %d State \n",sCellIdx, ueCb->cellInfo[sCellIdx]->sCellState);
965             printf("\n***** SCellInfo Addr=%p state Changed to RG_SCH_SCELL_READY\n",(void*)ueCb->cellInfo[sCellIdx]);
966          }
967          break;
968       }
969       case RGR_SCELL_ACT:
970       {
971          if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_READY)
972          {
973             RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid state %u for activating SCell Idx %u for UE %u\n", \
974                      ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId));
975             ret = RFAILED;
976          }
977          else
978          {
979             ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED;
980             if (NULLP == ueCb->sCellActLnk.node)
981             {
982                /* Add only if UE is not already present in the activation/deactivation list */
983                rgSCHSCellAddToActDeactLst(cell,ueCb);
984             }
985          }
986          break;
987       }
988       case RGR_SCELL_DEACT:
989       {
990          if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_ACTIVE)
991          {
992             RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid state %u for deactivating SCell Idx %u for UE %u\n", \
993                      ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId));
994             ret = RFAILED;
995          }
996          else
997          {
998             ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED;
999             if (NULLP == ueCb->sCellActLnk.node)
1000             {
1001                /* Add only if UE is not already present in the activation/deactivation list */
1002                rgSCHSCellAddToActDeactLst(cell,ueCb);
1003             }
1004          }
1005          break;
1006       }
1007       default:
1008       {
1009          RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid action received for SCell Idx %u for UE %u\n", \
1010                   sCellIdx, ueCb->ueId));
1011          ret = RFAILED;
1012          break;
1013       }
1014    }
1015    RETVALUE(ret);
1016 }
1017
1018  \f
1019 /**
1020  * @brief SCell Activation of selected cell
1021  *
1022  * @details
1023  *
1024  *     Function: rgSCHSCellSelectForAct
1025  *     Purpose :  Perform Selection of secondary cell for activation
1026  *
1027  *     Invoked by:Cfg/Commn Scheduler 
1028  *
1029  *  @param[in]  RgSchCellCb *cellCb
1030  *  @param[in]  RgSchUeCb   *ueCb
1031  *
1032  *  @return  ROK/RFAILED
1033  *
1034  **/
1035 #ifdef ANSI
1036 PRIVATE S16 rgSCHSCellSelectForAct
1037 (
1038 RgSchCellCb  *cell,
1039 RgSchUeCb    *ueCb,
1040 U8           *sCellIdx
1041 )
1042 #else
1043 PRIVATE S16 rgSCHSCellSelectForAct(cell, ueCb)
1044 RgSchCellCb  *cell;
1045 RgSchUeCb    *ueCb;
1046 U8           *sCellIdx;
1047 #endif
1048 {
1049    TRC3(rgSCHSCellSelectAndAct);
1050
1051    for((*sCellIdx) = 1; (*sCellIdx) <= RG_SCH_MAX_SCELL; (*sCellIdx)++)
1052    {
1053       if((ueCb->cellInfo[(*sCellIdx)] != NULLP) &&
1054             (ueCb->cellInfo[(*sCellIdx)]->sCellState == RG_SCH_SCELL_READY))
1055       {
1056          RETVALUE(ROK);
1057       }
1058    }
1059    RETVALUE(RFAILED);
1060 }
1061
1062 /**
1063  * @brief SCell Activation of selected cell
1064  *
1065  * @details
1066  *
1067  *     Function: rgSCHSCellSelectAndActDeAct
1068  *     Purpose :  Perform Selection and Activation/Deactivation of secondary cell
1069  *
1070  *     Invoked by:Cfg/Commn Scheduler 
1071  *
1072  *  @param[in]  RgSchCellCb *cellCb
1073  *  @param[in]  RgSchUeCb   *ueCb
1074  *  @param[in]  U8          action
1075  *
1076  *  @return  Void
1077  *
1078  **/
1079 #ifdef ANSI
1080 PUBLIC Void rgSCHSCellSelectAndActDeAct
1081 (
1082 RgSchCellCb  *pCell,
1083 RgSchUeCb    *ueCb,
1084 U8           action
1085 )
1086 #else
1087 PUBLIC Void rgSCHSCellSelectAndActDeAct(pCell, ueCb, action)
1088 RgSchCellCb  *pCell;
1089 RgSchUeCb    *ueCb;
1090 U8           action;
1091 #endif
1092 {
1093    U8  sCellIdx = 0;
1094    S16 ret = ROK;
1095
1096    switch (action)
1097    {
1098       case RGR_SCELL_ACT:
1099          {
1100
1101             if(((ret = rgSCHSCellSelectForAct(pCell, ueCb, &sCellIdx)) == ROK)
1102                   && (sCellIdx == 0))
1103                RETVOID;
1104             break;
1105          }
1106          default:
1107          RETVOID;
1108    }
1109    if ((ret != ROK) || 
1110          (ROK != (rgSCHSCellTrigActDeact(pCell, ueCb, sCellIdx, action))))
1111    {
1112       RGSCHDBGERR(pCell->instIdx,(rgSchPBuf(pCell->instIdx), "SCell Actication failed"
1113                "for UE [%d] with SCellIdx [%d]\n", ueCb->ueId, sCellIdx));
1114    }
1115    RETVOID;
1116 }
1117
1118  \f
1119 /**
1120  * @brief Handling of Scell Deletion 
1121  *
1122  * @details
1123  *
1124  *     Function: rgSCHSCellDelUeSCell
1125  *     Purpose : Perform Scell Deletion for an UE
1126  *             : flush harqEnttiy of the given scell associated
1127  *               with this UE
1128  *              
1129  *
1130  *     Invoked by:Cfg module 
1131  *
1132  *  @param[in]  RgSchCellCb  *cellCb
1133  *  @param[in]  RgSchUeCb    *ueCb
1134  *  @param[in]  U8            idx
1135  *  @return  ROK/RFAILED
1136  *
1137  **/
1138 #ifdef ANSI
1139 PUBLIC Void rgSCHSCellDelUeSCell
1140 (
1141 RgSchCellCb  *cellCb,
1142 RgSchUeCb    *ueCb,
1143 U8            sCellIdx
1144 )
1145 #else
1146 PUBLIC Void rgSCHSCellDelUeSCell(cellCb,ueCb,sCellIdx)
1147 RgSchCellCb  *cellCb;
1148 RgSchUeCb    *ueCb;
1149 U8            sCellIdx;
1150 #endif
1151 {
1152    RgUeUlHqCb       *ulHqEnt;
1153    Inst inst = cellCb->instIdx;
1154    RgSchUeCellInfo *sCellInfo;
1155    RgSchCmnUlUe *ueUl;
1156
1157    TRC3(rgSCHSCellDelUeSCell);
1158    sCellInfo = ueCb->cellInfo[sCellIdx];
1159
1160
1161    if(sCellInfo == NULLP)
1162    {
1163       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Serv Cell not added to this Ue Scell Idx %d\
1164                ueId %d\n",
1165                sCellIdx,ueCb->ueId));
1166       RETVOID;
1167    }
1168
1169    rgSCHDbmDelUeCb(sCellInfo->cell, ueCb);
1170    ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, sCellInfo->cell);
1171
1172    if (NULLP != sCellInfo->sCellLnk.node)
1173    {
1174       cmLListDelFrm(&sCellInfo->cell->sCellUeLst, &sCellInfo->sCellLnk);
1175    }
1176
1177    /* Clear Scheduler specific list for this UE from the 
1178     * corresponding CELL */
1179
1180    /*Updating 1BCS Value*/
1181    ueCb->f1bCsAVal = (ueCb->f1bCsAVal - 
1182          rgSCHUtlGetMaxTbSupp(sCellInfo->txMode.txModeEnum));
1183
1184 #ifdef LTE_TDD
1185    rgSCHUtlDelUeANFdbkInfo(ueCb,sCellIdx);
1186 #endif
1187
1188    rgSCHSCellDeActivation(sCellInfo);
1189    /* Release hqEnt mem */
1190    rgSCHDhmDelHqEnt(cellCb, &sCellInfo->hqEnt);
1191
1192    ulHqEnt = &(ueUl->hqEnt);
1193
1194    cellCb->sc.apis->rgSCHRgrSCellUeDel(sCellInfo, sCellInfo->ue);
1195
1196    rgSCHUhmFreeUe(sCellInfo->cell, ulHqEnt);
1197
1198    rgSCHUtlFreeSBuf(cellCb->instIdx,
1199          (Data**)(&(sCellInfo)), (sizeof(RgSchUeCellInfo)));
1200
1201    ueCb->cellInfo[sCellIdx] = NULLP;
1202    
1203    RETVOID;
1204 }
1205 \f
1206 /**
1207  * @brief Handling of UE Deletion
1208  *
1209  * @details
1210  *
1211  *     Function: rgSCHSCellDelUe
1212  *     Purpose : Perform UE Deletion
1213  *             : Delete all the SCells added for this UE
1214  *             : flush harqEnttiy of all scells associated
1215  *               with this UE
1216  *              
1217  *
1218  *     Invoked by:Cfg module 
1219  *
1220  *  @param[in]  RgSchCellCb  *cellCb
1221  *  @param[in]  RgSchUeCb    *ueCb
1222  *  @return  ROK/RFAILED
1223  *
1224  **/
1225 #ifdef ANSI
1226 PUBLIC S16 rgSCHSCellDelUe
1227 (
1228 RgSchCellCb  *cellCb,
1229 RgSchUeCb    *ueCb
1230 )
1231 #else
1232 PUBLIC S16 rgSCHSCellDelUe(cellCb,ueCb)
1233 RgSchCellCb  *cellCb;
1234 RgSchUeCb    *ueCb;
1235 #endif
1236 {
1237
1238    TRC3(rgSCHSCellDelUe);
1239
1240    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1241    {
1242       rgSCHSCellDelUeSCell(cellCb,ueCb,idx);
1243    }
1244
1245    RETVALUE(ROK);
1246 }
1247
1248 #ifdef TFU_UPGRADE
1249 \f
1250 /**
1251  * @brief Handling of PCqi cfg fro a scell
1252  *
1253  * @details
1254  *
1255  *     Function: rgSCHSCellPCqiCfg
1256  *     Purpose : 
1257  *             : Delete all the SCells added for this UE
1258  *             : flush harqEnttiy of all scells associated
1259  *               with this UE
1260  *    Processing Steps:
1261  *             - For SCell-specific Periodic CQI  related configuration, 
1262  *             - If Periodic CQI/PMI is configured,
1263  *                   - Update SCell with the configured values.
1264  *                   - Update the CQI offset and CQI perodicity information
1265  *        
1266  *
1267  *     - For SCell-specific Periodic RI  related configuration, 
1268  *      - If Periodic RI is configured,
1269  *        - Update SCell with the configured values.
1270  *         - Update the  RI offset and RI perodicity information
1271  *      
1272  *
1273  *     Invoked by:Cfg module 
1274  *
1275  *  @param[in]  RgSchCellCb  *cellCb
1276  *  @param[in]  RgSchUeCb    *ueCb
1277  *  @return  ROK/RFAILED
1278  *
1279  **/
1280 #ifdef ANSI
1281 PUBLIC S16 rgSCHSCellPCqiCfg
1282 (
1283 RgSchCellCb  *priCellCb,
1284 RgSchCellCb  *secCellCb,
1285 RgSchUeCb    *ueCb,
1286 RgrUePrdDlCqiCfg  *cqiCfg,
1287 CmLteUeCategory   ueCat,
1288 U8            sCellIdx
1289 )
1290 #else
1291 PUBLIC S16 rgSCHSCellPCqiCfg(priCellCb,secCellCb,ueCb,cqiCfg,ueCat,sCellIdx)
1292 RgSchCellCb       *priCellCb;
1293 RgSchCellCb       *secCellCb;
1294 RgSchUeCb         *ueCb;
1295 RgrUePrdDlCqiCfg  *cqiCfg;
1296 CmLteUeCategory    ueCat;
1297 U8                sCellIdx;
1298 #endif
1299 {
1300    U8     j;  /*Bandwidth Parts*/
1301    U8     temp; 
1302 #ifdef DEBUGP
1303    Inst   inst = priCellCb->instIdx;
1304 #endif
1305    RgSchUeCellInfo *sCellInfo;
1306    RgSchUePCqiCb *cqiCb = NULLP;
1307
1308    TRC3(rgSCHSCellPCqiCfg);
1309
1310    RGSCHDBGINFO(priCellCb->instIdx, (rgSchPBuf(priCellCb->instIdx), 
1311             "rgSCHSCellPCqiCfg cellId =%d, ueId = %d, CfgType =%d\n",
1312             secCellCb->cellId,  ueCb->ueId, cqiCfg->type));
1313    
1314    if((sCellIdx < 1) ||
1315       (sCellIdx > RGR_MAX_SCELL_PER_UE))
1316    {
1317       RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n",
1318                sCellIdx));
1319       RETVALUE(RFAILED);
1320    }
1321
1322    sCellInfo = ueCb->cellInfo[sCellIdx];
1323
1324    cqiCb = &ueCb->cellInfo[sCellIdx]->cqiCb;
1325    cqiCb->servCellInfo = sCellInfo;
1326
1327    /* Periodic CQI is setup  */
1328    if (cqiCfg->type == RGR_SCH_PCQI_SETUP)
1329    {   
1330       /*  1. Copy the Received CQI Cfg parameters to ueCb  */
1331       cmMemcpy((U8 *)&cqiCb->cqiCfg, (U8 *)cqiCfg, 
1332             sizeof(RgrUePrdDlCqiCfg));
1333
1334       /*  2. Compute Periodic CQI Periodicity and subframe offset   */
1335 #ifndef LTE_TDD           
1336       rgSCHUtlGetCfgPerOff(RG_SCH_FDD_PCQI_TBL, cqiCfg->cqiSetup.cqiPCfgIdx,
1337             &cqiCb->cqiPeri, &cqiCb->cqiOffset);      
1338 #else
1339       rgSCHUtlGetCfgPerOff( RG_SCH_TDD_PCQI_TBL, 
1340             cqiCfg->cqiSetup.cqiPCfgIdx,
1341             &cqiCb->cqiPeri, &cqiCb->cqiOffset);    
1342 #endif
1343
1344
1345       RGSCHDBGINFO(priCellCb->instIdx,(rgSchPBuf(priCellCb->instIdx), 
1346                "\n rgSCHSCellPCqiCfg(): CQI Peri=%d, CQI Offset=%d", 
1347                cqiCb->cqiPeri,cqiCb->cqiOffset));
1348
1349       if(RGR_UE_PCQI_SB_REP == cqiCfg->cqiSetup.cqiRepType)
1350       {
1351          U8     k;  /*SubBand Size (RB) */
1352          RG_SCH_GET_CQI_J_VAL(secCellCb->bwCfg.dlTotalBw, j);
1353          RG_SCH_GET_CQI_K_VAL(secCellCb->bwCfg.dlTotalBw, k);
1354          cqiCb->J = j; /*Number of Bandwidth Parts*/
1355          /*h: reporting instances required for a complete CQI/PMI report */
1356          /*j:Number of bandwidth parts; k: Subband Size*/
1357          cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1; 
1358          /* ccpu00140905- L-size is coming as 3 for 100Rbs where it should be 2*/
1359          temp = RGSCH_CEIL(secCellCb->bwCfg.dlTotalBw, (j*k));
1360          cqiCb->label = (temp & (temp-1)) ?
1361             (1+ rgSCHUtlLog32bitNbase2(temp)) : rgSCHUtlLog32bitNbase2(temp);
1362       }
1363       else
1364       {
1365          /* Wideband Cqi Rep Type */
1366          cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_1;
1367       }
1368       cqiCb->cqiLstEnt.node=(PTR)cqiCb;
1369       cqiCb->isCqiIgnoByCollsn = FALSE;
1370
1371
1372       /* 4. Rank Indicator Cfg handler */
1373       /* 1. Rank Indicator is enabled  */
1374       if(cqiCfg->cqiSetup.riEna)
1375       {
1376          rgSCHUtlGetCfgPerOff(RG_SCH_RI_TBL, 
1377                cqiCfg->cqiSetup.riCfgIdx,
1378                &cqiCb->riPeri, &cqiCb->riOffset);
1379
1380          RGSCHDBGINFO(priCellCb->instIdx,(rgSchPBuf(priCellCb->instIdx),
1381                   "\n rgSCHSCellPCqiCfg(): RI Peri=%d, RI Offset=%d", 
1382                   cqiCb->riPeri,cqiCb->riOffset));
1383
1384          if(ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_3 
1385                || ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_4)
1386          {
1387             if (secCellCb->numTxAntPorts ==2)
1388             {
1389                cqiCb->riNumBits = 1;
1390             }
1391             else if(secCellCb->numTxAntPorts ==4)
1392             {
1393                if(ueCat == CM_LTE_UE_CAT_8)
1394                {
1395                   cqiCb->riNumBits = 3;
1396                }
1397                else if((ueCat == CM_LTE_UE_CAT_5) || 
1398                      (ueCat == CM_LTE_UE_CAT_6) || CM_LTE_UE_CAT_7)
1399                {
1400                   cqiCb->riNumBits = 2;
1401                }
1402                else
1403                {
1404                   cqiCb->riNumBits = 1;
1405                }
1406             }
1407          }
1408          cqiCb->riLstEnt.node=(PTR) cqiCb;
1409          cqiCb->isRiIgnoByCollsn = FALSE;
1410
1411       }
1412    }
1413    else
1414    {
1415       sCellInfo->cqiCb.cqiCfg.type =  RGR_SCH_PCQI_REL;
1416    }
1417    /* Setting the indices to invalid during
1418       scell addition. These indices will be set during 
1419       activation */
1420    cqiCb->nRiTrIdx  = RG_SCH_INVALID_IDX;
1421    cqiCb->riDist    = RG_SCH_INVALID_IDX; 
1422    cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX;
1423  
1424    RETVALUE(ROK);
1425 }
1426 #endif
1427
1428 /**
1429  * @brief Handling of Ue Reset from common scheduler
1430  *
1431  * @details
1432  *
1433  *     Function: rgSCHSCellDlUeReset
1434  *     Purpose:  Call scheudler type spcefic UE RESET
1435  *               for all the secondary cells
1436  *
1437  *     Invoked by: CommonScheduler
1438  *
1439  *  @param[in]  RgSchCellCb*     cell
1440  *  @param[in]  RgSchUeCb*       ue
1441  *  @return  Void
1442  *
1443  **/
1444 #ifdef ANSI
1445 PUBLIC Void rgSCHSCellDlUeReset
1446 (
1447 RgSchCellCb                *cell,
1448 RgSchUeCb                  *ue
1449 )
1450 #else
1451 PUBLIC Void rgSCHSCellDlUeReset(cell, ue)
1452 RgSchCellCb                *cell;
1453 RgSchUeCb                  *ue;
1454 #endif
1455 {
1456    RgSchCmnCell *cellSch;
1457    TRC3(rgSCHSCellDlUeReset);
1458
1459    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1460    {
1461       if(ue->cellInfo[idx] != NULLP) 
1462       {
1463          cellSch = RG_SCH_CMN_GET_CELL(ue->cellInfo[idx]->cell);
1464          cellSch->apisDl->rgSCHDlUeReset(ue->cellInfo[idx]->cell, ue);
1465          rgSCHSCellDeActivation(ue->cellInfo[idx]);
1466          ue->cellInfo[idx]->sCellState = RG_SCH_SCELL_INACTIVE;
1467       }
1468    }
1469    RETVOID;
1470 }
1471
1472
1473 /**
1474  * @brief Handling of LC Cfg from common scheduler
1475  *
1476  * @details
1477  *
1478  *     Function: rgSCHSCellDlLcCfg
1479  *     Purpose:  Call scheudler type spcefic LC config
1480  *               for all the secondary cells
1481  *
1482  *     Invoked by: CommonScheduler
1483  *
1484  *  @param[in]  RgSchCellCb*     cell
1485  *  @param[in]  RgSchUeCb*       ue
1486  *  @return  Void
1487  *
1488  **/
1489 #ifdef ANSI
1490 PUBLIC Void rgSCHSCellDlLcCfg
1491 (
1492 RgSchCellCb                *cell,
1493 RgSchUeCb                  *ue,
1494 RgSchDlLcCb                *svc
1495 )
1496 #else
1497 PUBLIC Void rgSCHSCellDlLcCfg(cell, ue, svc)
1498 RgSchCellCb                *cell;
1499 RgSchUeCb                  *ue;
1500 RgSchDlLcCb                *svc;
1501 #endif
1502 {
1503    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1504    TRC3(rgSCHSCellDlLcCfg);
1505    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1506    {
1507       if(ue->cellInfo[idx] != NULLP) 
1508       {
1509          cellSch->apisDl->rgSCHRgrDlLcCfg(ue->cellInfo[idx]->cell, ue, svc,NULLP,NULLP);
1510       }
1511    }
1512    RETVOID;
1513 }
1514
1515 /**
1516  * @brief Handling of LC Delete from common scheduler
1517  *
1518  * @details
1519  *
1520  *     Function: rgSCHSCellDlLcDel
1521  *     Purpose:  Call scheudler type spcefic bo update handler
1522  *               for all the secondary cells
1523  *
1524  *     Invoked by: CommonScheduler
1525  *
1526  *  @param[in]  RgSchCellCb*     cell
1527  *  @param[in]  RgSchUeCb*       ue
1528  *  @return  Void
1529  *
1530  **/
1531 #ifdef ANSI
1532 PUBLIC Void rgSCHSCellDlLcDel
1533 (
1534 RgSchCellCb                *cell,
1535 RgSchUeCb                  *ue,
1536 RgSchDlLcCb                *svc
1537 )
1538 #else
1539 PUBLIC Void rgSCHSCellDlLcDel(cell, ue, svc)
1540 RgSchCellCb                *cell;
1541 RgSchUeCb                  *ue;
1542 RgSchDlLcCb                *svc;
1543 #endif
1544 {
1545    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1546    TRC3(rgSCHSCellDlLcDel);
1547    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1548    {
1549       if(ue->cellInfo[idx] != NULLP) 
1550       {
1551          cellSch->apisDl->rgSCHFreeDlLc(ue->cellInfo[idx]->cell, ue, svc);
1552       }
1553    }
1554    RETVOID;
1555 }
1556
1557 /**
1558  * @brief Handling of Bo update from common scheduler
1559  *
1560  * @details
1561  *
1562  *     Function: rgSCHSCellDlDedBoUpd
1563  *     Purpose:  Call scheudler type spcefic bo update handler
1564  *               for all the secondary cells
1565  *
1566  *     Invoked by: CommonScheduler
1567  *
1568  *  @param[in]  RgSchCellCb*     cell
1569  *  @param[in]  RgSchUeCb*       ue
1570  *  @return  Void
1571  *
1572  **/
1573 #ifdef ANSI
1574 PUBLIC Void rgSCHSCellDlDedBoUpd
1575 (
1576 RgSchCellCb                *cell,
1577 RgSchUeCb                  *ue,
1578 RgSchDlLcCb                *svc
1579 )
1580 #else
1581 PUBLIC Void rgSCHSCellDlDedBoUpd(cell, ue, svc)
1582 RgSchCellCb                *cell;
1583 RgSchUeCb                  *ue;
1584 RgSchDlLcCb                *svc;
1585 #endif
1586 {
1587    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1588    TRC3(rgSCHSCellDlDedBoUpd);
1589
1590    /* If this is not invoked by PCell, then
1591       invoke the call to PCell handler 
1592       This happens during finalization if LC Bo becomes zero*/
1593    if (ue->cell != cell)
1594    {
1595       cellSch->apisDl->rgSCHDlDedBoUpd(ue->cell, ue, svc);
1596    }
1597    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1598    {
1599       if((ue->cellInfo[idx] != NULLP) &&
1600             (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE) &&
1601            (ue->cellInfo[idx]->cell != cell))
1602       {
1603          cellSch->apisDl->rgSCHDlDedBoUpd(ue->cellInfo[idx]->cell, ue, svc);
1604       }
1605    }
1606    RETVOID;
1607 }
1608 #ifdef TFU_UPGRADE
1609 /**
1610  * @brief Compare two CQI CB configs are return the result
1611  *
1612  * @details
1613  *
1614  *     Function: rgSCHUtlSCellCmpCqiCfg
1615  *     Purpose : Compare priority levels of cqiCb1 and cqiCb2
1616  *               and set the isCqiIgnoByCollsn to TRUE for the 
1617  *               cqiCb which has lower priority 
1618  *     Invoked by:scell module 
1619  *
1620  *  @param[in] RgSchUePCqiCb *cqiCb1
1621  *  @param[in] RgSchUePCqiCb *cqiCb2
1622  *  @return U8 cqiCb cell idx which has the higher priority
1623  *
1624  **/
1625 #ifdef ANSI
1626 PRIVATE U8  rgSCHUtlSCellCmpCqiCfg
1627 (
1628 RgSchUePCqiCb *cqiCb1,
1629 RgSchUePCqiCb *cqiCb2
1630 )
1631 #else
1632 PRIVATE U8  rgSCHUtlSCellCmpCqiCfg(cqiCb1, cqiCb2)
1633 RgSchUePCqiCb     *cqiCb1;
1634 RgSchUePCqiCb     *cqiCb2;
1635 #endif
1636 {
1637    RgSchUePCqiCb     *retCqiCb;
1638    TRC3(rgSCHUtlSCellCmpCqiCfg);
1639    /* Collision rules are defined in TS 36.213,7.2.2 */
1640    /* RI, WB first PMI > WB CQI >  SB CQI */
1641    /* As of now only taking care of RI > WB CQI > SB CQI */
1642
1643    if (cqiCb1->prioLvl > cqiCb2->prioLvl)
1644    {
1645       cqiCb2->isCqiIgnoByCollsn = TRUE;
1646       cqiCb1->isCqiIgnoByCollsn = FALSE;
1647       retCqiCb = cqiCb1;
1648    }
1649    else if (cqiCb2->prioLvl > cqiCb1->prioLvl)
1650    {
1651       cqiCb1->isCqiIgnoByCollsn = TRUE;
1652       cqiCb2->isCqiIgnoByCollsn = FALSE;
1653       retCqiCb = cqiCb2;
1654    }
1655    else
1656    {
1657       if (cqiCb1->servCellInfo->sCellIdx > cqiCb2->servCellInfo->sCellIdx)
1658       {
1659          cqiCb1->isCqiIgnoByCollsn = TRUE;
1660          cqiCb2->isCqiIgnoByCollsn = FALSE;
1661          retCqiCb = cqiCb2;
1662       }
1663       else
1664       {
1665          cqiCb2->isCqiIgnoByCollsn = TRUE;
1666          cqiCb1->isCqiIgnoByCollsn = FALSE;
1667          retCqiCb = cqiCb1;
1668       }
1669    }
1670
1671    RETVALUE(retCqiCb->servCellInfo->sCellIdx);
1672 }
1673
1674 /**
1675  * @brief Handling of collision of CQI types between serving cells
1676  *
1677  * @details
1678  *
1679  *     Function: rgSCHUtlSCellHndlCqiCollsn
1680  *     Purpose : Takes care of collision clauses specified in 36.213 7.2.2 Rel 10 
1681  *               and selects next nearest cqiCb 
1682  *     Invoked by:Cfg module 
1683  *
1684  *  @param[in]  RgSchCellCb  *cellCb
1685  *  @param[in]  RgSchUeCb    *ueCb
1686  *  @return  ROK/RFAILED
1687  *
1688  **/
1689 #ifdef ANSI
1690 PUBLIC S16 rgSCHUtlSCellHndlCqiCollsn
1691 (
1692 RgSchUePCqiCb *cqiCb
1693 )
1694 #else
1695 PUBLIC S16 rgSCHUtlSCellHndlCqiCollsn(cqiCb)
1696 RgSchUePCqiCb     *cqiCb;
1697 #endif
1698 {
1699    U32 nPCqiServCellIdx;
1700    U32 minPCqiTrIdx;
1701    U32 scellPCqiTrIdx;
1702    U32 pCqiTrIdx;
1703    RgSchCellCb       *priCellCb = cqiCb->servCellInfo->ue->cell;
1704    RgSchUeCb         *ueCb = cqiCb->servCellInfo->ue;
1705    U16 crntSfIdx;
1706    U32 cellIdx;
1707    U32 sCellCnt = 0;
1708    CmLteTimingInfo timingInfo;
1709    U8 idx = 0;
1710    TRC3(rgSCHUtlSCellHndlCqiCollsn);
1711
1712 #ifdef xLTE_TDD
1713    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA);
1714 #else
1715    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo,
1716          TFU_RECPREQ_DLDELTA);
1717 #endif
1718
1719    RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx);
1720
1721    cqiCb->isCqiIgnoByCollsn = FALSE;
1722
1723    pCqiTrIdx = cqiCb->nCqiTrIdx;
1724    nPCqiServCellIdx = cqiCb->servCellInfo->sCellIdx;
1725    /* Handle wrap around case */
1726    if (pCqiTrIdx < crntSfIdx)
1727    {
1728       pCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1729    }
1730    minPCqiTrIdx = pCqiTrIdx;
1731
1732    for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++)
1733    {
1734       /* If a serving cell is configured */
1735       if(ueCb->cellInfo[cellIdx] != NULLP)
1736       {
1737          /* If the serving cell is in ACTIVE state and 
1738             If it is not the same serving cell as cqiCb for which 
1739             collision is being checked */
1740          if ((ueCb->cellInfo[cellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)&&
1741                (cellIdx != cqiCb->servCellInfo->sCellIdx))
1742          {
1743             scellPCqiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nCqiTrIdx;
1744
1745             /* Handle wrap around case */
1746             if (scellPCqiTrIdx < crntSfIdx)
1747             {
1748                scellPCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1749             }
1750             
1751             /* If cqiCb->isCqiIgnoByCollsn is TRUE then a higher prio cqiCb
1752                is already found so need to compare */
1753             if ((FALSE == ueCb->cellInfo[cellIdx]->cqiCb.isCqiIgnoByCollsn) &&
1754                   (FALSE == cqiCb->isCqiIgnoByCollsn) && 
1755                   (scellPCqiTrIdx == pCqiTrIdx))
1756             {
1757                /* Handle Collision */
1758                /* set isCqiIgnoByCollsn to TRUE for low prio CQI Rep type */
1759                nPCqiServCellIdx = rgSCHUtlSCellCmpCqiCfg(&ueCb->cellInfo[cellIdx]->cqiCb,cqiCb);
1760             }
1761             else if (scellPCqiTrIdx < minPCqiTrIdx)
1762             {
1763                minPCqiTrIdx = scellPCqiTrIdx;
1764                nPCqiServCellIdx = cellIdx;
1765             }
1766          }
1767
1768          /* If all of the num of configured scells are checked then break */
1769          if (sCellCnt == ueCb->numSCells)
1770          {
1771             break;
1772          }   
1773          sCellCnt++;
1774       }
1775    }
1776
1777    /* Set the next expected Cqi into nPCqiCb */
1778    idx = ((nPCqiServCellIdx)& (CM_LTE_MAX_CELLS -1));
1779    ueCb->nPCqiCb = &ueCb->cellInfo[idx]->cqiCb;
1780
1781    RETVALUE(ROK);
1782 }
1783
1784
1785 /**
1786  * @brief Handling of collision of RI types between serving cells
1787  *
1788  * @details
1789  *
1790  *     Function: rgSCHUtlSCellHndlRiCollsn
1791  *     Purpose : Takes care of collision clauses specified in 36.213 7.2.2 Rel 10 
1792  *               and selects next nearest cqiCb 
1793  *     Invoked by:Cfg module 
1794  *
1795  *  @param[in]  RgSchCellCb  *cellCb
1796  *  @param[in]  RgSchUeCb    *ueCb
1797  *  @return  ROK/RFAILED
1798  *
1799  **/
1800 #ifdef ANSI
1801 PUBLIC S16 rgSCHUtlSCellHndlRiCollsn
1802 (
1803 RgSchUePCqiCb *cqiCb
1804 )
1805 #else
1806 PUBLIC S16 rgSCHUtlSCellHndlRiCollsn(cqiCb)
1807 RgSchUePCqiCb     *cqiCb;
1808 #endif
1809 {
1810    U32 nPRiServCellIdx;
1811    U32 minPRiTrIdx;
1812    U32 scellPRiTrIdx;
1813    U32 pRiTrIdx;
1814    RgSchCellCb       *priCellCb = cqiCb->servCellInfo->ue->cell;
1815    RgSchUeCb         *ueCb = cqiCb->servCellInfo->ue;
1816    U16 crntSfIdx;
1817    U32 cellIdx;
1818    U32 sCellCnt = 0;
1819    CmLteTimingInfo timingInfo;
1820    TRC3(rgSCHUtlSCellHndlRiCollsn);
1821
1822 #ifdef xLTE_TDD
1823    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA);
1824 #else
1825    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo,
1826          TFU_RECPREQ_DLDELTA);
1827 #endif
1828
1829    RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx);
1830
1831    pRiTrIdx = cqiCb->nRiTrIdx + cqiCb->riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1832
1833    /* Handle wrap around case */
1834    if (pRiTrIdx < crntSfIdx)
1835    {
1836       pRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1837    }
1838
1839    cqiCb->isRiIgnoByCollsn = FALSE;
1840    nPRiServCellIdx = cqiCb->servCellInfo->sCellIdx;
1841    minPRiTrIdx = pRiTrIdx;
1842
1843    for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++)
1844    {
1845       /* If a serving cell is configured */
1846       if(ueCb->cellInfo[cellIdx] != NULLP)
1847       {
1848          /* If the serving cell is in ACTIVE state and 
1849             If it is not the same serving cell as cqiCb for which 
1850             collision is being checked */
1851          if ((ueCb->cellInfo[cellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)&&
1852                (cellIdx != cqiCb->servCellInfo->sCellIdx))
1853          {
1854             scellPRiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nRiTrIdx + 
1855                ueCb->cellInfo[cellIdx]->cqiCb.riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1856
1857             /* Handle wrap around case */
1858             if (scellPRiTrIdx < crntSfIdx)
1859             {
1860                scellPRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1861             }
1862             
1863             /* If cqiCb->isRiIgnoByCollsn is TRUE then a higher prio cqiCb
1864                is already found so need to compare */
1865             if ((FALSE == ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn) &&
1866                   (FALSE == cqiCb->isRiIgnoByCollsn) && 
1867                   (scellPRiTrIdx == pRiTrIdx))
1868             {
1869                /* Handle Collision */
1870                /* set isRiIgnoByCollsn to TRUE for low prio CQI Rep type */
1871                if (cqiCb->servCellInfo->sCellIdx < (ueCb->cellInfo[cellIdx]->sCellIdx))
1872                {
1873                   ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn = TRUE;
1874                }
1875                else
1876                {
1877                   cqiCb->isRiIgnoByCollsn = TRUE;
1878                }
1879             }
1880             else if (scellPRiTrIdx < minPRiTrIdx)
1881             {
1882                minPRiTrIdx = scellPRiTrIdx;
1883                nPRiServCellIdx = cellIdx;
1884             }
1885          }
1886
1887          /* If all of the num of configured scells are checked then break */
1888          if (sCellCnt == ueCb->numSCells)
1889          {
1890             break;
1891          }   
1892          sCellCnt++;
1893       }
1894    }
1895
1896    /* Set the next expected Cqi into nPCqiCb */
1897    ueCb->nPRiCb = &ueCb->cellInfo[nPRiServCellIdx]->cqiCb;
1898
1899    RETVALUE(ROK);
1900 }
1901 #endif/*TFU_UPGRADE*/
1902
1903 /**
1904  * @brief Checking whethter the scell is active or not
1905  *
1906  * @details
1907  *
1908  *     Function: rgSCHSCellIsActive
1909  *     Purpose: Check the Scell is in active state or not 
1910  *              
1911  *
1912  *     Invoked by: SpecificScheduler
1913  *
1914  *  @param[in]  RgSchCellCb*     cell
1915  *  @param[in]  RgSchUeCb*       ue
1916  *  @return  Void
1917  *
1918  **/
1919 #ifdef ANSI
1920 PUBLIC S16 rgSCHSCellIsActive
1921 (
1922 RgSchCellCb                *cell,
1923 RgSchUeCb                  *ue
1924 )
1925 #else
1926 PUBLIC S16 rgSCHSCellIsActive(cell, ue)
1927 RgSchCellCb                *cell;
1928 RgSchUeCb                  *ue;
1929 #endif
1930 {
1931    S16 retVal = RFAILED;
1932    TRC3(rgSCHSCellIsActive);
1933
1934    for(U8 idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1935    {
1936       if((ue->cellInfo[idx] != NULLP) &&
1937          (ue->cellInfo[idx]->cell->cellId == cell->cellId)&&
1938          (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE)) 
1939       {
1940          retVal = ROK;
1941          break;
1942       }
1943    }
1944    RETVALUE(retVal);    
1945 }
1946
1947 /**
1948  * @brief Function to check for Acell Activation Trigered.
1949  *
1950  * @details
1951  *
1952  *     Function : rgSCHIsActvReqd
1953  *       This function will check for Secondary cell activation criteria
1954  *       If met this will return TRUE else FALSE
1955  *     
1956  *  @param[in]     RgSchCellCb    *cell
1957  *  @param[in]     RgSchUeCb      *ue
1958  *  @return  BOOL
1959  *      -#  TRUE
1960  **/
1961 #ifdef ANSI
1962 PUBLIC Bool rgSCHIsActvReqd 
1963 (
1964 RgSchCellCb    *cell,
1965 RgSchUeCb      *ue
1966 )
1967 #else
1968 PUBLIC Bool rgSCHIsActvReqd(cell, ue)
1969 RgSchCellCb    *cell;
1970 RgSchUeCb      *ue
1971 #endif
1972 {
1973    TRC2(rgSCHIsActvReqd)
1974    /* Check if remBoCnt in this UE is greater than ZERO for sufficient number of
1975     * Scheduling TTIs. If yes then We should activate a secondary cell to handle
1976     * outstanding BO */
1977    if(ue->remBoCnt == RG_SCH_ACTIVATION_COUNT)
1978    {
1979       RETVALUE(TRUE);
1980    }
1981    RETVALUE(FALSE);
1982 }
1983 #endif/*LTE_ADV*/
1984
1985
1986
1987 /**********************************************************************
1988
1989          End of file
1990 **********************************************************************/