2990c0f3e0e4aa01551b8a42ed42ffcc9b0a1d40
[o-du/l2.git] / 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       DU_LOG("\nINFO  -->  SCH : SCell is already added in the Act List: ueId(%u)\n", ue->ueId);
224    }
225    
226    return;
227 }
228
229 \f
230 /**
231  * @brief Removes an UE from Cell's SCell Activation list
232  *
233  * @details
234  *
235  *     Function: rgSCHSCellRmvFrmActLst
236  *     Purpose:  Removes an UE from Cell's SCEll Act list
237  *
238  *     Invoked by: Specific Scheduler
239  *
240  *  @param[in]  RgSchCellCb*     cell
241  *  @param[in]  RgSchUeCb*       ue
242  *  @return  Void
243  *
244  **/
245 Void rgSCHSCellRmvFrmActLst(RgSchCellCb *cell,RgSchUeCb *ue)
246 {
247    RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
248    if (NULLP != ue->sCellActLnk.node)
249    {
250       cmLListDelFrm(&cellCmnDl->secCellActCeLst, &ue->sCellActLnk);
251    }
252    ue->sCellActLnk.node = (PTR)NULLP;
253
254    return;
255 }
256 \f
257 /**
258  * @brief Handling of SCell Activation
259  *
260  * @details
261  *
262  *     Function: rgSCHSCellActivation
263  *     Purpose : Perform Activation of secondary cell
264  *             : Move the state to ACTIVE
265  *             : Start the procedure for PCQI/SRS for this scell
266  *
267  *     Invoked by:Cfg/Commn Scheduler 
268  *
269  *  @param[in]  RgSchUeCellInfo *sCellInfo
270  *
271  *  @return  ROK/RFAILED
272  *
273  **/
274 Void rgSCHSCellActivation(RgSchUeCellInfo  *sCellInfo)
275 {
276    RgSchCellCb  *sCell = sCellInfo->cell;
277    RgSchUeCb    *ueCb = sCellInfo->ue;
278    RgSchCmnCell *cellSch;
279 #ifdef TFU_UPGRADE
280 #ifdef DEBUGP
281    Inst   inst = ueCb->cell->instIdx;
282 #endif
283    uint16_t    tempIdx; 
284    RgrUePrdDlCqiCfg  *cqiCfg;
285    uint8_t     j;  /*Bandwidth Parts*/
286    uint16_t    riTrInsTime; 
287    uint16_t    periodicity; 
288    uint16_t    cqiTrInstTime; 
289    RgSchUePCqiCb *cqiCb = NULLP;
290    CmLteTimingInfo timingInfo;
291    uint16_t    crntTime;           
292 #endif
293
294
295    sCellInfo->sCellState = RG_SCH_SCELL_ACTIVE;
296 #ifdef TENB_STATS
297    ueCb->tenbStats->stats.persistent.numActivation++;
298 #endif
299
300 #ifdef CA_DBG 
301     DU_LOG("\nDEBUG  -->  SCH : ueId is SCELL_ACTIVE\n ueCb->ueId = %d sCell->sCellIdx =%d,\
302     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       DU_LOG("\nINFO  -->  SCH : 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       DU_LOG("\nINFO  -->  SCH :  rgSCHCfgPCqiUeCfg():"
350                "  CrntTime=%d  Next CqiTrInstTime=%d  Index Stored at=%d  ",
351                crntTime, cqiTrInstTime, cqiCb->nCqiTrIdx);
352
353       if(cqiCfg->cqiSetup.riEna)
354       {
355          cqiCb->perRiVal = 1;
356          cqiCb->invalidateCqi = FALSE;
357
358          if(RGR_UE_PCQI_WB_REP == cqiCfg->cqiSetup.cqiRepType)
359          {
360             /* 
361                1. wideband RI reporting is configured 
362                (Mode 1-0 or 1-1)
363                (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )Mod(NCqiperiod
364              *MriPeriod)=0  
365              */ 
366             periodicity = cqiCb->cqiPeri * cqiCb->riPeri; 
367          }
368          else
369          {
370             /*
371              *  Where Widesband and Subband RI reporting is configured
372              *   (Mode 2-0 or 2-1 )
373              *   (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )
374              *   Mod(H. NCqiperiod *MriPeriod )=0 
375              *   where H= J * K +1;  J=Number of bandwidth parts(BW/subsize). 
376              *   K is RGR interf input 
377              */
378
379             RG_SCH_GET_CQI_J_VAL(sCell->bwCfg.dlTotalBw, j);
380             cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1;  
381             periodicity = cqiCb->h * cqiCb->cqiPeri * 
382                cqiCb->riPeri; 
383
384          }
385
386          /* In case of SFN wraparound, the SB CQI reporting cycle breaks
387           * and RI->WB CQI->SBCQI.. should resume. RI is repositioned 
388           * accordingly. WBCQI handling is naturally accomplished */
389          if (periodicity >= RGSCH_MAX_SUBFRM_5G)
390          {
391             periodicity = cqiCb->cqiOffset - cqiCb->riOffset + 
392                RGSCH_MAX_SUBFRM_5G - (crntTime);
393             tempIdx = crntTime + periodicity;
394          }
395          else
396          {
397             riTrInsTime = ((periodicity +crntTime )- \
398                   cqiCb->cqiOffset + cqiCb->riOffset)\
399                           % periodicity;
400             tempIdx = (crntTime + (periodicity -riTrInsTime));
401          }
402          if (tempIdx <= (crntTime + TFU_RECPREQ_DLDELTA))
403          {
404             tempIdx = tempIdx + periodicity; 
405          }
406          cqiCb->nRiTrIdx = tempIdx 
407             % RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
408          if(periodicity >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE)
409          {  
410             cqiCb->riDist = rgSCHUtlFindDist((uint16_t)(crntTime + TFU_RECPREQ_DLDELTA),
411                   (uint16_t) tempIdx);
412          }
413          else
414          {
415             cqiCb->riDist =0; 
416          }
417
418
419          /* Start receiving RI for this SCell for this UE */
420          cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst,
421                &cqiCb->riLstEnt);  
422          RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_ADD,
423             &ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst);
424
425          rgSCHUtlSCellHndlRiCollsn(cqiCb);
426          /*werror*/
427 #ifndef BIT_64
428          DU_LOG("\nINFO  -->  SCH : SCel RI cfg:"
429                   "idx %u period %u Offset %u posInQ(%u) riDist(%u)lst count"
430                   "%lu\n", cqiCfg->cqiSetup.riCfgIdx, cqiCb->riPeri,
431                   cqiCb->riOffset, cqiCb->nRiTrIdx, cqiCb->riDist, 
432                   ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst.count);
433 #else
434          DU_LOG("\nINFO  -->  SCH : SCel RI cfg:"
435                   "idx %u period %u Offset %u posInQ(%u) riDist(%u)lst count"
436                   "%u\n", cqiCfg->cqiSetup.riCfgIdx, cqiCb->riPeri,
437                   cqiCb->riOffset, cqiCb->nRiTrIdx, cqiCb->riDist, 
438                   ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst.count);
439
440
441 #endif
442
443          DU_LOG("\nINFO  -->  SCH : \n rgSCHSCellActivation(): CrntTime=%d Next RiTrInstTime=%d"
444                   "Index Stored at=%d riDis=%d ",
445                   crntTime, riTrInsTime, cqiCb->nRiTrIdx, cqiCb->riDist);
446       }
447    }
448 #endif
449
450    cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell);
451    cellSch->apisDl->rgSCHDlSCellActv(sCellInfo->cell, sCellInfo->ue);
452
453    return;
454 }
455
456 #ifdef TFU_UPGRADE
457 \f
458 /**
459  * @brief Remove CQI from Scell Lst
460  *
461  * @details
462  *
463  *     Function: rgSCHCellClearScellLstOfCQI
464  *     Purpose : Remove CQI from Scell Lst
465  *              
466  *
467  *     Invoked by: Timer
468  *
469  *  @param[in]  RgSchUeCellInfo *sCellInfo
470  *  @return  Void
471  *
472  **/
473 static Void rgSCHCellClearScellLstOfCQI(RgSchUeCellInfo *sCellInfo)
474 {
475
476    RgSchUePCqiCb *cqiRiCb = NULLP;
477    RgSchUeCb    *ueCb;
478    ueCb = sCellInfo->ue;
479    /* Clear CQI/RI entry for this SCELL */
480    cqiRiCb = &sCellInfo->cqiCb;
481    /* Delete Periodic CQI/PMI  Transmission Instance  */
482    if (cqiRiCb->nCqiTrIdx != RG_SCH_INVALID_IDX)
483    {
484       cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nCqiTrIdx].cqiLst, 
485             &cqiRiCb->cqiLstEnt); 
486       cqiRiCb->nCqiTrIdx = RG_SCH_INVALID_IDX;
487
488       if (ueCb->nPCqiCb == cqiRiCb)
489       {
490          rgSCHUtlSCellHndlCqiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb);
491       }
492       /* Delete Periodic  RI  Transmission Instance  */
493
494       if (cqiRiCb->nRiTrIdx != RG_SCH_INVALID_IDX)
495       {
496          cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst, 
497                &cqiRiCb->riLstEnt); 
498          RG_SCH_RECORD(&cqiRiCb->histElem,RGSCH_ACTION_DEL,
499             &ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst);
500          cqiRiCb->nRiTrIdx = RG_SCH_INVALID_IDX;
501          if (ueCb->nPRiCb == cqiRiCb)
502          {
503             rgSCHUtlSCellHndlRiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb);
504          }
505       }
506    }
507
508    return;
509 }
510 #endif/*TFU_UPGRADE*/
511 \f
512 /**
513  * @brief Handling of SCell DeActivation
514  *
515  * @details
516  *
517  *     Function: rgSCHSCellDeActivation
518  *     Purpose : Perform Deactivation of secondary cell
519  *             : Move the state to IN_ACTIVE
520  *             : Flush the harqEntity
521  *             : Trigger harqEntity flushing to MAC
522  *             : Remove  PCQI/SRS for this scell
523  *             : Stop Deactivation timer if running
524  *
525  *     Invoked by:Cfg/Commn Scheduler 
526  *
527  *  @param[in]  RgSchUeCellInfo *sCellInfo
528  *
529  *  @return  ROK/RFAILED
530  *
531  **/
532 static S16 rgSCHSCellDeActivation(RgSchUeCellInfo *sCellInfo)
533 {
534    return ROK;
535    RgSchCmnCell *cellSch;
536    Inst inst = sCellInfo->cell->instIdx;
537
538    /* Stop the timer if running */
539
540    if(sCellInfo->deactTmr.tmrEvnt != TMR_NONE)
541    {
542       rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_DEACT, sCellInfo);
543    }
544
545    if (sCellInfo->actDelayTmr.tmrEvnt != TMR_NONE)
546    {
547       rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_ACT_DELAY, sCellInfo);
548    }
549
550    cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell);
551    cellSch->apisDl->rgSCHDlUeReset(sCellInfo->cell, sCellInfo->ue);
552
553    if(sCellInfo->ue->isDrxEnabled)
554    {   
555       rgSCHDrxUeHqReset(sCellInfo->ue->cell, sCellInfo->ue, 
556                         sCellInfo->hqEnt, sCellInfo->sCellIdx);
557    }
558
559    /* Flush the harqEntity at scheduler */
560    if(sCellInfo->hqEnt != NULLP) 
561    {
562       rgSCHDhmHqEntReset(sCellInfo->hqEnt);
563    }
564    /* Trigger harq flush req to MAC */
565
566
567    rgSCHSCellTrgMacHqEReset(inst,sCellInfo->sCellId,sCellInfo->ue->ueId);
568    
569    sCellInfo->sCellState = RG_SCH_SCELL_READY;
570 #ifdef TFU_UPGRADE
571    rgSCHCellClearScellLstOfCQI(sCellInfo);
572 #endif
573
574 #ifdef TENB_STATS
575    sCellInfo->ue->tenbStats->stats.persistent.numDeactivation++;
576 #endif
577
578    cellSch->apisDl->rgSCHDlSCellDeactv(sCellInfo->cell, sCellInfo->ue);
579
580 #ifdef CA_DBG 
581    DU_LOG("\nDEBUG  -->  SCH : SCELL DEATIVATED  sCellInfo->ue->ueId =%d, sCellInfo->sCellId =%d\n",\
582    sCellInfo->ue->ueId, sCellInfo->sCellId);
583    //MSPD_DBG("SCELL DEATIVATED  sCellInfo->ue->ueId =%d, sCellInfo->sCellId =%d\n", sCellInfo->ue->ueId, sCellInfo->sCellId);
584 #endif
585    return ROK;
586 }
587
588 \f
589 /**
590  * @brief Triggering hqEntity reset to mac
591  *
592  * @details
593  *
594  *     Function: rgSCHSCellTrgMacHqEReset
595  *     Purpose: Frame the interface for mac to reset
596  *              the mac
597  *              Derive the macInstance corresponding
598  *              to the secondary cell going to be deactivated.
599  *              Triiger the msg to that macInstance
600  *
601  *     Invoked by: CommonScheduler
602  *
603  *  @param[in]  uint16_t        sCellId
604  *  @param[in]  uint16_t        rnti
605  *  @return  Void
606  *
607  **/
608 static S16 rgSCHSCellTrgMacHqEReset(Inst inst,uint16_t secCellId,uint16_  rnti)
609 {
610    Pst               pst;
611    RgSchCellCb      *secCellCb = NULLP;
612    RgInfResetHqEnt   hqEntRstInfo;
613
614    if((secCellCb = (RgSchCellCb *)rgSchUtlGetCellCb(inst, secCellId)) == NULLP)
615    {
616       DU_LOG("\nERROR  -->  SCH : SCell doesnt exists");
617       return RFAILED;
618    }
619
620    hqEntRstInfo.cellId = secCellId;
621    hqEntRstInfo.crnti  = rnti;
622
623    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], secCellCb->macInst);
624
625    RgSchMacRstHqEnt(&pst, &hqEntRstInfo);
626
627    return ROK;
628 }
629 /*removed endif*/
630
631
632 \f
633 /**
634  * @brief Handling of harq feeback for SCell act CE txion
635  *
636  * @details
637  *
638  *     Function: rgSCHSCellHndlFdbkInd
639  *     Purpose:  Handling the harq feedback for SCell ACT ce txion
640  *               ACK:: Set the state as active for the Scells for which
641  *                     CE was sent
642  *               HQ FAILURE/DTX/NACK:: Perform retxion. Add to Act CE list
643  *                                   Set the state to TOBE_SCHEDULED
644  *               
645  *
646  *     Invoked by: CommonScheduler
647  *
648  *  @param[in]  RgSchCellCb*     cell
649  *  @param[in]  RgSchUeCb*       ue
650  *  @return  Void
651  *
652  **/
653 Void rgSCHSCellHndlFdbkInd(RgSchDlHqProcCb *hqP,uint8_t tbIdx,uint8_t  fdbk,Bool maxHqRetxReached)
654 {
655
656    RgSchUeCb      *ueCb;
657    RgSchCellCb    *cell;
658    RgSchUeCellInfo *sCellInfo;
659
660
661    ueCb  = hqP->hqE->ue;
662    cell  = ueCb->cell;
663    switch(fdbk)
664    {
665       case TFU_HQFDB_ACK:
666          {
667             hqP->tbInfo[tbIdx].schdSCellActCe.pres =  FALSE;
668
669             for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
670             {
671                if(ueCb->cellInfo[idx] != NULLP) 
672                {
673                   if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG)
674                   {
675 #ifdef CA_DBG
676                      DU_LOG("\nINFO  -->  SCH : starting delay timer...\n");
677 #endif                     
678                      rgSCHTmrStartTmr (cell,ueCb->cellInfo[idx] ,RG_SCH_TMR_SCELL_ACT_DELAY,
679                            RG_SCH_CMN_SCELL_ACT_DELAY_TMR);
680                   }
681                   else
682                   {
683                      if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG)
684                      {
685                         sCellInfo = ueCb->cellInfo[idx];
686                         rgSCHSCellDeActivation(sCellInfo);
687                      }
688                   }
689                }
690             }
691          }
692          break;
693       case TFU_HQFDB_NACK:
694       case TFU_HQFDB_DTX:
695          {
696             if(TRUE == maxHqRetxReached)
697             {
698                hqP->tbInfo[tbIdx].schdSCellActCe.pres =  FALSE;
699                for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
700                {
701                   if(ueCb->cellInfo[idx] != NULLP) 
702                   {
703                      if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG)
704                      {
705                         ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED;
706                      }
707                      else
708                      {
709                         if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG)
710                         {
711                            ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED;
712                         }
713                      }
714                   }
715                   /* Add to actDeactCe lst */
716                   rgSCHSCellAddToActDeactLst(cell,ueCb);
717                }
718             }
719          }
720          break;
721       default:
722          break;
723    }
724    return;
725 }
726
727 #ifdef LTE_ADV
728 /**
729  * @brief Handling of SCell Deactivation Tmr Expiry
730  *
731  * @details
732  *
733  *     Function: rgSCHSCellDeactTmrExpry
734  *     Purpose : Deactivating the SCell. a
735  *               Clear all the Harq Procs associated with this
736  *               scell.
737  *               Trigger Harq Reset to the respective MAC
738  *               Set the state of the cell to Inactive  
739  *              
740  *
741  *     Invoked by: Timer
742  *
743  *  @param[in]  RgSchUeCellInfo *sCellInfo
744  *  @return  Void
745  *
746  **/
747 Void rgSCHSCellDeactTmrExpry(RgSchUeCellInfo *sCellInfo)
748 {
749
750    if (sCellInfo->ue->isScellExplicitDeAct == TRUE)
751    {
752       /* Deactivation Timer is not configured (infinity), thus send deactivation CE explicitly */ 
753       /* No doing Deactivaiton of LAA Cell */
754       if (FALSE == rgSCHLaaSCellEnabled(sCellInfo->cell))
755       {
756          rgSCHSCellTrigActDeact(sCellInfo->ue->cell, sCellInfo->ue, sCellInfo->sCellIdx, RGR_SCELL_DEACT);
757       }
758       else
759       {
760          DU_LOG("\nERROR  -->  SCH : !!!!!! Avoiding DEACT for UE %d because of LAA Cell !!!!!!!!!!!!! \n",
761          sCellInfo->ue->ueId);
762       }
763
764    }
765    else
766    {
767       /* Deactivation Timer is configured, thus assume that UE has deactivated */ 
768       rgSCHSCellDeActivation(sCellInfo);
769    }
770    return;
771 }
772 #endif
773 \f
774 /**
775  * @brief This function handles the action of the SCell
776  *
777  * @details
778  *
779  *     Function: rgSCHSCellTrigActDeact
780  *     Purpose :  
781  *        1) Prepares SCELL ready for activation OR
782  *        2) Initiates activation of SCELL OR
783  *        3) Initiate deactivation of SCELL OR
784  *
785  *     Invoked by:Cfg/Commn Scheduler 
786  *
787  *  @param[in]  RgSchCellCb *cellCb
788  *  @param[in]  RgSchUeCb   *ueCb
789  *  @param[in]  uint8_t           sCellIdx
790  *  @param[in]  uint8_t           action
791  *
792  *  @return  ROK/RFAILED
793  *
794  **/
795 S16 rgSCHSCellTrigActDeact(RgSchCellCb *cell,RgSchUeCb *ueCb,uint8_t sCellIdx,uint8_t action)
796 {
797    Inst inst = cell->instIdx;
798    S16 ret   = ROK;
799
800    if((sCellIdx < 1) ||
801       (sCellIdx > RGR_MAX_SCELL_PER_UE))
802    {
803       DU_LOG("\nERROR  -->  SCH : Invalid Serv Cell Idx %d\n", sCellIdx);
804       return RFAILED;
805    }
806
807    if(ueCb->cellInfo[sCellIdx] == NULLP)
808    {
809       DU_LOG("\nERROR  -->  SCH : Serv Cell not added to this Ue Scell Idx %d ueId %d\n", \
810               sCellIdx,ueCb->ueId);
811       return RFAILED;
812    }
813
814    switch (action)
815    {
816       case RGR_SCELL_READY:
817       {
818          if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_INACTIVE)
819          {
820             DU_LOG("\nERROR  -->  SCH : Invalid state %u for preparing SCell Idx %u for UE %u\n", \
821                      ueCb->cellInfo[sCellIdx]->sCellState, sCellIdx, ueCb->ueId);
822             ret = RFAILED;
823          }
824          else
825          {
826             ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_READY;
827             //TODO_SID Activating the cell directly. Ignoring the ActCe procedure.
828             rgSCHSCellActivation(ueCb->cellInfo[sCellIdx]);
829             /* Setting allocCmnUlPdcch flag to FALSE, So that PDCCH allocation will be done 
830                from UE Searchspace */
831             ueCb->allocCmnUlPdcch = FALSE;
832             DU_LOG("\nINFO  -->  SCH : ***** SCellIdx=%d state Changed to %d State \n",sCellIdx,\
833             ueCb->cellInfo[sCellIdx]->sCellState);
834             DU_LOG("\nINFO  -->  SCH : ***** SCellInfo Addr=%p state Changed to RG_SCH_SCELL_READY\n",\
835             (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             DU_LOG("\nERROR  -->  SCH : 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             DU_LOG("\nERROR  -->  SCH : 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          DU_LOG("\nERROR  -->  SCH : 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       DU_LOG("\nERROR  -->  SCH : 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       DU_LOG("\nERROR  -->  SCH : 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    DU_LOG("\nINFO  -->  SCH : rgSCHSCellPCqiCfg cellId =%d, ueId = %d, CfgType =%d\n",
1120             secCellCb->cellId,  ueCb->ueId, cqiCfg->type);
1121    
1122    if((sCellIdx < 1) ||
1123       (sCellIdx > RGR_MAX_SCELL_PER_UE))
1124    {
1125       DU_LOG("\nERROR  -->  SCH : Invalid Serv Cell Idx %d\n",
1126                sCellIdx);
1127       return RFAILED;
1128    }
1129
1130    sCellInfo = ueCb->cellInfo[sCellIdx];
1131
1132    cqiCb = &ueCb->cellInfo[sCellIdx]->cqiCb;
1133    cqiCb->servCellInfo = sCellInfo;
1134
1135    /* Periodic CQI is setup  */
1136    if (cqiCfg->type == RGR_SCH_PCQI_SETUP)
1137    {   
1138       /*  1. Copy the Received CQI Cfg parameters to ueCb  */
1139       memcpy(&cqiCb->cqiCfg, cqiCfg, 
1140             sizeof(RgrUePrdDlCqiCfg));
1141
1142       /*  2. Compute Periodic CQI Periodicity and subframe offset   */
1143 #ifndef LTE_TDD           
1144       rgSCHUtlGetCfgPerOff(RG_SCH_FDD_PCQI_TBL, cqiCfg->cqiSetup.cqiPCfgIdx,
1145             &cqiCb->cqiPeri, &cqiCb->cqiOffset);      
1146 #else
1147       rgSCHUtlGetCfgPerOff( RG_SCH_TDD_PCQI_TBL, 
1148             cqiCfg->cqiSetup.cqiPCfgIdx,
1149             &cqiCb->cqiPeri, &cqiCb->cqiOffset);    
1150 #endif
1151
1152
1153       DU_LOG("\nDEBUG  -->  SCH :  rgSCHSCellPCqiCfg(): CQI Peri=%d, CQI Offset=%d", 
1154                cqiCb->cqiPeri,cqiCb->cqiOffset);
1155
1156       if(RGR_UE_PCQI_SB_REP == cqiCfg->cqiSetup.cqiRepType)
1157       {
1158          uint8_t     k;  /*SubBand Size (RB) */
1159          RG_SCH_GET_CQI_J_VAL(secCellCb->bwCfg.dlTotalBw, j);
1160          RG_SCH_GET_CQI_K_VAL(secCellCb->bwCfg.dlTotalBw, k);
1161          cqiCb->J = j; /*Number of Bandwidth Parts*/
1162          /*h: reporting instances required for a complete CQI/PMI report */
1163          /*j:Number of bandwidth parts; k: Subband Size*/
1164          cqiCb->h = (cqiCb->cqiCfg.cqiSetup.k *j )+1; 
1165          /* ccpu00140905- L-size is coming as 3 for 100Rbs where it should be 2*/
1166          temp = RGSCH_CEIL(secCellCb->bwCfg.dlTotalBw, (j*k));
1167          cqiCb->label = (temp & (temp-1)) ?
1168             (1+ rgSCHUtlLog32bitNbase2(temp)) : rgSCHUtlLog32bitNbase2(temp);
1169       }
1170       else
1171       {
1172          /* Wideband Cqi Rep Type */
1173          cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_1;
1174       }
1175       cqiCb->cqiLstEnt.node=(PTR)cqiCb;
1176       cqiCb->isCqiIgnoByCollsn = FALSE;
1177
1178
1179       /* 4. Rank Indicator Cfg handler */
1180       /* 1. Rank Indicator is enabled  */
1181       if(cqiCfg->cqiSetup.riEna)
1182       {
1183          rgSCHUtlGetCfgPerOff(RG_SCH_RI_TBL, 
1184                cqiCfg->cqiSetup.riCfgIdx,
1185                &cqiCb->riPeri, &cqiCb->riOffset);
1186
1187          DU_LOG("\nDEBUG  -->  SCH :  rgSCHSCellPCqiCfg(): RI Peri=%d, RI Offset=%d", 
1188                   cqiCb->riPeri,cqiCb->riOffset);
1189
1190          if(ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_3 
1191                || ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_4)
1192          {
1193             if (secCellCb->numTxAntPorts ==2)
1194             {
1195                cqiCb->riNumBits = 1;
1196             }
1197             else if(secCellCb->numTxAntPorts ==4)
1198             {
1199                if(ueCat == CM_LTE_UE_CAT_8)
1200                {
1201                   cqiCb->riNumBits = 3;
1202                }
1203                else if((ueCat == CM_LTE_UE_CAT_5) || 
1204                      (ueCat == CM_LTE_UE_CAT_6) || CM_LTE_UE_CAT_7)
1205                {
1206                   cqiCb->riNumBits = 2;
1207                }
1208                else
1209                {
1210                   cqiCb->riNumBits = 1;
1211                }
1212             }
1213          }
1214          cqiCb->riLstEnt.node=(PTR) cqiCb;
1215          cqiCb->isRiIgnoByCollsn = FALSE;
1216
1217       }
1218    }
1219    else
1220    {
1221       sCellInfo->cqiCb.cqiCfg.type =  RGR_SCH_PCQI_REL;
1222    }
1223    /* Setting the indices to invalid during
1224       scell addition. These indices will be set during 
1225       activation */
1226    cqiCb->nRiTrIdx  = RG_SCH_INVALID_IDX;
1227    cqiCb->riDist    = RG_SCH_INVALID_IDX; 
1228    cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX;
1229  
1230    return ROK;
1231 }
1232 #endif
1233
1234 /**
1235  * @brief Handling of Ue Reset from common scheduler
1236  *
1237  * @details
1238  *
1239  *     Function: rgSCHSCellDlUeReset
1240  *     Purpose:  Call scheudler type spcefic UE RESET
1241  *               for all the secondary cells
1242  *
1243  *     Invoked by: CommonScheduler
1244  *
1245  *  @param[in]  RgSchCellCb*     cell
1246  *  @param[in]  RgSchUeCb*       ue
1247  *  @return  Void
1248  *
1249  **/
1250 Void rgSCHSCellDlUeReset(RgSchCellCb *cell,RgSchUeCb *ue)
1251 {
1252    RgSchCmnCell *cellSch;
1253
1254    for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1255    {
1256       if(ue->cellInfo[idx] != NULLP) 
1257       {
1258          cellSch = RG_SCH_CMN_GET_CELL(ue->cellInfo[idx]->cell);
1259          cellSch->apisDl->rgSCHDlUeReset(ue->cellInfo[idx]->cell, ue);
1260          rgSCHSCellDeActivation(ue->cellInfo[idx]);
1261          ue->cellInfo[idx]->sCellState = RG_SCH_SCELL_INACTIVE;
1262       }
1263    }
1264    return;
1265 }
1266
1267
1268 /**
1269  * @brief Handling of LC Cfg from common scheduler
1270  *
1271  * @details
1272  *
1273  *     Function: rgSCHSCellDlLcCfg
1274  *     Purpose:  Call scheudler type spcefic LC config
1275  *               for all the secondary cells
1276  *
1277  *     Invoked by: CommonScheduler
1278  *
1279  *  @param[in]  RgSchCellCb*     cell
1280  *  @param[in]  RgSchUeCb*       ue
1281  *  @return  Void
1282  *
1283  **/
1284 Void rgSCHSCellDlLcCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1285 {
1286    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1287    for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1288    {
1289       if(ue->cellInfo[idx] != NULLP) 
1290       {
1291          cellSch->apisDl->rgSCHRgrDlLcCfg(ue->cellInfo[idx]->cell, ue, svc,NULLP,NULLP);
1292       }
1293    }
1294    return;
1295 }
1296
1297 /**
1298  * @brief Handling of LC Delete from common scheduler
1299  *
1300  * @details
1301  *
1302  *     Function: rgSCHSCellDlLcDel
1303  *     Purpose:  Call scheudler type spcefic bo update handler
1304  *               for all the secondary cells
1305  *
1306  *     Invoked by: CommonScheduler
1307  *
1308  *  @param[in]  RgSchCellCb*     cell
1309  *  @param[in]  RgSchUeCb*       ue
1310  *  @return  Void
1311  *
1312  **/
1313 Void rgSCHSCellDlLcDel(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchDlLcCb  *svc)
1314 {
1315    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1316    for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1317    {
1318       if(ue->cellInfo[idx] != NULLP) 
1319       {
1320          cellSch->apisDl->rgSCHFreeDlLc(ue->cellInfo[idx]->cell, ue, svc);
1321       }
1322    }
1323    return;
1324 }
1325
1326 /**
1327  * @brief Handling of Bo update from common scheduler
1328  *
1329  * @details
1330  *
1331  *     Function: rgSCHSCellDlDedBoUpd
1332  *     Purpose:  Call scheudler type spcefic bo update handler
1333  *               for all the secondary cells
1334  *
1335  *     Invoked by: CommonScheduler
1336  *
1337  *  @param[in]  RgSchCellCb*     cell
1338  *  @param[in]  RgSchUeCb*       ue
1339  *  @return  Void
1340  *
1341  **/
1342 Void rgSCHSCellDlDedBoUpd(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1343 {
1344    RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1345
1346    /* If this is not invoked by PCell, then
1347       invoke the call to PCell handler 
1348       This happens during finalization if LC Bo becomes zero*/
1349    if (ue->cell != cell)
1350    {
1351       cellSch->apisDl->rgSCHDlDedBoUpd(ue->cell, ue, svc);
1352    }
1353    for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1354    {
1355       if((ue->cellInfo[idx] != NULLP) &&
1356             (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE) &&
1357            (ue->cellInfo[idx]->cell != cell))
1358       {
1359          cellSch->apisDl->rgSCHDlDedBoUpd(ue->cellInfo[idx]->cell, ue, svc);
1360       }
1361    }
1362    return;
1363 }
1364 #ifdef TFU_UPGRADE
1365 /**
1366  * @brief Compare two CQI CB configs are return the result
1367  *
1368  * @details
1369  *
1370  *     Function: rgSCHUtlSCellCmpCqiCfg
1371  *     Purpose : Compare priority levels of cqiCb1 and cqiCb2
1372  *               and set the isCqiIgnoByCollsn to TRUE for the 
1373  *               cqiCb which has lower priority 
1374  *     Invoked by:scell module 
1375  *
1376  *  @param[in] RgSchUePCqiCb *cqiCb1
1377  *  @param[in] RgSchUePCqiCb *cqiCb2
1378  *  @return uint8_t cqiCb cell idx which has the higher priority
1379  *
1380  **/
1381 static uint8_t  rgSCHUtlSCellCmpCqiCfg(RgSchUePCqiCb *cqiCb1,RgSchUePCqiCb *cqiCb2)
1382 {
1383    RgSchUePCqiCb     *retCqiCb;
1384    /* Collision rules are defined in TS 36.213,7.2.2 */
1385    /* RI, WB first PMI > WB CQI >  SB CQI */
1386    /* As of now only taking care of RI > WB CQI > SB CQI */
1387
1388    if (cqiCb1->prioLvl > cqiCb2->prioLvl)
1389    {
1390       cqiCb2->isCqiIgnoByCollsn = TRUE;
1391       cqiCb1->isCqiIgnoByCollsn = FALSE;
1392       retCqiCb = cqiCb1;
1393    }
1394    else if (cqiCb2->prioLvl > cqiCb1->prioLvl)
1395    {
1396       cqiCb1->isCqiIgnoByCollsn = TRUE;
1397       cqiCb2->isCqiIgnoByCollsn = FALSE;
1398       retCqiCb = cqiCb2;
1399    }
1400    else
1401    {
1402       if (cqiCb1->servCellInfo->sCellIdx > cqiCb2->servCellInfo->sCellIdx)
1403       {
1404          cqiCb1->isCqiIgnoByCollsn = TRUE;
1405          cqiCb2->isCqiIgnoByCollsn = FALSE;
1406          retCqiCb = cqiCb2;
1407       }
1408       else
1409       {
1410          cqiCb2->isCqiIgnoByCollsn = TRUE;
1411          cqiCb1->isCqiIgnoByCollsn = FALSE;
1412          retCqiCb = cqiCb1;
1413       }
1414    }
1415
1416    return (retCqiCb->servCellInfo->sCellIdx);
1417 }
1418
1419 /**
1420  * @brief Handling of collision of CQI types between serving cells
1421  *
1422  * @details
1423  *
1424  *     Function: rgSCHUtlSCellHndlCqiCollsn
1425  *     Purpose : Takes care of collision clauses specified in 36.213 7.2.2 Rel 10 
1426  *               and selects next nearest cqiCb 
1427  *     Invoked by:Cfg module 
1428  *
1429  *  @param[in]  RgSchCellCb  *cellCb
1430  *  @param[in]  RgSchUeCb    *ueCb
1431  *  @return  ROK/RFAILED
1432  *
1433  **/
1434 S16 rgSCHUtlSCellHndlCqiCollsn(RgSchUePCqiCb *cqiCb)
1435 {
1436    uint32_t nPCqiServCellIdx;
1437    uint32_t minPCqiTrIdx;
1438    uint32_t scellPCqiTrIdx;
1439    uint32_t pCqiTrIdx;
1440    RgSchCellCb       *priCellCb = cqiCb->servCellInfo->ue->cell;
1441    RgSchUeCb         *ueCb = cqiCb->servCellInfo->ue;
1442    uint16_t crntSfIdx;
1443    uint32_t cellIdx;
1444    uint32_t sCellCnt = 0;
1445    CmLteTimingInfo timingInfo;
1446    uint8_t idx = 0;
1447
1448 #ifdef xLTE_TDD
1449    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA);
1450 #else
1451    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo,
1452          TFU_RECPREQ_DLDELTA);
1453 #endif
1454
1455    RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx);
1456
1457    cqiCb->isCqiIgnoByCollsn = FALSE;
1458
1459    pCqiTrIdx = cqiCb->nCqiTrIdx;
1460    nPCqiServCellIdx = cqiCb->servCellInfo->sCellIdx;
1461    /* Handle wrap around case */
1462    if (pCqiTrIdx < crntSfIdx)
1463    {
1464       pCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1465    }
1466    minPCqiTrIdx = pCqiTrIdx;
1467
1468    for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++)
1469    {
1470       /* If a serving cell is configured */
1471       if(ueCb->cellInfo[cellIdx] != NULLP)
1472       {
1473          /* If the serving cell is in ACTIVE state and 
1474             If it is not the same serving cell as cqiCb for which 
1475             collision is being checked */
1476          if ((ueCb->cellInfo[cellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)&&
1477                (cellIdx != cqiCb->servCellInfo->sCellIdx))
1478          {
1479             scellPCqiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nCqiTrIdx;
1480
1481             /* Handle wrap around case */
1482             if (scellPCqiTrIdx < crntSfIdx)
1483             {
1484                scellPCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1485             }
1486             
1487             /* If cqiCb->isCqiIgnoByCollsn is TRUE then a higher prio cqiCb
1488                is already found so need to compare */
1489             if ((FALSE == ueCb->cellInfo[cellIdx]->cqiCb.isCqiIgnoByCollsn) &&
1490                   (FALSE == cqiCb->isCqiIgnoByCollsn) && 
1491                   (scellPCqiTrIdx == pCqiTrIdx))
1492             {
1493                /* Handle Collision */
1494                /* set isCqiIgnoByCollsn to TRUE for low prio CQI Rep type */
1495                nPCqiServCellIdx = rgSCHUtlSCellCmpCqiCfg(&ueCb->cellInfo[cellIdx]->cqiCb,cqiCb);
1496             }
1497             else if (scellPCqiTrIdx < minPCqiTrIdx)
1498             {
1499                minPCqiTrIdx = scellPCqiTrIdx;
1500                nPCqiServCellIdx = cellIdx;
1501             }
1502          }
1503
1504          /* If all of the num of configured scells are checked then break */
1505          if (sCellCnt == ueCb->numSCells)
1506          {
1507             break;
1508          }   
1509          sCellCnt++;
1510       }
1511    }
1512
1513    /* Set the next expected Cqi into nPCqiCb */
1514    idx = ((nPCqiServCellIdx)& (CM_LTE_MAX_CELLS -1));
1515    ueCb->nPCqiCb = &ueCb->cellInfo[idx]->cqiCb;
1516
1517    return ROK;
1518 }
1519
1520
1521 /**
1522  * @brief Handling of collision of RI types between serving cells
1523  *
1524  * @details
1525  *
1526  *     Function: rgSCHUtlSCellHndlRiCollsn
1527  *     Purpose : Takes care of collision clauses specified in 36.213 7.2.2 Rel 10 
1528  *               and selects next nearest cqiCb 
1529  *     Invoked by:Cfg module 
1530  *
1531  *  @param[in]  RgSchCellCb  *cellCb
1532  *  @param[in]  RgSchUeCb    *ueCb
1533  *  @return  ROK/RFAILED
1534  *
1535  **/
1536 S16 rgSCHUtlSCellHndlRiCollsn(RgSchUePCqiCb *cqiCb)
1537 {
1538    uint32_t nPRiServCellIdx;
1539    uint32_t minPRiTrIdx;
1540    uint32_t scellPRiTrIdx;
1541    uint32_t pRiTrIdx;
1542    RgSchCellCb       *priCellCb = cqiCb->servCellInfo->ue->cell;
1543    RgSchUeCb         *ueCb = cqiCb->servCellInfo->ue;
1544    uint16_t crntSfIdx;
1545    uint32_t cellIdx;
1546    uint32_t sCellCnt = 0;
1547    CmLteTimingInfo timingInfo;
1548
1549 #ifdef xLTE_TDD
1550    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA);
1551 #else
1552    RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo,
1553          TFU_RECPREQ_DLDELTA);
1554 #endif
1555
1556    RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx);
1557
1558    pRiTrIdx = cqiCb->nRiTrIdx + cqiCb->riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1559
1560    /* Handle wrap around case */
1561    if (pRiTrIdx < crntSfIdx)
1562    {
1563       pRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1564    }
1565
1566    cqiCb->isRiIgnoByCollsn = FALSE;
1567    nPRiServCellIdx = cqiCb->servCellInfo->sCellIdx;
1568    minPRiTrIdx = pRiTrIdx;
1569
1570    for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++)
1571    {
1572       /* If a serving cell is configured */
1573       if(ueCb->cellInfo[cellIdx] != NULLP)
1574       {
1575          /* If the serving cell is in ACTIVE state and 
1576             If it is not the same serving cell as cqiCb for which 
1577             collision is being checked */
1578          if ((ueCb->cellInfo[cellIdx]->sCellState == RG_SCH_SCELL_ACTIVE)&&
1579                (cellIdx != cqiCb->servCellInfo->sCellIdx))
1580          {
1581             scellPRiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nRiTrIdx + 
1582                ueCb->cellInfo[cellIdx]->cqiCb.riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1583
1584             /* Handle wrap around case */
1585             if (scellPRiTrIdx < crntSfIdx)
1586             {
1587                scellPRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1588             }
1589             
1590             /* If cqiCb->isRiIgnoByCollsn is TRUE then a higher prio cqiCb
1591                is already found so need to compare */
1592             if ((FALSE == ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn) &&
1593                   (FALSE == cqiCb->isRiIgnoByCollsn) && 
1594                   (scellPRiTrIdx == pRiTrIdx))
1595             {
1596                /* Handle Collision */
1597                /* set isRiIgnoByCollsn to TRUE for low prio CQI Rep type */
1598                if (cqiCb->servCellInfo->sCellIdx < (ueCb->cellInfo[cellIdx]->sCellIdx))
1599                {
1600                   ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn = TRUE;
1601                }
1602                else
1603                {
1604                   cqiCb->isRiIgnoByCollsn = TRUE;
1605                }
1606             }
1607             else if (scellPRiTrIdx < minPRiTrIdx)
1608             {
1609                minPRiTrIdx = scellPRiTrIdx;
1610                nPRiServCellIdx = cellIdx;
1611             }
1612          }
1613
1614          /* If all of the num of configured scells are checked then break */
1615          if (sCellCnt == ueCb->numSCells)
1616          {
1617             break;
1618          }   
1619          sCellCnt++;
1620       }
1621    }
1622
1623    /* Set the next expected Cqi into nPCqiCb */
1624    ueCb->nPRiCb = &ueCb->cellInfo[nPRiServCellIdx]->cqiCb;
1625
1626    return ROK;
1627 }
1628 #endif/*TFU_UPGRADE*/
1629
1630 /**
1631  * @brief Checking whethter the scell is active or not
1632  *
1633  * @details
1634  *
1635  *     Function: rgSCHSCellIsActive
1636  *     Purpose: Check the Scell is in active state or not 
1637  *              
1638  *
1639  *     Invoked by: SpecificScheduler
1640  *
1641  *  @param[in]  RgSchCellCb*     cell
1642  *  @param[in]  RgSchUeCb*       ue
1643  *  @return  Void
1644  *
1645  **/
1646 S16 rgSCHSCellIsActive(RgSchCellCb *cell,RgSchUeCb *ue)
1647 {
1648    S16 retVal = RFAILED;
1649
1650    for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1651    {
1652       if((ue->cellInfo[idx] != NULLP) &&
1653          (ue->cellInfo[idx]->cell->cellId == cell->cellId)&&
1654          (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE)) 
1655       {
1656          retVal = ROK;
1657          break;
1658       }
1659    }
1660    return (retVal);     
1661 }
1662
1663 /**
1664  * @brief Function to check for Acell Activation Trigered.
1665  *
1666  * @details
1667  *
1668  *     Function : rgSCHIsActvReqd
1669  *       This function will check for Secondary cell activation criteria
1670  *       If met this will return TRUE else FALSE
1671  *     
1672  *  @param[in]     RgSchCellCb    *cell
1673  *  @param[in]     RgSchUeCb      *ue
1674  *  @return  BOOL
1675  *      -#  TRUE
1676  **/
1677 Bool rgSCHIsActvReqd(RgSchCellCb *cell,RgSchUeCb *ue)
1678 {
1679    /* Check if remBoCnt in this UE is greater than ZERO for sufficient number of
1680     * Scheduling TTIs. If yes then We should activate a secondary cell to handle
1681     * outstanding BO */
1682    if(ue->remBoCnt == RG_SCH_ACTIVATION_COUNT)
1683    {
1684       return (TRUE);
1685    }
1686    return (FALSE);
1687 }
1688 #endif/*LTE_ADV*/
1689
1690
1691
1692 /**********************************************************************
1693
1694          End of file
1695 **********************************************************************/