1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Round Robin functions
29 **********************************************************************/
32 @brief This module handles the round robin scheduler functionality
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
42 #include "rg_sch_inf.h"
43 #include "rg_sch_err.h"
45 #include "rg_sch_cmn.h"
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"
58 Void rgSCHSCellActivation ARGS((
59 RgSchUeCellInfo *sCell
62 Void rgSCHSCellSchdActDeactCe ARGS((
66 Void rgSCHSCellAddToActDeactLst ARGS((
71 Void rgSCHSCellRmvFrmActLst ARGS((
75 S16 rgSCHSCellIsActive ARGS((
80 Void rgSCHSCellHndlFdbkInd ARGS((
88 Void rgSCHSCellDeactTmrExpry ARGS((
89 RgSchUeCellInfo *sCell
93 Void rgSCHSCellDelUeSCell ARGS((
99 S16 rgSCHSCellDelUe ARGS((
104 S16 rgSCHSCellPCqiCfg ARGS((
105 RgSchCellCb *priCellCb,
106 RgSchCellCb *secCellCb,
108 RgrUePrdDlCqiCfg *cqiCfg,
109 CmLteUeCategory ueCat,
113 static S16 rgSCHSCellTrgMacHqEReset ARGS((
121 /** * @brief Handler for scheduling Scell Activation CE.
125 * Function : rgSCHDhmShcdSCellActCe
127 * This function is called by scheduler when resource allocation
128 * for SCell Activation CE transmission is done.
130 * @param[in] RgSchUeCb *ue
131 * @param[out] RgSchDlHqTbCb *tbInfo
135 Void rgSCHSCellSchdActDeactCe(RgSchUeCb *ueCb,RgSchDlHqTbCb *tbInfo)
139 uint8_t sCellActDeactBitMask = 0;
141 /* Change the state of all Scells waiting for
144 /* -------------------------
145 * | C7|C6|C5|C4|C3|C2|C1|R|
146 * -------------------------*/
151 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
153 if(ueCb->cellInfo[idx] != NULLP)
155 switch(ueCb->cellInfo[idx]->sCellState)
157 case RG_SCH_SCELL_TOBE_ACTIVATED:
158 case RG_SCH_SCELL_ACTVTN_IN_PROG:
160 ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_ACTVTN_IN_PROG;
164 case RG_SCH_SCELL_ACTIVE:
169 case RG_SCH_SCELL_TOBE_DEACTIVATED:
170 case RG_SCH_SCELL_DEACTVTN_IN_PROG:
172 ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_DEACTVTN_IN_PROG;
176 case RG_SCH_SCELL_INACTIVE:
177 case RG_SCH_SCELL_READY:
186 sCellActDeactBitMask |= 1 << (idx);/* servCellIdx = idx + 1 */
190 tbInfo->schdSCellActCe.pres = PRSNT_NODEF;
191 tbInfo->schdSCellActCe.val = sCellActDeactBitMask;
194 } /* rgSCHSCellSchdActDeactCe */
198 * @brief Adds an UE to the Cell's SCell Activation list
202 * Function: rgSCHSCellAddToActDeactLst
203 * Purpose: Adds an UE to Cell's SCEll Act list
205 * Invoked by: Common Scheduler
207 * @param[in] RgSchCellCb* cell
208 * @param[in] RgSchUeCb* ue
212 Void rgSCHSCellAddToActDeactLst(RgSchCellCb *cell,RgSchUeCb *ue)
214 RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
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;
223 RGSCHDBGINFONEW(cell->instIdx,(rgSchPBuf(cell->instIdx),
224 "SCell is already added in the Act List: ueId(%u)\n", ue->ueId));
232 * @brief Removes an UE from Cell's SCell Activation list
236 * Function: rgSCHSCellRmvFrmActLst
237 * Purpose: Removes an UE from Cell's SCEll Act list
239 * Invoked by: Specific Scheduler
241 * @param[in] RgSchCellCb* cell
242 * @param[in] RgSchUeCb* ue
246 Void rgSCHSCellRmvFrmActLst(RgSchCellCb *cell,RgSchUeCb *ue)
248 RgSchCmnDlCell *cellCmnDl = RG_SCH_CMN_GET_DL_CELL(cell);
249 if (NULLP != ue->sCellActLnk.node)
251 cmLListDelFrm(&cellCmnDl->secCellActCeLst, &ue->sCellActLnk);
253 ue->sCellActLnk.node = (PTR)NULLP;
259 * @brief Handling of SCell Activation
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
268 * Invoked by:Cfg/Commn Scheduler
270 * @param[in] RgSchUeCellInfo *sCellInfo
272 * @return ROK/RFAILED
275 Void rgSCHSCellActivation(RgSchUeCellInfo *sCellInfo)
277 RgSchCellCb *sCell = sCellInfo->cell;
278 RgSchUeCb *ueCb = sCellInfo->ue;
279 RgSchCmnCell *cellSch;
282 Inst inst = ueCb->cell->instIdx;
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;
296 sCellInfo->sCellState = RG_SCH_SCELL_ACTIVE;
298 ueCb->tenbStats->stats.persistent.numActivation++;
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);
304 /* Start the sCellDeactivation timer if cfgd */
305 if(PRSNT_NODEF == ueCb->sCellDeactTmrVal.pres)
307 //rgSCHTmrStartTmr (sCell,sCellInfo ,RG_SCH_TMR_SCELL_DEACT,
308 // ueCb->sCellDeactTmrVal.val);
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);
316 cqiCb = &sCellInfo->cqiCb;
317 cqiCfg = &cqiCb->cqiCfg;
318 if (cqiCfg->type == RGR_SCH_PCQI_SETUP)
320 cqiTrInstTime = ((cqiCb->cqiPeri+crntTime) - cqiCb->cqiOffset)
322 cqiCb->nCqiTrIdx = (crntTime +
323 (cqiCb->cqiPeri - cqiTrInstTime));
324 /* Introduced timing delta for reception req
326 if(cqiCb->nCqiTrIdx <= (crntTime + TFU_RECPREQ_DLDELTA))
328 cqiCb->nCqiTrIdx = cqiCb->nCqiTrIdx + cqiCb->cqiPeri;
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)
335 rgSCHTomUtlPcqiSbCalcBpIdx(timingInfo,ueCb,cqiCb);
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));
344 cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nCqiTrIdx].cqiLst,
347 rgSCHUtlSCellHndlCqiCollsn(cqiCb);
349 RGSCHDBGINFO(inst,(rgSchPBuf(inst),
350 "\n rgSCHCfgPCqiUeCfg():"
351 " CrntTime=%d Next CqiTrInstTime=%d Index Stored at=%d ",
352 crntTime, cqiTrInstTime, cqiCb->nCqiTrIdx));
354 if(cqiCfg->cqiSetup.riEna)
357 cqiCb->invalidateCqi = FALSE;
359 if(RGR_UE_PCQI_WB_REP == cqiCfg->cqiSetup.cqiRepType)
362 1. wideband RI reporting is configured
364 (10*sfn+floor(subframe)-Noffsetcqi-NoffsetRI )Mod(NCqiperiod
367 periodicity = cqiCb->cqiPeri * cqiCb->riPeri;
372 * Where Widesband and Subband RI reporting is configured
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
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 *
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)
392 periodicity = cqiCb->cqiOffset - cqiCb->riOffset +
393 RGSCH_MAX_SUBFRM_5G - (crntTime);
394 tempIdx = crntTime + periodicity;
398 riTrInsTime = ((periodicity +crntTime )- \
399 cqiCb->cqiOffset + cqiCb->riOffset)\
401 tempIdx = (crntTime + (periodicity -riTrInsTime));
403 if (tempIdx <= (crntTime + TFU_RECPREQ_DLDELTA))
405 tempIdx = tempIdx + periodicity;
407 cqiCb->nRiTrIdx = tempIdx
408 % RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
409 if(periodicity >= RG_SCH_PCQI_SRS_SR_TRINS_SIZE)
411 cqiCb->riDist = rgSCHUtlFindDist((uint16_t)(crntTime + TFU_RECPREQ_DLDELTA),
420 /* Start receiving RI for this SCell for this UE */
421 cmLListAdd2Tail(&ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst,
423 RG_SCH_RECORD(&cqiCb->histElem,RGSCH_ACTION_ADD,
424 &ueCb->cell->pCqiSrsSrLst[cqiCb->nRiTrIdx].riLst);
426 rgSCHUtlSCellHndlRiCollsn(cqiCb);
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));
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));
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));
452 cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell);
453 cellSch->apisDl->rgSCHDlSCellActv(sCellInfo->cell, sCellInfo->ue);
461 * @brief Remove CQI from Scell Lst
465 * Function: rgSCHCellClearScellLstOfCQI
466 * Purpose : Remove CQI from Scell Lst
471 * @param[in] RgSchUeCellInfo *sCellInfo
475 static Void rgSCHCellClearScellLstOfCQI(RgSchUeCellInfo *sCellInfo)
478 RgSchUePCqiCb *cqiRiCb = NULLP;
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)
486 cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nCqiTrIdx].cqiLst,
487 &cqiRiCb->cqiLstEnt);
488 cqiRiCb->nCqiTrIdx = RG_SCH_INVALID_IDX;
490 if (ueCb->nPCqiCb == cqiRiCb)
492 rgSCHUtlSCellHndlCqiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb);
494 /* Delete Periodic RI Transmission Instance */
496 if (cqiRiCb->nRiTrIdx != RG_SCH_INVALID_IDX)
498 cmLListDelFrm(&ueCb->cell->pCqiSrsSrLst[cqiRiCb->nRiTrIdx].riLst,
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)
505 rgSCHUtlSCellHndlRiCollsn(&ueCb->cellInfo[RGSCH_PCELL_INDEX]->cqiCb);
512 #endif/*TFU_UPGRADE*/
515 * @brief Handling of SCell DeActivation
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
527 * Invoked by:Cfg/Commn Scheduler
529 * @param[in] RgSchUeCellInfo *sCellInfo
531 * @return ROK/RFAILED
534 static S16 rgSCHSCellDeActivation(RgSchUeCellInfo *sCellInfo)
537 RgSchCmnCell *cellSch;
538 Inst inst = sCellInfo->cell->instIdx;
540 /* Stop the timer if running */
542 if(sCellInfo->deactTmr.tmrEvnt != TMR_NONE)
544 rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_DEACT, sCellInfo);
547 if (sCellInfo->actDelayTmr.tmrEvnt != TMR_NONE)
549 rgSCHTmrStopTmr(sCellInfo->cell, RG_SCH_TMR_SCELL_ACT_DELAY, sCellInfo);
552 cellSch = RG_SCH_CMN_GET_CELL(sCellInfo->cell);
553 cellSch->apisDl->rgSCHDlUeReset(sCellInfo->cell, sCellInfo->ue);
555 if(sCellInfo->ue->isDrxEnabled)
557 rgSCHDrxUeHqReset(sCellInfo->ue->cell, sCellInfo->ue,
558 sCellInfo->hqEnt, sCellInfo->sCellIdx);
561 /* Flush the harqEntity at scheduler */
562 if(sCellInfo->hqEnt != NULLP)
564 rgSCHDhmHqEntReset(sCellInfo->hqEnt);
566 /* Trigger harq flush req to MAC */
569 rgSCHSCellTrgMacHqEReset(inst,sCellInfo->sCellId,sCellInfo->ue->ueId);
571 sCellInfo->sCellState = RG_SCH_SCELL_READY;
573 rgSCHCellClearScellLstOfCQI(sCellInfo);
577 sCellInfo->ue->tenbStats->stats.persistent.numDeactivation++;
580 cellSch->apisDl->rgSCHDlSCellDeactv(sCellInfo->cell, sCellInfo->ue);
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);
591 * @brief Triggering hqEntity reset to mac
595 * Function: rgSCHSCellTrgMacHqEReset
596 * Purpose: Frame the interface for mac to reset
598 * Derive the macInstance corresponding
599 * to the secondary cell going to be deactivated.
600 * Triiger the msg to that macInstance
602 * Invoked by: CommonScheduler
604 * @param[in] uint16_t sCellId
605 * @param[in] uint16_t rnti
609 static S16 rgSCHSCellTrgMacHqEReset(Inst inst,uint16_t secCellId,uint16_ rnti)
612 RgSchCellCb *secCellCb = NULLP;
613 RgInfResetHqEnt hqEntRstInfo;
615 if((secCellCb = (RgSchCellCb *)rgSchUtlGetCellCb(inst, secCellId)) == NULLP)
617 RGSCHDBGERRNEW(inst, (rgSchPBuf(inst), "SCell doesnt exists"));
621 hqEntRstInfo.cellId = secCellId;
622 hqEntRstInfo.crnti = rnti;
624 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], secCellCb->macInst);
626 RgSchMacRstHqEnt(&pst, &hqEntRstInfo);
635 * @brief Handling of harq feeback for SCell act CE txion
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
643 * HQ FAILURE/DTX/NACK:: Perform retxion. Add to Act CE list
644 * Set the state to TOBE_SCHEDULED
647 * Invoked by: CommonScheduler
649 * @param[in] RgSchCellCb* cell
650 * @param[in] RgSchUeCb* ue
654 Void rgSCHSCellHndlFdbkInd(RgSchDlHqProcCb *hqP,uint8_t tbIdx,uint8_t fdbk,Bool maxHqRetxReached)
659 RgSchUeCellInfo *sCellInfo;
668 hqP->tbInfo[tbIdx].schdSCellActCe.pres = FALSE;
670 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
672 if(ueCb->cellInfo[idx] != NULLP)
674 if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG)
677 printf("\n starting delay timer...\n");
679 rgSCHTmrStartTmr (cell,ueCb->cellInfo[idx] ,RG_SCH_TMR_SCELL_ACT_DELAY,
680 RG_SCH_CMN_SCELL_ACT_DELAY_TMR);
684 if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG)
686 sCellInfo = ueCb->cellInfo[idx];
687 rgSCHSCellDeActivation(sCellInfo);
697 if(TRUE == maxHqRetxReached)
699 hqP->tbInfo[tbIdx].schdSCellActCe.pres = FALSE;
700 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
702 if(ueCb->cellInfo[idx] != NULLP)
704 if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTVTN_IN_PROG)
706 ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED;
710 if(ueCb->cellInfo[idx]->sCellState == RG_SCH_SCELL_DEACTVTN_IN_PROG)
712 ueCb->cellInfo[idx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED;
716 /* Add to actDeactCe lst */
717 rgSCHSCellAddToActDeactLst(cell,ueCb);
730 * @brief Handling of SCell Deactivation Tmr Expiry
734 * Function: rgSCHSCellDeactTmrExpry
735 * Purpose : Deactivating the SCell. a
736 * Clear all the Harq Procs associated with this
738 * Trigger Harq Reset to the respective MAC
739 * Set the state of the cell to Inactive
744 * @param[in] RgSchUeCellInfo *sCellInfo
748 Void rgSCHSCellDeactTmrExpry(RgSchUeCellInfo *sCellInfo)
751 if (sCellInfo->ue->isScellExplicitDeAct == TRUE)
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))
757 rgSCHSCellTrigActDeact(sCellInfo->ue->cell, sCellInfo->ue, sCellInfo->sCellIdx, RGR_SCELL_DEACT);
761 printf (" !!!!!! Avoiding DEACT for UE %d because of LAA Cell !!!!!!!!!!!!! \n",
762 sCellInfo->ue->ueId);
768 /* Deactivation Timer is configured, thus assume that UE has deactivated */
769 rgSCHSCellDeActivation(sCellInfo);
776 * @brief This function handles the action of the SCell
780 * Function: rgSCHSCellTrigActDeact
782 * 1) Prepares SCELL ready for activation OR
783 * 2) Initiates activation of SCELL OR
784 * 3) Initiate deactivation of SCELL OR
786 * Invoked by:Cfg/Commn Scheduler
788 * @param[in] RgSchCellCb *cellCb
789 * @param[in] RgSchUeCb *ueCb
790 * @param[in] uint8_t sCellIdx
791 * @param[in] uint8_t action
793 * @return ROK/RFAILED
796 S16 rgSCHSCellTrigActDeact(RgSchCellCb *cell,RgSchUeCb *ueCb,uint8_t sCellIdx,uint8_t action)
798 Inst inst = cell->instIdx;
802 (sCellIdx > RGR_MAX_SCELL_PER_UE))
804 RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n", \
809 if(ueCb->cellInfo[sCellIdx] == NULLP)
811 RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Serv Cell not added to this Ue Scell Idx %d ueId %d\n", \
812 sCellIdx,ueCb->ueId));
818 case RGR_SCELL_READY:
820 if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_INACTIVE)
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));
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]);
841 if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_READY)
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));
849 ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_TOBE_ACTIVATED;
850 if (NULLP == ueCb->sCellActLnk.node)
852 /* Add only if UE is not already present in the activation/deactivation list */
853 rgSCHSCellAddToActDeactLst(cell,ueCb);
858 case RGR_SCELL_DEACT:
860 if(ueCb->cellInfo[sCellIdx]->sCellState != RG_SCH_SCELL_ACTIVE)
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));
868 ueCb->cellInfo[sCellIdx]->sCellState = RG_SCH_SCELL_TOBE_DEACTIVATED;
869 if (NULLP == ueCb->sCellActLnk.node)
871 /* Add only if UE is not already present in the activation/deactivation list */
872 rgSCHSCellAddToActDeactLst(cell,ueCb);
879 RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid action received for SCell Idx %u for UE %u\n", \
880 sCellIdx, ueCb->ueId));
890 * @brief SCell Activation of selected cell
894 * Function: rgSCHSCellSelectForAct
895 * Purpose : Perform Selection of secondary cell for activation
897 * Invoked by:Cfg/Commn Scheduler
899 * @param[in] RgSchCellCb *cellCb
900 * @param[in] RgSchUeCb *ueCb
902 * @return ROK/RFAILED
905 static S16 rgSCHSCellSelectForAct(RgSchCellCb *cell,RgSchUeCb *ueCb,uint8_t *sCellIdx)
908 for((*sCellIdx) = 1; (*sCellIdx) <= RG_SCH_MAX_SCELL; (*sCellIdx)++)
910 if((ueCb->cellInfo[(*sCellIdx)] != NULLP) &&
911 (ueCb->cellInfo[(*sCellIdx)]->sCellState == RG_SCH_SCELL_READY))
920 * @brief SCell Activation of selected cell
924 * Function: rgSCHSCellSelectAndActDeAct
925 * Purpose : Perform Selection and Activation/Deactivation of secondary cell
927 * Invoked by:Cfg/Commn Scheduler
929 * @param[in] RgSchCellCb *cellCb
930 * @param[in] RgSchUeCb *ueCb
931 * @param[in] uint8_t action
936 Void rgSCHSCellSelectAndActDeAct(RgSchCellCb *pCell,RgSchUeCb *ueCb,uint8_t action)
938 uint8_t sCellIdx = 0;
946 if(((ret = rgSCHSCellSelectForAct(pCell, ueCb, &sCellIdx)) == ROK)
955 (ROK != (rgSCHSCellTrigActDeact(pCell, ueCb, sCellIdx, action))))
957 RGSCHDBGERR(pCell->instIdx,(rgSchPBuf(pCell->instIdx), "SCell Actication failed"
958 "for UE [%d] with SCellIdx [%d]\n", ueCb->ueId, sCellIdx));
965 * @brief Handling of Scell Deletion
969 * Function: rgSCHSCellDelUeSCell
970 * Purpose : Perform Scell Deletion for an UE
971 * : flush harqEnttiy of the given scell associated
975 * Invoked by:Cfg module
977 * @param[in] RgSchCellCb *cellCb
978 * @param[in] RgSchUeCb *ueCb
979 * @param[in] uint8_t idx
980 * @return ROK/RFAILED
983 Void rgSCHSCellDelUeSCell(RgSchCellCb *cellCb,RgSchUeCb *ueCb,uint8_t sCellIdx)
986 Inst inst = cellCb->instIdx;
987 RgSchUeCellInfo *sCellInfo;
990 sCellInfo = ueCb->cellInfo[sCellIdx];
993 if(sCellInfo == NULLP)
995 RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Serv Cell not added to this Ue Scell Idx %d\
997 sCellIdx,ueCb->ueId));
1001 rgSCHDbmDelUeCb(sCellInfo->cell, ueCb);
1002 ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, sCellInfo->cell);
1004 if (NULLP != sCellInfo->sCellLnk.node)
1006 cmLListDelFrm(&sCellInfo->cell->sCellUeLst, &sCellInfo->sCellLnk);
1009 /* Clear Scheduler specific list for this UE from the
1010 * corresponding CELL */
1012 /*Updating 1BCS Value*/
1013 ueCb->f1bCsAVal = (ueCb->f1bCsAVal -
1014 rgSCHUtlGetMaxTbSupp(sCellInfo->txMode.txModeEnum));
1017 rgSCHUtlDelUeANFdbkInfo(ueCb,sCellIdx);
1020 rgSCHSCellDeActivation(sCellInfo);
1021 /* Release hqEnt mem */
1022 rgSCHDhmDelHqEnt(cellCb, &sCellInfo->hqEnt);
1024 ulHqEnt = &(ueUl->hqEnt);
1026 cellCb->sc.apis->rgSCHRgrSCellUeDel(sCellInfo, sCellInfo->ue);
1028 rgSCHUhmFreeUe(sCellInfo->cell, ulHqEnt);
1030 rgSCHUtlFreeSBuf(cellCb->instIdx,
1031 (Data**)(&(sCellInfo)), (sizeof(RgSchUeCellInfo)));
1033 ueCb->cellInfo[sCellIdx] = NULLP;
1039 * @brief Handling of UE Deletion
1043 * Function: rgSCHSCellDelUe
1044 * Purpose : Perform UE Deletion
1045 * : Delete all the SCells added for this UE
1046 * : flush harqEnttiy of all scells associated
1050 * Invoked by:Cfg module
1052 * @param[in] RgSchCellCb *cellCb
1053 * @param[in] RgSchUeCb *ueCb
1054 * @return ROK/RFAILED
1057 S16 rgSCHSCellDelUe(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
1061 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1063 rgSCHSCellDelUeSCell(cellCb,ueCb,idx);
1072 * @brief Handling of PCqi cfg fro a scell
1076 * Function: rgSCHSCellPCqiCfg
1078 * : Delete all the SCells added for this UE
1079 * : flush harqEnttiy of all scells associated
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
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
1094 * Invoked by:Cfg module
1096 * @param[in] RgSchCellCb *cellCb
1097 * @param[in] RgSchUeCb *ueCb
1098 * @return ROK/RFAILED
1101 S16 rgSCHSCellPCqiCfg
1103 RgSchCellCb *priCellCb,
1104 RgSchCellCb *secCellCb,
1106 RgrUePrdDlCqiCfg *cqiCfg,
1107 CmLteUeCategory ueCat,
1111 uint8_t j; /*Bandwidth Parts*/
1114 Inst inst = priCellCb->instIdx;
1116 RgSchUeCellInfo *sCellInfo;
1117 RgSchUePCqiCb *cqiCb = NULLP;
1119 RGSCHDBGINFO(priCellCb->instIdx, (rgSchPBuf(priCellCb->instIdx),
1120 "rgSCHSCellPCqiCfg cellId =%d, ueId = %d, CfgType =%d\n",
1121 secCellCb->cellId, ueCb->ueId, cqiCfg->type));
1123 if((sCellIdx < 1) ||
1124 (sCellIdx > RGR_MAX_SCELL_PER_UE))
1126 RGSCHDBGERRNEW(inst, (rgSchPBuf(inst),"Invalid Serv Cell Idx %d\n",
1131 sCellInfo = ueCb->cellInfo[sCellIdx];
1133 cqiCb = &ueCb->cellInfo[sCellIdx]->cqiCb;
1134 cqiCb->servCellInfo = sCellInfo;
1136 /* Periodic CQI is setup */
1137 if (cqiCfg->type == RGR_SCH_PCQI_SETUP)
1139 /* 1. Copy the Received CQI Cfg parameters to ueCb */
1140 memcpy(&cqiCb->cqiCfg, cqiCfg,
1141 sizeof(RgrUePrdDlCqiCfg));
1143 /* 2. Compute Periodic CQI Periodicity and subframe offset */
1145 rgSCHUtlGetCfgPerOff(RG_SCH_FDD_PCQI_TBL, cqiCfg->cqiSetup.cqiPCfgIdx,
1146 &cqiCb->cqiPeri, &cqiCb->cqiOffset);
1148 rgSCHUtlGetCfgPerOff( RG_SCH_TDD_PCQI_TBL,
1149 cqiCfg->cqiSetup.cqiPCfgIdx,
1150 &cqiCb->cqiPeri, &cqiCb->cqiOffset);
1154 RGSCHDBGINFO(priCellCb->instIdx,(rgSchPBuf(priCellCb->instIdx),
1155 "\n rgSCHSCellPCqiCfg(): CQI Peri=%d, CQI Offset=%d",
1156 cqiCb->cqiPeri,cqiCb->cqiOffset));
1158 if(RGR_UE_PCQI_SB_REP == cqiCfg->cqiSetup.cqiRepType)
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);
1174 /* Wideband Cqi Rep Type */
1175 cqiCb->prioLvl = RG_SCH_CQI_PRIO_LVL_1;
1177 cqiCb->cqiLstEnt.node=(PTR)cqiCb;
1178 cqiCb->isCqiIgnoByCollsn = FALSE;
1181 /* 4. Rank Indicator Cfg handler */
1182 /* 1. Rank Indicator is enabled */
1183 if(cqiCfg->cqiSetup.riEna)
1185 rgSCHUtlGetCfgPerOff(RG_SCH_RI_TBL,
1186 cqiCfg->cqiSetup.riCfgIdx,
1187 &cqiCb->riPeri, &cqiCb->riOffset);
1189 RGSCHDBGINFO(priCellCb->instIdx,(rgSchPBuf(priCellCb->instIdx),
1190 "\n rgSCHSCellPCqiCfg(): RI Peri=%d, RI Offset=%d",
1191 cqiCb->riPeri,cqiCb->riOffset));
1193 if(ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_3
1194 || ueCb->cellInfo[sCellIdx]->txMode.txModeEnum == RGR_UE_TM_4)
1196 if (secCellCb->numTxAntPorts ==2)
1198 cqiCb->riNumBits = 1;
1200 else if(secCellCb->numTxAntPorts ==4)
1202 if(ueCat == CM_LTE_UE_CAT_8)
1204 cqiCb->riNumBits = 3;
1206 else if((ueCat == CM_LTE_UE_CAT_5) ||
1207 (ueCat == CM_LTE_UE_CAT_6) || CM_LTE_UE_CAT_7)
1209 cqiCb->riNumBits = 2;
1213 cqiCb->riNumBits = 1;
1217 cqiCb->riLstEnt.node=(PTR) cqiCb;
1218 cqiCb->isRiIgnoByCollsn = FALSE;
1224 sCellInfo->cqiCb.cqiCfg.type = RGR_SCH_PCQI_REL;
1226 /* Setting the indices to invalid during
1227 scell addition. These indices will be set during
1229 cqiCb->nRiTrIdx = RG_SCH_INVALID_IDX;
1230 cqiCb->riDist = RG_SCH_INVALID_IDX;
1231 cqiCb->nCqiTrIdx = RG_SCH_INVALID_IDX;
1238 * @brief Handling of Ue Reset from common scheduler
1242 * Function: rgSCHSCellDlUeReset
1243 * Purpose: Call scheudler type spcefic UE RESET
1244 * for all the secondary cells
1246 * Invoked by: CommonScheduler
1248 * @param[in] RgSchCellCb* cell
1249 * @param[in] RgSchUeCb* ue
1253 Void rgSCHSCellDlUeReset(RgSchCellCb *cell,RgSchUeCb *ue)
1255 RgSchCmnCell *cellSch;
1257 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1259 if(ue->cellInfo[idx] != NULLP)
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;
1272 * @brief Handling of LC Cfg from common scheduler
1276 * Function: rgSCHSCellDlLcCfg
1277 * Purpose: Call scheudler type spcefic LC config
1278 * for all the secondary cells
1280 * Invoked by: CommonScheduler
1282 * @param[in] RgSchCellCb* cell
1283 * @param[in] RgSchUeCb* ue
1287 Void rgSCHSCellDlLcCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1289 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1290 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1292 if(ue->cellInfo[idx] != NULLP)
1294 cellSch->apisDl->rgSCHRgrDlLcCfg(ue->cellInfo[idx]->cell, ue, svc,NULLP,NULLP);
1301 * @brief Handling of LC Delete from common scheduler
1305 * Function: rgSCHSCellDlLcDel
1306 * Purpose: Call scheudler type spcefic bo update handler
1307 * for all the secondary cells
1309 * Invoked by: CommonScheduler
1311 * @param[in] RgSchCellCb* cell
1312 * @param[in] RgSchUeCb* ue
1316 Void rgSCHSCellDlLcDel(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1318 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
1319 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1321 if(ue->cellInfo[idx] != NULLP)
1323 cellSch->apisDl->rgSCHFreeDlLc(ue->cellInfo[idx]->cell, ue, svc);
1330 * @brief Handling of Bo update from common scheduler
1334 * Function: rgSCHSCellDlDedBoUpd
1335 * Purpose: Call scheudler type spcefic bo update handler
1336 * for all the secondary cells
1338 * Invoked by: CommonScheduler
1340 * @param[in] RgSchCellCb* cell
1341 * @param[in] RgSchUeCb* ue
1345 Void rgSCHSCellDlDedBoUpd(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *svc)
1347 RgSchCmnCell *cellSch = RG_SCH_CMN_GET_CELL(cell);
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)
1354 cellSch->apisDl->rgSCHDlDedBoUpd(ue->cell, ue, svc);
1356 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1358 if((ue->cellInfo[idx] != NULLP) &&
1359 (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE) &&
1360 (ue->cellInfo[idx]->cell != cell))
1362 cellSch->apisDl->rgSCHDlDedBoUpd(ue->cellInfo[idx]->cell, ue, svc);
1369 * @brief Compare two CQI CB configs are return the result
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
1379 * @param[in] RgSchUePCqiCb *cqiCb1
1380 * @param[in] RgSchUePCqiCb *cqiCb2
1381 * @return uint8_t cqiCb cell idx which has the higher priority
1384 static uint8_t rgSCHUtlSCellCmpCqiCfg(RgSchUePCqiCb *cqiCb1,RgSchUePCqiCb *cqiCb2)
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 */
1391 if (cqiCb1->prioLvl > cqiCb2->prioLvl)
1393 cqiCb2->isCqiIgnoByCollsn = TRUE;
1394 cqiCb1->isCqiIgnoByCollsn = FALSE;
1397 else if (cqiCb2->prioLvl > cqiCb1->prioLvl)
1399 cqiCb1->isCqiIgnoByCollsn = TRUE;
1400 cqiCb2->isCqiIgnoByCollsn = FALSE;
1405 if (cqiCb1->servCellInfo->sCellIdx > cqiCb2->servCellInfo->sCellIdx)
1407 cqiCb1->isCqiIgnoByCollsn = TRUE;
1408 cqiCb2->isCqiIgnoByCollsn = FALSE;
1413 cqiCb2->isCqiIgnoByCollsn = TRUE;
1414 cqiCb1->isCqiIgnoByCollsn = FALSE;
1419 return (retCqiCb->servCellInfo->sCellIdx);
1423 * @brief Handling of collision of CQI types between serving cells
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
1432 * @param[in] RgSchCellCb *cellCb
1433 * @param[in] RgSchUeCb *ueCb
1434 * @return ROK/RFAILED
1437 S16 rgSCHUtlSCellHndlCqiCollsn(RgSchUePCqiCb *cqiCb)
1439 uint32_t nPCqiServCellIdx;
1440 uint32_t minPCqiTrIdx;
1441 uint32_t scellPCqiTrIdx;
1443 RgSchCellCb *priCellCb = cqiCb->servCellInfo->ue->cell;
1444 RgSchUeCb *ueCb = cqiCb->servCellInfo->ue;
1447 uint32_t sCellCnt = 0;
1448 CmLteTimingInfo timingInfo;
1452 RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA);
1454 RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo,
1455 TFU_RECPREQ_DLDELTA);
1458 RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx);
1460 cqiCb->isCqiIgnoByCollsn = FALSE;
1462 pCqiTrIdx = cqiCb->nCqiTrIdx;
1463 nPCqiServCellIdx = cqiCb->servCellInfo->sCellIdx;
1464 /* Handle wrap around case */
1465 if (pCqiTrIdx < crntSfIdx)
1467 pCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1469 minPCqiTrIdx = pCqiTrIdx;
1471 for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++)
1473 /* If a serving cell is configured */
1474 if(ueCb->cellInfo[cellIdx] != NULLP)
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))
1482 scellPCqiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nCqiTrIdx;
1484 /* Handle wrap around case */
1485 if (scellPCqiTrIdx < crntSfIdx)
1487 scellPCqiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
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))
1496 /* Handle Collision */
1497 /* set isCqiIgnoByCollsn to TRUE for low prio CQI Rep type */
1498 nPCqiServCellIdx = rgSCHUtlSCellCmpCqiCfg(&ueCb->cellInfo[cellIdx]->cqiCb,cqiCb);
1500 else if (scellPCqiTrIdx < minPCqiTrIdx)
1502 minPCqiTrIdx = scellPCqiTrIdx;
1503 nPCqiServCellIdx = cellIdx;
1507 /* If all of the num of configured scells are checked then break */
1508 if (sCellCnt == ueCb->numSCells)
1516 /* Set the next expected Cqi into nPCqiCb */
1517 idx = ((nPCqiServCellIdx)& (CM_LTE_MAX_CELLS -1));
1518 ueCb->nPCqiCb = &ueCb->cellInfo[idx]->cqiCb;
1525 * @brief Handling of collision of RI types between serving cells
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
1534 * @param[in] RgSchCellCb *cellCb
1535 * @param[in] RgSchUeCb *ueCb
1536 * @return ROK/RFAILED
1539 S16 rgSCHUtlSCellHndlRiCollsn(RgSchUePCqiCb *cqiCb)
1541 uint32_t nPRiServCellIdx;
1542 uint32_t minPRiTrIdx;
1543 uint32_t scellPRiTrIdx;
1545 RgSchCellCb *priCellCb = cqiCb->servCellInfo->ue->cell;
1546 RgSchUeCb *ueCb = cqiCb->servCellInfo->ue;
1549 uint32_t sCellCnt = 0;
1550 CmLteTimingInfo timingInfo;
1553 RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo, TFU_DELTA);
1555 RG_SCH_ADD_TO_CRNT_TIME(priCellCb->crntTime, timingInfo,
1556 TFU_RECPREQ_DLDELTA);
1559 RG_SCH_GET_IDX_PCQISRSSR(timingInfo, crntSfIdx);
1561 pRiTrIdx = cqiCb->nRiTrIdx + cqiCb->riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1563 /* Handle wrap around case */
1564 if (pRiTrIdx < crntSfIdx)
1566 pRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1569 cqiCb->isRiIgnoByCollsn = FALSE;
1570 nPRiServCellIdx = cqiCb->servCellInfo->sCellIdx;
1571 minPRiTrIdx = pRiTrIdx;
1573 for (cellIdx =0; cellIdx <= RG_SCH_MAX_SCELL; cellIdx++)
1575 /* If a serving cell is configured */
1576 if(ueCb->cellInfo[cellIdx] != NULLP)
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))
1584 scellPRiTrIdx = ueCb->cellInfo[cellIdx]->cqiCb.nRiTrIdx +
1585 ueCb->cellInfo[cellIdx]->cqiCb.riDist * RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
1587 /* Handle wrap around case */
1588 if (scellPRiTrIdx < crntSfIdx)
1590 scellPRiTrIdx += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
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))
1599 /* Handle Collision */
1600 /* set isRiIgnoByCollsn to TRUE for low prio CQI Rep type */
1601 if (cqiCb->servCellInfo->sCellIdx < (ueCb->cellInfo[cellIdx]->sCellIdx))
1603 ueCb->cellInfo[cellIdx]->cqiCb.isRiIgnoByCollsn = TRUE;
1607 cqiCb->isRiIgnoByCollsn = TRUE;
1610 else if (scellPRiTrIdx < minPRiTrIdx)
1612 minPRiTrIdx = scellPRiTrIdx;
1613 nPRiServCellIdx = cellIdx;
1617 /* If all of the num of configured scells are checked then break */
1618 if (sCellCnt == ueCb->numSCells)
1626 /* Set the next expected Cqi into nPCqiCb */
1627 ueCb->nPRiCb = &ueCb->cellInfo[nPRiServCellIdx]->cqiCb;
1631 #endif/*TFU_UPGRADE*/
1634 * @brief Checking whethter the scell is active or not
1638 * Function: rgSCHSCellIsActive
1639 * Purpose: Check the Scell is in active state or not
1642 * Invoked by: SpecificScheduler
1644 * @param[in] RgSchCellCb* cell
1645 * @param[in] RgSchUeCb* ue
1649 S16 rgSCHSCellIsActive(RgSchCellCb *cell,RgSchUeCb *ue)
1651 S16 retVal = RFAILED;
1653 for(uint8_t idx = 1; idx <= RG_SCH_MAX_SCELL ; idx++)
1655 if((ue->cellInfo[idx] != NULLP) &&
1656 (ue->cellInfo[idx]->cell->cellId == cell->cellId)&&
1657 (ue->cellInfo[idx]->sCellState == RG_SCH_SCELL_ACTIVE))
1667 * @brief Function to check for Acell Activation Trigered.
1671 * Function : rgSCHIsActvReqd
1672 * This function will check for Secondary cell activation criteria
1673 * If met this will return TRUE else FALSE
1675 * @param[in] RgSchCellCb *cell
1676 * @param[in] RgSchUeCb *ue
1680 Bool rgSCHIsActvReqd(RgSchCellCb *cell,RgSchUeCb *ue)
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
1685 if(ue->remBoCnt == RG_SCH_ACTIVATION_COUNT)
1695 /**********************************************************************
1698 **********************************************************************/