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