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 Entry point fucntions
29 **********************************************************************/
31 /** @file rg_sch_utl.c
32 @brief This file implements the schedulers main access to MAC layer code.
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_MODULE_ID=4096;
37 static int RLOG_FILE_ID=177;
39 /* header include files -- defines (.h) */
40 #include "common_def.h"
45 #include "rg_sch_err.h"
46 #include "rg_sch_inf.h"
48 #include "rg_sch_cmn.h"
50 #include "rl_interface.h"
51 #include "rl_common.h"
53 /* header/extern include files (.x) */
54 #include "tfu.x" /* TFU types */
55 #include "lrg.x" /* layer management typedefs for MAC */
56 #include "rgr.x" /* layer management typedefs for MAC */
58 #include "rg_sch_inf.x" /* typedefs for Scheduler */
59 #include "rg_sch.x" /* typedefs for Scheduler */
60 #include "rg_sch_cmn.x" /* typedefs for Scheduler */
62 #include "rg_sch_emtc_ext.x"
67 U32 rgNumPrachRecvd =0; /* Num of Rach Req received including dedicated preambles */
68 U32 rgNumRarSched =0; /* Num of RARs sent */
69 U32 rgNumBI =0; /* Num of BackOff Ind sent */
70 U32 rgNumMsg3CrcPassed =0; /* Num of CRC success for Msg3 */
71 U32 rgNumMsg3CrcFailed =0; /* Num of CRC fail for Msg 3 */
72 U32 rgNumMsg3FailMaxRetx =0; /* Num of Msg3 fail after Max Retx attempts */
73 U32 rgNumMsg4Ack =0; /* Num of Acks for Msg4 Tx */
75 /* Num of Nacks for Msg4 Tx */
76 U32 rgNumMsg4FailMaxRetx =0; /* Num of Msg4 Tx failed after Max Retx attempts */
77 U32 rgNumSrRecvd =0; /* Num of Sched Req received */
78 U32 rgNumSrGrant =0; /* Num of Sched Req Grants sent */
79 U32 rgNumMsg3CrntiCE =0; /* Num of Msg 3 CRNTI CE received */
80 U32 rgNumDedPream =0; /* Num of Dedicated Preambles recvd */
81 U32 rgNumMsg3CCCHSdu =0; /* Num of Msg 3 CCCH Sdus recvd */
82 U32 rgNumCCCHSduCrntiNotFound =0; /*UE Ctx not found for CCCH SDU Msg 3 */
83 U32 rgNumCrntiCeCrntiNotFound =0; /*UE Ctx not found for CRNTI CE Msg 3 */
84 U32 rgNumMsg4WithCCCHSdu =0; /* Num of Msg4 with CCCH Sdu */
85 U32 rgNumMsg4WoCCCHSdu =0; /* Num of Msg4 without CCCH Sdu */
86 U32 rgNumMsg4Dtx =0; /* Num of DTX received for Msg 4 */
87 U32 rgNumMsg3AckSent =0; /* Num of PHICH Ack sent for Msg 3 */
88 U32 rgNumMsg3NackSent =0; /* Num of PHICH Nack sent for Msg 3 */
89 U32 rgNumMsg4PdcchWithCrnti =0; /* Num of PDCCH for CRNTI based contention resolution */
90 U32 rgNumRarFailDuetoRntiExhaustion =0; /* Num of RACH Failures due to RNTI pool exhaution */
91 U32 rgNumTAModified =0; /* Num of times TA received is different from prev value */
92 U32 rgNumTASent =0; /* Num of TA Command sent */
93 U32 rgNumMsg4ToBeTx =0; /* Num of times MSG4 that should be sent */
94 U32 rgNumMsg4Txed =0; /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */
95 U32 rgNumMsg3DtxRcvd =0; /* CRC Fail with SINR < 0 */
97 U32 rgNumDedPreamUECtxtFound =0; /* Num of Dedicated Preambles recvd */
99 PRIVATE U8 rgSchDciAmbigSizeTbl[61] = {0,0,0,0,0,0,0,0,0,0,0,
100 0,1,0,1,0,1,0,0,0,1,
101 0,0,0,1,0,1,0,0,0,0,
102 0,1,0,0,0,0,0,0,0,1,
103 0,0,0,1,0,0,0,0,0,0,
104 0,0,0,0,0,1,0,0,0,0};
108 EXTERN U32 rgSchCmnBetaCqiOffstTbl[16];
109 EXTERN U32 rgSchCmnBetaRiOffstTbl[16];
110 EXTERN RgSchdApis rgSchCmnApis;
111 EXTERN PUBLIC S16 RgUiRgmSendPrbRprtInd ARGS((
114 RgmPrbRprtInd *prbRprtInd
117 EXTERN PUBLIC S16 RgUiRgmSendTmModeChangeInd ARGS((
120 RgmTransModeInd *txModeChngInd
123 EXTERN PUBLIC S16 rgSCHEmtcUtlGetSfAlloc ARGS((
126 EXTERN PUBLIC S16 rgSCHEmtcUtlPutSfAlloc ARGS((
129 EXTERN PUBLIC Void rgSCHEmtcUtlUpdUeDciSize ARGS((
133 EXTERN PUBLIC Void rgSCHEmtcGetDciFrmt61ASize ARGS((
136 EXTERN PUBLIC Void rgSCHEmtcGetDciFrmt60ASize ARGS((
139 EXTERN PUBLIC S16 rgSCHEmtcUtlFillPdschDciInfo ARGS((
140 TfuPdschDciInfo *pdsch,
143 EXTERN PUBLIC Void rgSCHEmtcUtlRlsRnti ARGS((
145 RgSchRntiLnk *rntiLnk,
148 EXTERN PUBLIC S16 rgSCHEmtcPdcchAlloc ARGS((
152 EXTERN PUBLIC Void rgSCHEmtcPdcchFree ARGS((
157 /* Functions specific to TM1/TM2/TM6/TM7 for PRB calculation*/
158 PUBLIC Void rgSchUtlDlCalc1CwPrb ARGS(( RgSchCellCb *cell,
163 /* Functions specific to TM3/TM4 for PRB calculation*/
164 PUBLIC Void rgSchUtlDlCalc2CwPrb ARGS(( RgSchCellCb *cell,
170 PUBLIC RgSchCellCb* rgSchUtlGetCellCb ARGS(( Inst inst,
175 typedef Void (*RgSchUtlDlCalcPrbFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
176 U32 bo, U32 *prbRequrd));
178 /* Functions specific to each transmission mode for PRB calculation*/
179 RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[7] = {rgSchUtlDlCalc1CwPrb,
180 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
181 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb};
184 /* Functions specific to each transmission mode for PRB calculation*/
185 RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[9] = {rgSchUtlDlCalc1CwPrb,
186 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
187 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb, NULLP, NULLP};
192 /* The below table will be used to map the UL SF number in a TDD Cfg 0
193 frame to the ul Sf array maintained in cellCb */
194 PRIVATE U8 rgSchTddCfg0UlSfTbl[] = {2, 3, 4, 7, 8, 9};
197 PRIVATE S16 rgSCHUtlUlAllocDbInit ARGS((
202 PRIVATE Void rgSCHUtlUlAllocDbDeinit ARGS((
206 PRIVATE S16 rgSCHUtlUlHoleDbInit ARGS((
213 PRIVATE Void rgSCHUtlUlHoleDbDeinit ARGS((
218 PRIVATE S16 rgSCHChkBoUpdate ARGS((
220 RgInfCmnBoRpt *boUpdt
224 PRIVATE U8 rgSCHUtlFetchPcqiBitSz ARGS((
231 /* sorted in ascending order of tbSz */
232 CONSTANT struct rgSchUtlBcchPcchTbSz
234 U8 rbIndex; /* RB index {2,3} */
235 U16 tbSz; /* one of the Transport block size in bits of
237 /* Corrected allocation for common channels */
239 } rgSchUtlBcchPcchTbSzTbl[44] = {
240 { 2, 32, 0 }, { 2, 56, 1 }, { 2, 72, 2 }, { 3, 88, 1 },
241 { 2, 104, 3 }, { 2, 120, 4 }, { 2, 144, 5 }, { 2, 176, 6 },
242 { 3, 208, 4 }, { 2, 224, 7 }, { 2, 256, 8 }, { 2, 296, 9 },
243 { 2, 328, 10 }, { 2, 376, 11 }, { 3, 392, 8 }, { 2, 440, 12 },
244 { 3, 456, 9 }, { 2, 488, 13 }, { 3, 504, 10 }, { 2, 552, 14 },
245 { 3, 584, 11 }, { 2, 600, 15 }, { 2, 632, 16 }, { 3, 680, 12 },
246 { 2, 696, 17 }, { 3, 744, 13 }, { 2, 776, 18 }, { 2, 840, 19 },
247 { 2, 904, 20 }, { 3, 968, 16 }, { 2, 1000, 21 }, { 2, 1064, 22 },
248 { 2, 1128, 23 }, { 3, 1160, 18 }, { 2, 1192, 24 }, { 2, 1256, 25 },
249 { 3, 1288, 19 }, { 3, 1384, 20 }, { 2, 1480, 26 }, { 3, 1608, 22 },
250 { 3, 1736, 23 }, { 3, 1800, 24 }, { 3, 1864, 25 }, { 3, 2216, 26 }
257 /* forward references */
259 PRIVATE Void rgSCHUtlUpdPrachOcc ARGS((
261 RgrTddPrachInfo *cellCfg));
264 #define RGSCH_NUM_PCFICH_REG 4
265 #define RGSCH_NUM_REG_PER_CCE 9
266 #define RGSCH_NUM_REG_PER_PHICH_GRP 3
269 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _iPhich) {\
270 (_phich)->hqFeedBack = _hqFeedBack; \
271 (_phich)->rbStart = _rbStart; \
272 (_phich)->nDmrs = _nDmrs; \
273 (_phich)->iPhich = _iPhich; \
274 (_phich)->lnk.next = NULLP; \
275 (_phich)->lnk.prev = NULLP; \
276 (_phich)->lnk.node = (PTR)(_phich); \
279 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _isForMsg3) {\
280 (_phich)->hqFeedBack = _hqFeedBack; \
281 (_phich)->rbStart = _rbStart; \
282 (_phich)->nDmrs = _nDmrs; \
283 (_phich)->isForMsg3 = _isForMsg3; \
284 (_phich)->lnk.next = NULLP; \
285 (_phich)->lnk.prev = NULLP; \
286 (_phich)->lnk.node = (PTR)(_phich); \
290 #define RGSCH_PHICH_ALLOC(_inst,_dataPtr, _size, _ret) {\
291 _ret = rgSCHUtlAllocSBuf(_inst, (Data **)&_dataPtr, _size); \
294 /* ccpu00117052 - MOD - Passing double pointer
295 for proper NULLP assignment*/
296 #define RGSCH_PHICH_FREE(_inst, _dataPtr, _size) {\
297 rgSCHUtlFreeSBuf(_inst, (Data **)(&(_dataPtr)), _size); \
301 #define RGSCH_GETBIT(a, b) ((((U8*)a)[(b)>>3] >> ((7-((b)&7)))) & 1)
307 * Desc: This function finds of the Power of x raised to n
309 * Ret: value of x raised to n
317 PUBLIC F64 rgSCHUtlPower
323 PUBLIC F64 rgSCHUtlPower(x, n)
334 RETVALUE( x * rgSCHUtlPower( x, n-1 ) );
338 RETVALUE( (1/x) * rgSCHUtlPower( x, n+1 ) );
340 } /* end of rgSCHUtlPower*/
346 * Desc: This function parses bits x to y of an array and
347 * returns the integer value out of it.
349 * Ret: integer value of z bits
357 PUBLIC U32 rgSCHUtlParse
365 PUBLIC U32 rgSCHUtlParse(buff, startPos, endPos, buffSize)
372 U8 pointToChar,pointToEnd, loop;
373 U8 size = endPos - startPos;
376 pointToEnd = (startPos)%8;
377 for ( loop=0; loop<size; loop++)
379 pointToChar = (((startPos)+loop)/8);
380 if (RGSCH_GETBIT(buff+pointToChar,pointToEnd%8)==1)
382 result=result+(rgSCHUtlPower(2,(size-loop-1)));
386 RETVALUE((U32)result);
387 } /* end of rgSCHUtlParse*/
391 * Fun: rgSCHUtlFindDist
393 * Desc: This function calculates the iterations need to cover
394 * before the valid Index can be used for next possible Reception
396 * Ret: integer value of z bits
404 PUBLIC U8 rgSCHUtlFindDist
410 PUBLIC U8 rgSCHUtlFindDist(crntTime, tempIdx)
416 /* ccpu00137113- Distance is not estimated properly if the periodicity is
417 * equal to RG_SCH_PCQI_SRS_SR_TRINS_SIZE.
419 while(crntTime<=tempIdx)
421 crntTime += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
425 } /* end of rgSCHUtlFindDist*/
430 * @brief This function checks availability of a PDCCH
434 * Function: rgSCHUtlPdcchAvail
435 * Purpose: This function checks if a particular PDCCH is in use.
436 * map field of PDCCH is used to track the CCEs arleady
437 * allocated. Each bit of map represents one CCE and the
438 * LSBit of first byte represents CCE 0.
440 * 1. Locate the set of bits that represent the PDCCH for
441 * the provided location.
442 * 2. If the value of the bits is non-zero one or many CCEs
443 * for the PDCCH are in use and hence the PDCCH is not available.
444 * 3. If pdcch is available, assign it to [out]pdcch.
445 * 4. Set all of the bits to one. There is no check performed
446 * to see if the PDCCH is available.
448 * Invoked by: scheduler
450 * @param[in] RgSchCellCb* cell
451 * @param[in] RgSchPdcchInfo* pdcchInfo
453 * @param[in] U8 aggrLvl
454 * @param[out] RgSchPdcch** pdcch
456 * -# TRUE if available
461 PUBLIC Bool rgSCHUtlPdcchAvail
464 RgSchPdcchInfo *pdcchInfo,
465 CmLteAggrLvl aggrLvl,
469 PUBLIC Bool rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, pdcch)
471 RgSchPdcchInfo *pdcchInfo;
472 CmLteAggrLvl aggrLvl;
480 Inst inst = cell->instIdx;
484 TRC2(rgSCHUtlPdcchAvail);
488 byte = &pdcchInfo->map[0];
489 initMask = (0xffff >> (16 - aggrLvl));
491 /* if N(symbol, xPDCCH) =2, then xPDCCH will be candidates in
492 * search space of index {0,1,2,3} and {8,9,..14}
494 if ((cell->cell5gtfCb.cfi == 2) && (aggrLvl == CM_LTE_AGGR_LVL2))
496 offsetStepMask = 0xc;
500 offsetStepMask = 0xc0;
503 /* Loop till the number of bytes available in the CCE map */
504 while (offset < ((pdcchInfo->nCce+ 7) >> 3))
506 byte = &pdcchInfo->map[offset];
507 /* Checking for available CCE */
508 if ((*byte & currMask) == 0)
512 /* if the number of CCEs required are not available, move to next offset */
513 if (currMask & offsetStepMask)
520 /* Move to the next available CCE index in the current byte(cce map) */
521 currMask = currMask << aggrLvl;
525 if ((offset >= ((pdcchInfo->nCce + 7) >> 3)) ||
526 ((aggrLvl == CM_LTE_AGGR_LVL16) && (offset > 0)))
531 byte = &pdcchInfo->map[offset];
533 if (cell->pdcchLst.first != NULLP)
535 *pdcch = (RgSchPdcch *)(cell->pdcchLst.first->node);
536 cmLListDelFrm(&cell->pdcchLst, cell->pdcchLst.first);
540 ret = rgSCHUtlAllocSBuf(inst, (Data **)pdcch, sizeof(RgSchPdcch));
550 /* ALL CCEs will be used in case of level 16 */
551 if (aggrLvl == CM_LTE_AGGR_LVL16)
553 *(byte+1) |= currMask;
555 (*pdcch)->aggrLvl = aggrLvl;
556 cmLListAdd2Tail(&pdcchInfo->pdcchs, &((*pdcch)->lnk));
557 (*pdcch)->lnk.node = (PTR)*pdcch;
558 (*pdcch)->nCce = aggrLvl;
559 (*pdcch)->ue = NULLP;
567 * @brief This function releases a PDCCH
571 * Function: rgSCHUtlPdcchPut
572 * Purpose: This function releases a PDCCH.
574 * 1. Locate the set of bits that represent the PDCCH for
575 * the provided location.
576 * 2. Set all of the bits to zero.
577 * 3. Release the memory of PDCCH to the cell free Q
579 * Invoked by: scheduler
581 * @param[in] RgSchPdcchInfo* pdcchInfo
583 * @param[in] U8 aggrLvl
588 PUBLIC Void rgSCHUtlPdcchPut
591 RgSchPdcchInfo *pdcchInfo,
595 PUBLIC Void rgSCHUtlPdcchPut(cell, pdcchInfo, pdcch)
597 RgSchPdcchInfo *pdcchInfo;
605 TRC2(rgSCHUtlPdcchPut);
607 switch(pdcch->aggrLvl)
609 case CM_LTE_AGGR_LVL2:
610 offset = (pdcch->nCce >> 1) & 3;
611 mask = 0x3 << (offset * 2); /*ccpu00128826 - Offset Correction */
613 case CM_LTE_AGGR_LVL4:
614 offset = (pdcch->nCce >> 2) & 1;
615 mask = 0xf << (offset * 4);/*ccpu00128826 - Offset Correction */
617 case CM_LTE_AGGR_LVL8:
620 case CM_LTE_AGGR_LVL16:
626 /* Placing common computation of byte from all the cases above here
628 byte = &pdcchInfo->map[pdcch->nCce >> 3];
630 cmLListDelFrm(&pdcchInfo->pdcchs, &pdcch->lnk);
631 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
632 pdcch->lnk.node = (PTR)pdcch;
641 * @brief This function initializes PDCCH information for frame
645 * Function: rgSCHUtlPdcchInit
646 * Purpose: This function initializes PDCCH information for
647 * a slot. It removes the list of PDCCHs allocated
648 * in the prior use of this slot structure.
650 * Invoked by: rgSCHUtlSubFrmPut
652 * @param[in] RgSchCellCb* cell
653 * @param[in] RgSubFrm* subFrm
658 PUBLIC Void rgSCHUtlPdcchInit
665 PUBLIC Void rgSCHUtlPdcchInit(cell, subFrm, nCce)
671 RgSchPdcchInfo *pdcchInfo;
673 Inst inst = cell->instIdx;
677 TRC2(rgSCHUtlPdcchInit);
679 pdcchInfo = &subFrm->pdcchInfo;
680 while(pdcchInfo->pdcchs.first != NULLP)
682 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
683 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
684 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
687 cmLListInit(&pdcchInfo->pdcchs);
690 subFrm->relPdcch = NULLP;
693 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
695 /* The bitMap array size is the number of ceiling(CCEs/8) */
696 /* If nCce received is not the same as the one stored in
697 * pdcchInfo, free the pdcchInfo map */
699 if(pdcchInfo->nCce != nCce)
703 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), cceMapSz);
705 pdcchInfo->nCce = nCce;
706 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
707 rgSCHUtlAllocSBuf(inst, (Data **)&pdcchInfo->map,
709 if (pdcchInfo->map == NULLP)
711 /* Generate log error here */
716 cmMemset(subFrm->pdcchInfo.map, 0, cceMapSz);
717 /* If nCce is not exactly same as the bitMap size(no of bits allocated
718 * to represent the Cce's, then mark the extra bits as unavailable
719 extra bits = (((pdcchInfo->nCce + 7) >> 3)*8) - pdcchInfo->nCce
720 The last byte of bit map = subFrm->pdcchInfo.map[((pdcchInfo->nCce + 7) >> 3) - 1]
721 NOTE : extra bits are most significant of the last byte eg. */
722 extraBits = (cceMapSz)*8 - pdcchInfo->nCce;
723 subFrm->pdcchInfo.map[cceMapSz - 1] |=
724 ((1 << extraBits) - 1) << (8 - extraBits);
728 /* LTE_ADV_FLAG_REMOVED_START */
730 * @brief This function frees Pool
733 * Function: rgSchSFRTotalPoolFree
735 * Invoked by: rgSchSFRTotalPoolInit
737 * @param[in] RgSchCellCb* cell
738 * @param[in] RgSubFrm* subFrm
743 PUBLIC Void rgSchSFRTotalPoolFree
745 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo,
749 PUBLIC Void rgSchSFRTotalPoolFree(sfrTotalPoolInfo, cell)
750 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo;
756 TRC2(rgSchSFRTotalPoolFree);
758 /*Deinitialise if these cc pools and ce pools are already existent*/
759 l = &sfrTotalPoolInfo->ccPool;
763 /*REMOVING Cell Centred POOLS IF ANY*/
764 n = cmLListDelFrm(l, n);
766 /* Deallocate buffer */
767 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
769 /* Deallocate buffer */
770 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
774 /*REMOVING Cell Edged POOLS IF ANY*/
775 l = &sfrTotalPoolInfo->cePool;
779 n = cmLListDelFrm(l, n);
781 /* Deallocate buffer */
782 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
784 /* Deallocate buffer */
785 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
792 * @brief This function resets temporary variables in Pool
795 * Function: rgSchSFRResetPoolVariables
797 * Invoked by: rgSCHSFRUtlTotalPoolInit
799 * @param[in] RgSchCellCb* cell
800 * @param[in] RgSubFrm* subFrm
805 PUBLIC S16 rgSchSFRTotalPoolInit
811 PRIVATE Void rgSchSFRTotalPoolInit(cell, sf)
816 /* Initialise the variables */
817 RgSchSFRPoolInfo *sfrCCPool;
818 RgSchSFRPoolInfo *sfrCEPool;
821 CmLList *temp = NULLP;
824 TRC2(rgSchSFRTotalPoolInit);
826 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
827 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = 0;
828 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = 0;
829 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = 0;
830 sf->sfrTotalPoolInfo.CC1 = FALSE;
831 sf->sfrTotalPoolInfo.CC2 = FALSE;
832 /*Initialise the CE Pools*/
833 cmLListInit (&(sf->sfrTotalPoolInfo.cePool));
835 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
838 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
839 "CE Pool memory allocation FAILED for cell");
840 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
844 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
847 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
848 "CE Pool memory allocation FAILED for cell ");
849 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
853 l = &sf->sfrTotalPoolInfo.cePool;
854 cmLListAdd2Tail(l, temp);
856 /*Initialise Bandwidth and startRB and endRB for each pool*/
859 /* Initialise the CE Pools */
860 sfrCEPool = (RgSchSFRPoolInfo*)n->node;
862 sfrCEPool->poolstartRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb;
863 sfrCEPool->poolendRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb;
864 sfrCEPool->bw = sfrCEPool->poolendRB - sfrCEPool->poolstartRB + 1;
865 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = sfrCEPool->bw;
867 sfrCEPool->bwAlloced = 0;
868 sfrCEPool->type2Start = sfrCEPool->poolstartRB;
869 sfrCEPool->type2End = RGSCH_CEIL(sfrCEPool->poolstartRB, cell->rbgSize);
870 sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1;
871 sfrCEPool->pwrHiCCRange.startRb = 0;
872 sfrCEPool->pwrHiCCRange.endRb = 0;
874 /*Initialise CC Pool*/
875 cmLListInit (&(sf->sfrTotalPoolInfo.ccPool));
877 /*Add memory and Update CCPool*/
878 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
881 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
882 "CC Pool memory allocation FAILED for cell ");
883 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
887 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
890 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
891 "CC Pool memory allocation FAILED for cell ");
892 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
896 l = &sf->sfrTotalPoolInfo.ccPool;
897 cmLListAdd2Tail(l, temp);
899 /*Initialise Bandwidth and startRB and endRB for each pool*/
900 if(sfrCEPool->poolstartRB)
903 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
905 sfrCCPool->poolstartRB = 0;
906 sfrCCPool->poolendRB = sfrCEPool->poolstartRB - 1;
907 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
908 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = sfrCCPool->bw;
909 sfrCCPool->bwAlloced = 0;
910 sfrCCPool->type2Start = 0;
911 sfrCCPool->type2End = 0;
912 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
913 sf->sfrTotalPoolInfo.CC1 = TRUE;
914 sfrCCPool->pwrHiCCRange.startRb = 0;
915 sfrCCPool->pwrHiCCRange.endRb = 0;
920 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
922 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
923 sfrCCPool->poolendRB = sf->bw - 1;
924 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
925 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
926 sfrCCPool->CCPool2Exists = TRUE;
927 sfrCCPool->bwAlloced = 0;
928 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
929 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
930 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
931 sf->sfrTotalPoolInfo.CC2 = TRUE;
932 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
933 sfrCCPool->pwrHiCCRange.startRb = 0;
934 sfrCCPool->pwrHiCCRange.endRb = 0;
937 if((sfrCEPool->poolendRB != sf->bw - 1) && (!sfrCCPool->poolstartRB))
939 /*Add memory and Update CCPool*/
940 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
943 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
944 "CC Pool memory allocation FAILED for cell ");
945 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
949 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
952 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
953 "CC Pool memory allocation FAILED for cell ");
954 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
958 cmLListAdd2Tail(l, temp);
961 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
963 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
964 sfrCCPool->poolendRB = sf->bw - 1;
965 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
966 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
967 sfrCCPool->CCPool2Exists = TRUE;
968 sfrCCPool->bwAlloced = 0;
969 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
970 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
971 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
972 sf->sfrTotalPoolInfo.CC2 = TRUE;
973 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
974 sfrCCPool->pwrHiCCRange.startRb = 0;
975 sfrCCPool->pwrHiCCRange.endRb = 0;
978 sf->sfrTotalPoolInfo.CCRetx = FALSE;
979 sf->sfrTotalPoolInfo.CERetx = FALSE;
981 sf->sfrTotalPoolInfo.ccBwFull = FALSE;
982 sf->sfrTotalPoolInfo.ceBwFull = FALSE;
983 sf->sfrTotalPoolInfo.isUeCellEdge = FALSE;
987 * @brief This function resets temporary variables in RNTP Prepration
990 * Function: rgSchDSFRRntpInfoInit
992 * Invoked by: rgSCHSFRUtlTotalPoolInit
994 * @param[in] TknStrOSXL* rntpPtr
995 * @param[in] RgSubFrm* subFrm
1000 PUBLIC S16 rgSchDSFRRntpInfoInit
1002 TknStrOSXL *rntpPtr,
1007 PRIVATE Void rgSchDSFRRntpInfoInit(rntpPtr, cell, bw)
1008 TknStrOSXL *rntpPtr;
1013 Inst inst = cell->instIdx;
1016 TRC2(rgSchDSFRRntpInfoInit);
1018 rntpPtr->pres = PRSNT_NODEF;
1020 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1024 /* Allocate memory for "scheduled UE" Info */
1025 if((rgSCHUtlAllocSBuf(inst, (Data**)&(rntpPtr->val),
1026 (len * sizeof(U8)))) != ROK)
1028 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
1036 * @brief This function release RNTP pattern from slot and Cell
1039 * Function: rgSchDSFRRntpInfoFree
1041 * Invoked by: rgSCHSFRUtlTotalPoolInit
1043 * @param[in] TknStrOSXL* rntpPtr
1044 * @param[in] RgSubFrm* subFrm
1049 PUBLIC S16 rgSchDSFRRntpInfoFree
1051 TknStrOSXL *rntpPtr,
1056 PRIVATE Void rgSchDSFRRntpInfoFree(rntpPtr, cell, bw)
1057 TknStrOSXL *rntpPtr;
1062 Inst inst = cell->instIdx;
1065 TRC2(rgSchDSFRRntpInfoFree);
1067 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1069 if(rntpPtr->pres == PRSNT_NODEF)
1071 rgSCHUtlFreeSBuf(inst, (Data **)(&(rntpPtr->val)),(len * sizeof(U8)));
1072 rntpPtr->pres = NOTPRSNT;
1080 * @brief This function resets temporary variables in Pool
1083 * Function: rgSchSFRResetPoolVariables
1084 * Purpose: Initialise the dynamic variables in each pool.
1085 * Reset bwAlloced, bwAssigned, type2End, type0End, type2Start
1086 * Invoked by: rgSCHSFRUtlTotalPoolReset
1088 * @param[in] RgSchCellCb* cell
1089 * @param[in] RgSchSFRPoolInfo *pool
1094 PRIVATE Void rgSchSFRResetPoolVariables
1097 RgSchSFRPoolInfo *pool
1100 PRIVATE Void rgSchSFRResetPoolVariables(cell, pool)
1102 RgSchSFRPoolInfo *pool;
1106 TRC2(rgSchSFRResetPoolVariables);
1107 pool->bwAlloced = 0;
1109 /*type0end will be the last RBG in pool with all available RBs*/
1110 pool->type0End = (((pool->poolendRB + 1)/cell->rbgSize) - 1);
1112 /*type2end will be the first RBG in pool with all available RBs*/
1113 pool->type2End = RGSCH_CEIL(pool->poolstartRB, cell->rbgSize);
1114 pool->type2Start = pool->poolstartRB;
1115 pool->bw = pool->poolendRB - pool->poolstartRB + 1;
1120 * @brief This function resets SFR Pool information for frame
1124 * Function: rgSCHSFRUtlTotalPooReset
1125 * Purpose: Update the dynamic variables in each pool as they will be modified in each slot.
1126 * Dont modify the static variables like startRB, endRB, BW
1127 * Invoked by: rgSCHUtlSubFrmPut
1129 * @param[in] RgSchCellCb* cell
1130 * @param[in] RgSchDlSf* subFrm
1135 PRIVATE Void rgSCHSFRUtlTotalPoolReset
1141 PRIVATE Void rgSCHSFRUtlTotalPoolReset(cell, subFrm)
1146 RgSchSFRTotalPoolInfo *totalPoolInfo = &subFrm->sfrTotalPoolInfo;
1147 CmLListCp *ccPool = &totalPoolInfo->ccPool;
1148 CmLListCp *cePool = &totalPoolInfo->cePool;
1149 CmLList *node = NULLP;
1150 RgSchSFRPoolInfo *tempPool = NULLP;
1152 TRC2(rgSCHSFRUtlTotalPoolReset);
1154 totalPoolInfo->ccBwFull = FALSE;
1155 totalPoolInfo->ceBwFull = FALSE;
1156 totalPoolInfo->isUeCellEdge = FALSE;
1157 totalPoolInfo->CCPool1BwAvlbl = 0;
1158 totalPoolInfo->CCPool2BwAvlbl = 0;
1159 totalPoolInfo->CEPoolBwAvlbl = 0;
1160 totalPoolInfo->CCRetx = FALSE;
1161 totalPoolInfo->CERetx = FALSE;
1163 node = ccPool->first;
1166 tempPool = (RgSchSFRPoolInfo *)(node->node);
1168 rgSchSFRResetPoolVariables(cell, tempPool);
1169 if(tempPool->poolstartRB == 0)
1170 totalPoolInfo->CCPool1BwAvlbl = tempPool->bw;
1172 totalPoolInfo->CCPool2BwAvlbl = tempPool->bw;
1175 node = cePool->first;
1178 tempPool = (RgSchSFRPoolInfo *)(node->node);
1180 rgSchSFRResetPoolVariables(cell, tempPool);
1181 totalPoolInfo->CEPoolBwAvlbl = tempPool->bw;
1186 /* LTE_ADV_FLAG_REMOVED_END */
1188 * @brief This function appends PHICH information for frame
1192 * Function: rgSCHUtlAddPhich
1193 * Purpose: This function appends PHICH information for
1198 * @param[in] RgSchCellCb* cell
1199 * @param[in] RgSubFrm* subFrm
1200 * @param[in] U8 hqFeedBack
1201 * @param[in] U8 nDmrs
1202 * @param[in] U8 rbStart
1209 PUBLIC S16 rgSCHUtlAddPhich
1212 CmLteTimingInfo frm,
1219 PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, iPhich)
1221 CmLteTimingInfo frm;
1229 PUBLIC S16 rgSCHUtlAddPhich
1232 CmLteTimingInfo frm,
1239 PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, isForMsg3)
1241 CmLteTimingInfo frm;
1252 Inst inst = cell->instIdx;
1253 TRC2(rgSCHUtlAddPhich);
1255 dlSf = rgSCHUtlSubFrmGet(cell, frm);
1256 RGSCH_PHICH_ALLOC(inst, phich,sizeof(RgSchPhich), ret);
1260 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, " rgSCHUtlAddPhich(): "
1261 "Allocation of RgSchPhich failed");
1265 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, iPhich);
1267 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, isForMsg3); /*SR_RACH_STATS */
1269 cmLListAdd2Tail(&dlSf->phichInfo.phichs, &phich->lnk);
1271 } /* rgSCHUtlAddPhich */
1274 * @brief This function resets PHICH information for frame
1278 * Function: rgSCHUtlPhichReset
1279 * Purpose: This function initializes PHICH information for
1280 * a slot. It removes the list of PHICHs allocated
1281 * in the prior use of this slot structure.
1283 * Invoked by: rgSCHUtlSubFrmPut
1285 * @param[in] RgSchCellCb* cell
1286 * @param[in] RgSubFrm* subFrm
1291 PRIVATE Void rgSCHUtlPhichReset
1297 PRIVATE Void rgSCHUtlPhichReset(cell, subFrm)
1302 RgSchPhichInfo *phichInfo;
1307 TRC2(rgSCHUtlPhichReset);
1309 phichInfo = &subFrm->phichInfo;
1310 while(phichInfo->phichs.first != NULLP)
1312 phich = (RgSchPhich *)phichInfo->phichs.first->node;
1313 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
1314 RGSCH_PHICH_FREE(cell->instIdx, phich, sizeof(RgSchPhich));
1316 cmLListInit(&phichInfo->phichs);
1318 } /* rgSCHUtlPhichReset */
1322 * @brief This function returns slot data structure for a cell
1326 * Function: rgSCHUtlSubFrmGet
1327 * Purpose: This function resets the slot data structure
1328 * when the slot is released
1330 * Invoked by: scheduler
1332 * @param[in] RgSubFrm subFrm
1337 PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet
1343 PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet(cell, frm)
1345 CmLteTimingInfo frm;
1351 TRC2(rgSCHUtlSubFrmGet);
1354 dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
1355 //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1356 sf = cell->subFrms[dlIdx];
1358 /* Changing the idexing
1359 so that proper slot is selected */
1360 dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
1361 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1362 sf = cell->subFrms[dlIdx];
1372 * @brief This function returns slot data structure for a cell
1376 * Function: rgSCHUtlSubFrmPut
1377 * Purpose: This function resets the slot data structure
1378 * when the slot is released
1380 * Invoked by: scheduler
1382 * @param[in] RgSubFrm subFrm
1387 PUBLIC Void rgSCHUtlSubFrmPut
1393 PUBLIC Void rgSCHUtlSubFrmPut(cell, sf)
1401 TRC2(rgSCHUtlSubFrmPut);
1404 /* Release all the held PDCCH information */
1405 rgSCHUtlPdcchInit(cell, sf, sf->nCce);
1407 /* Release all the held PDCCH information */
1408 rgSCHUtlPdcchInit(cell, sf, cell->nCce);
1410 rgSCHUtlPhichReset(cell, sf);
1412 /* Reset the bw allocated. */
1415 /* Setting allocated bandwidth to SPS bandwidth for non-SPS RB allocator */
1416 sf->bwAlloced = ((cell->spsCellCfg.maxSpsDlBw +
1417 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
1418 if (sf->bwAlloced > sf->bw)
1420 sf->bwAlloced = sf->bw;
1422 sf->spsAllocdBw = 0;
1423 sf->type2Start = sf->bwAlloced;
1424 cmMemset((U8*) &sf->dlSfAllocInfo, 0, sizeof(RgSchDlSfAllocInfo));
1427 /* Fix for ccpu00123918*/
1429 /* LTE_ADV_FLAG_REMOVED_START */
1430 /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
1431 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
1433 cmMemset((U8*) sf->rntpInfo.val, 0, sf->rntpInfo.len);
1435 /* LTE_ADV_FLAG_REMOVED_END */
1438 /*[ccpu00138609]-ADD-Reset the CCCH UE counter */
1441 /* Non DLFS scheduling using Type0 RA requires the following
1442 * parameter's tracking */
1443 /* Type 2 localized allocations start from 0th RBG and onwards */
1444 /* Type 0 allocations start from last RBG and backwards*/
1448 sf->type2End = RGSCH_CEIL(sf->bwAlloced,cell->rbgSize);
1450 sf->type0End = cell->noOfRbgs - 1;
1451 /* If last RBG is of incomplete size then special handling */
1452 (sf->bw % cell->rbgSize == 0)? (sf->lstRbgDfct = 0) :
1453 (sf->lstRbgDfct = cell->rbgSize - (sf->bw % cell->rbgSize));
1454 /* This resets the allocation for BCCH and PDCCH */
1456 /* TODO we need to move this reset for emtc functions */
1457 if(!(cell->emtcEnable))
1466 sf->bcch.pdcch = NULLP;
1467 sf->pcch.pdcch = NULLP;
1469 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
1471 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
1473 for (i = 0; i < noRaRsps; i++)
1475 sf->raRsp[i].pdcch = NULLP;
1476 cmLListInit(&(sf->raRsp[i].raRspLst));
1478 /* LTE_ADV_FLAG_REMOVED_START */
1479 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
1481 rgSCHSFRUtlTotalPoolReset(cell, sf);
1483 /* LTE_ADV_FLAG_REMOVED_END */
1485 cmLListInit(&sf->n1PucchResLst);
1489 sf->isCceFailure = FALSE;
1490 sf->dlUlBothCmplt = 0;
1496 * @brief This function computes log N (32 bit Unsigned) to the base 2
1500 * Function: rgSCHUtlLog32bitNbase2
1501 * Purpose: This function computes log N (32 bit Unsigned) to the base 2.
1502 * For n= 0,1 ret = 0.
1504 * Invoked by: Scheduler
1511 PUBLIC U8 rgSCHUtlLog32bitNbase2
1516 PUBLIC U8 rgSCHUtlLog32bitNbase2(n)
1520 U32 b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
1521 U32 s[] = {1, 2, 4, 8, 16};
1525 TRC2(rgSCHUtlLog32bitNbase2)
1527 for (i=4; i >= 0; i--)
1541 * @brief This function is a wrapper to call scheduler specific API.
1545 * Function: rgSCHUtlDlRelPdcchFbk
1546 * Purpose: Calls scheduler's handler for SPS release PDCCH feedback
1551 * @param[in] RgSchCellCb *cell
1552 * @param[in] RgSchUeCb *ue
1553 * @param[in] U8 isAck
1558 PUBLIC Void rgSCHUtlDlRelPdcchFbk
1565 PUBLIC Void rgSCHUtlDlRelPdcchFbk(cell, ue, isAck)
1571 TRC2(rgSCHUtlDlRelPdcchFbk);
1572 cell->sc.apis->rgSCHDlRelPdcchFbk(cell, ue, isAck);
1579 * @brief This function is a wrapper to call scheduler specific API.
1583 * Function: rgSCHUtlDlProcAck
1584 * Purpose: Calls scheduler's handler to process Ack
1589 * @param[in] RgSchCellCb *cell
1590 * @param[in] RgSchDlHqProcCb *hqP
1595 PUBLIC Void rgSCHUtlDlProcAck
1598 RgSchDlHqProcCb *hqP
1601 PUBLIC Void rgSCHUtlDlProcAck(cell, hqP)
1603 RgSchDlHqProcCb *hqP;
1606 TRC2(rgSCHUtlDlProcAck);
1607 cell->sc.apis->rgSCHDlProcAck(cell, hqP);
1612 * @brief CRNTI CE Handler
1616 * Function : rgSCHUtlHdlCrntiCE
1618 * - Call scheduler common API
1621 * @param[in] RgSchCellCb *cell
1622 * @param[in] RgSchUeCb *ue
1623 * @param[out] RgSchErrInfo *err
1627 PUBLIC Void rgSCHUtlHdlCrntiCE
1633 PUBLIC Void rgSCHUtlHdlCrntiCE(cell, ue)
1638 TRC2(rgSCHUtlHdlCrntiCE);
1640 cell->sc.apis->rgSCHHdlCrntiCE(cell, ue);
1642 } /* rgSCHUtlHdlCrntiCE */
1643 #endif /* LTEMAC_SPS */
1645 /***********************************************************
1647 * Func : rgSCHUtlCalcTotalRegs
1649 * Desc : Calculate total REGs, given a bandwidth, CFI
1650 * and number of antennas.
1652 * Ret : Total REGs (U16)
1654 * Notes: Could optimise if bw values are limited
1655 * (taken from RRC spec) by indexing values from
1657 * Input values are not validated. CFI is assumed
1662 **********************************************************/
1664 PRIVATE U16 rgSCHUtlCalcTotalRegs
1672 PRIVATE U16 rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp)
1680 TRC2(rgSCHUtlCalcTotalRegs);
1682 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1688 /* Refer 36.211 section 6.10.1.2
1689 * For symbols 2 and 4, the REGs per RB will be based on cyclic prefix
1690 * and number of antenna ports.
1691 * For symbol 1, there are 2 REGs per RB always. Similarly symbol 3
1695 /*CR changes [ccpu00124416] - MOD*/
1698 regs = bw * RGSCH_NUM_REGS_4TH_SYM_EXT_CP;
1702 regs = bw * RGSCH_NUM_REGS_4TH_SYM_NOR_CP;
1705 regs += bw * RGSCH_NUM_REGS_3RD_SYM;
1707 /*CR changes [ccpu00124416] - MOD using number of antenna ports*/
1708 regs += (numAntna == RGSCH_NUM_ANT_PORT_FOUR) ? \
1709 (bw * RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT) : \
1710 (bw * RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT);
1711 default: /* case 1 */
1712 regs += bw * RGSCH_NUM_REGS_1ST_SYM;
1717 /***********************************************************
1719 * Func : rgSCHUtlCalcPhichRegs
1721 * Desc : Calculates number of PHICH REGs
1723 * Ret : Number of PHICH REGs (U8)
1725 * Notes: ng6 is Ng multiplied by 6
1729 **********************************************************/
1731 PRIVATE U16 rgSCHUtlCalcPhichRegs
1737 PRIVATE U16 rgSCHUtlCalcPhichRegs(bw, ng6)
1742 TRC2(rgSCHUtlCalcPhichRegs);
1743 /* ccpu00115330: Corrected the calculation for number of PHICH groups*/
1744 RETVALUE(RGSCH_CEIL((bw * ng6) ,(8 * 6)) * RGSCH_NUM_REG_PER_PHICH_GRP);
1749 * @brief Calculates total CCEs (N_cce)
1753 * Function: rgSCHUtlCalcNCce
1754 * Purpose: This function calculates and returns total CCEs for a
1755 * cell, given the following: bandwidth, Ng configuration
1756 * (multiplied by six), cfi (actual number of control
1757 * symbols), m factor for PHICH and number of antennas.
1759 * Invoked by: Scheduler
1764 * @param[in] U8 mPhich
1765 * @param[in] U8 numAntna
1766 * @param[in] Bool isEcp
1767 * @return N_cce (U8)
1771 PUBLIC U8 rgSCHUtlCalcNCce
1781 PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, mPhich, numAntna, isEcp)
1794 TRC2(rgSCHUtlCalcNCce);
1796 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1800 case RGR_NG_ONESIXTH:
1815 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1816 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1817 cceRegs = totalRegs - mPhich*phichRegs - RGSCH_NUM_PCFICH_REG;
1819 RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1824 * @brief Calculates total CCEs (N_cce)
1828 * Function: rgSCHUtlCalcNCce
1829 * Purpose: This function calculates and returns total CCEs for a
1830 * cell, given the following: bandwidth, Ng configuration
1831 * (multiplied by six), cfi (actual number of control
1832 * symbols) and number of antennas.
1834 * Invoked by: Scheduler
1839 * @param[in] U8 numAntna
1840 * @return N_cce (U8)
1844 PUBLIC U8 rgSCHUtlCalcNCce
1853 PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, numAntna, isEcp)
1865 TRC2(rgSCHUtlCalcNCce);
1867 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1871 case RGR_NG_ONESIXTH:
1886 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1887 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1888 cceRegs = totalRegs - phichRegs - RGSCH_NUM_PCFICH_REG;
1890 RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1895 * @brief Returns PHICH info associated with an uplink
1896 * HARQ process allocation
1900 * Function: rgSCHUtlGetPhichInfo
1901 * Purpose: This function returns PHICH info associated with
1902 * an uplink HARQ process allocation. PHICH info
1903 * comprises RB start and N_dmrs.
1905 * @param[in] RgSchUlHqProcCb *hqProc
1906 * @param[out] U8 *rbStartRef
1907 * @param[out] U8 *nDmrsRef
1912 PUBLIC S16 rgSCHUtlGetPhichInfo
1914 RgSchUlHqProcCb *hqProc,
1920 PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef, iPhich)
1921 RgSchUlHqProcCb *hqProc;
1928 PUBLIC S16 rgSCHUtlGetPhichInfo
1930 RgSchUlHqProcCb *hqProc,
1935 PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef)
1936 RgSchUlHqProcCb *hqProc;
1945 TRC2(rgSCHUtlGetPhichInfo);
1947 if ((hqProc != NULLP) && (hqProc->alloc != NULLP))
1949 *rbStartRef = hqProc->alloc->grnt.rbStart;
1950 *nDmrsRef = hqProc->alloc->grnt.nDmrs;
1952 *iPhich = hqProc->iPhich;
1960 * @brief Returns uplink grant information required to permit
1961 * PHY to receive data
1965 * Function: rgSCHUtlAllocRcptInfo
1966 * Purpose: Given an uplink allocation, this function returns
1967 * uplink grant information which is needed by PHY to
1968 * decode data sent from UE. This information includes:
1973 * @param[in] RgSchUlAlloc *alloc
1974 * @param[out] U8 *rbStartRef
1975 * @param[out] U8 *numRbRef
1976 * @param[out] U8 *rvRef
1977 * @param[out] U16 *size
1978 * @param[out] TfuModScheme *modType
1979 * @param[out] Bool *isRtx
1980 * @param[out] U8 *nDmrs
1981 * @param[out] Bool *ndi
1982 * @param[out] U8 *hqPId
1986 PUBLIC S16 rgSCHUtlAllocRcptInfo
1988 RgSchUlAlloc *alloc,
1995 TfuModScheme *modType,
2002 PUBLIC S16 rgSCHUtlAllocRcptInfo(alloc, rnti, iMcsRef, rbStartRef, numRbRef,
2003 rvRef, size, modType, isRtx, nDmrs, ndi,
2005 RgSchUlAlloc *alloc;
2012 TfuModScheme *modType;
2019 /* Modulation order for 16qam UEs would be
2020 * min(4,modulation order in grant). Please refer to 36.213-8.6.1*/
2021 CmLteUeCategory ueCtgy;
2023 TRC2(rgSCHUtlAllocRcptInfo);
2024 #if (ERRCLASS & ERRCLS_DEBUG)
2025 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2031 if ( !alloc->forMsg3 )
2033 if ( ((alloc->ue) == NULLP) || (RG_SCH_CMN_GET_UE(alloc->ue, alloc->ue->cell) == NULLP))
2035 RLOG_ARG2(L_ERROR,DBG_CELLID,alloc->ue->cell->cellId,
2036 "Failed: ue->sch is null RNTI:%d,isRetx=%d",
2037 alloc->rnti, alloc->grnt.isRtx);
2040 ueCtgy = (RG_SCH_CMN_GET_UE_CTGY(alloc->ue));
2043 *iMcsRef = alloc->grnt.iMcs;
2044 *rbStartRef = alloc->grnt.rbStart;
2045 *numRbRef = alloc->grnt.numRb;
2046 *rvRef = rgRvTable[alloc->hqProc->rvIdx];
2047 *rnti = alloc->rnti;
2048 *size = alloc->grnt.datSz;
2049 *modType = (alloc->forMsg3)? alloc->grnt.modOdr:
2050 ((ueCtgy == CM_LTE_UE_CAT_5)?
2052 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)));
2053 *isRtx = alloc->grnt.isRtx;
2054 *nDmrs = alloc->grnt.nDmrs;
2055 *ndi = alloc->hqProc->ndi;
2056 *hqPId = alloc->hqProc->procId;
2062 * @brief Returns uplink grant information required to permit
2063 * PHY to receive data
2067 * Function: rgSCHUtlAllocRcptInfo
2068 * Purpose: Given an uplink allocation, this function returns
2069 * uplink grant information which is needed by PHY to
2070 * decode data sent from UE. This information includes:
2075 * @param[in] RgSchUlAlloc *alloc
2076 * @param[out] U8 *rbStartRef
2077 * @param[out] U8 *numRbRef
2078 * @param[out] U8 *rvRef
2079 * @param[out] U16 *size
2080 * @param[out] TfuModScheme *modType
2084 PUBLIC S16 rgSCHUtlAllocRcptInfo
2087 RgSchUlAlloc *alloc,
2088 CmLteTimingInfo *timeInfo,
2089 TfuUeUlSchRecpInfo *recpReq
2092 PUBLIC S16 rgSCHUtlAllocRcptInfo(cell, alloc, timeInfo, recpReq)
2094 RgSchUlAlloc *alloc;
2095 CmLteTimingInfo *timeInfo;
2096 TfuUeUlSchRecpInfo *recpReq;
2099 TRC2(rgSCHUtlAllocRcptInfo);
2100 #if (ERRCLASS & ERRCLS_DEBUG)
2101 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2106 recpReq->size = alloc->grnt.datSz;
2107 recpReq->rbStart = alloc->grnt.rbStart;
2108 recpReq->numRb = alloc->grnt.numRb;
2109 /* Modulation order min(4,mod in grant) for 16 qam UEs.
2110 * Please refer to 36.213-8.6.1*/
2111 #ifdef FOUR_TX_ANTENNA
2112 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2113 (/*(alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2114 alloc->grnt.modOdr: *//* Chandra:TmpFx-TM500 Cat5 with Only16QAM */
2115 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2117 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2118 ((alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2120 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2122 recpReq->nDmrs = alloc->grnt.nDmrs;
2123 recpReq->hoppingEnbld = FALSE;
2124 recpReq->hoppingBits = 0;
2125 recpReq->isRtx = alloc->grnt.isRtx;
2126 recpReq->ndi = alloc->hqProc->ndi;
2127 recpReq->rv = rgRvTable[alloc->hqProc->rvIdx];
2129 recpReq->harqProcId = alloc->hqProc->procId;
2131 recpReq->harqProcId = rgSCHCmnGetUlHqProcIdx(timeInfo, cell);
2133 /* Transmission mode is SISO till Uplink MIMO is implemented. */
2134 recpReq->txMode = 0;
2135 /* This value needs to filled in in the case of frequency hopping. */
2136 recpReq->crntTxNb = 0;
2138 recpReq->mcs = alloc->grnt.iMcs;
2140 recpReq->rbgStart = alloc->grnt.vrbgStart;
2141 recpReq->numRbg = alloc->grnt.numVrbg;
2142 recpReq->xPUSCHRange = alloc->grnt.xPUSCHRange;
2143 //TODO_SID Need to check
2144 recpReq->nAntPortLayer = 0;
2145 recpReq->SCID = alloc->grnt.SCID;
2146 recpReq->PMI = alloc->grnt.PMI;
2147 recpReq->uciWoTBFlag = alloc->grnt.uciOnxPUSCH;
2150 recpReq->beamIndex = alloc->ue->ue5gtfCb.BeamId;
2155 if (!alloc->forMsg3)
2157 if (alloc->grnt.isRtx)
2159 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulRetxOccns++;
2163 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulTxOccns++;
2164 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulSumiTbs += \
2165 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2166 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulNumiTbs ++;
2167 cell->tenbStats->sch.ulSumiTbs += \
2168 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2169 cell->tenbStats->sch.ulNumiTbs ++;
2171 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulPrbUsg += alloc->grnt.numRb;
2172 cell->tenbStats->sch.ulPrbUsage[0] += alloc->grnt.numRb;
2175 /* ccpu00117050 - DEL - nSrs setting at rgSCHUtlAllocRcptInfo */
2182 * @brief This function initialises the PRACH slot occasions
2186 * Function: rgSCHUtlUpdPrachOcc
2187 * Purpose: This function updates the PRACH slots based on
2188 * RGR configuration.
2190 * Invoked by: Scheduler
2192 * @param[in] RgSchCellCb *cell
2193 * @param[in] RgrTddPrachInfo *cellCfg
2198 PRIVATE Void rgSCHUtlUpdPrachOcc
2201 RgrTddPrachInfo *cellCfg
2204 PRIVATE Void rgSCHUtlUpdPrachOcc(cell, cellCfg)
2206 RgrTddPrachInfo *cellCfg;
2215 TRC2(rgSCHUtlUpdPrachOcc)
2217 /* In the 1st half frame */
2218 if(cellCfg->halfFrm == 0)
2223 /* In the 2nd half frame */
2229 for(idx = startIdx; idx < endIdx; idx++)
2231 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
2232 == RG_SCH_TDD_UL_slot)
2234 if(cellCfg->ulStartSfIdx == count)
2236 size = cell->rachCfg.raOccasion.size;
2237 cell->rachCfg.raOccasion.slotNum[size] = idx;
2238 cell->rachCfg.raOccasion.size++;
2248 * @brief This function initialises the PRACH occasions
2252 * Function: rgSCHUtlPrachCfgInit
2253 * Purpose: This function initialises the PRACH occasions based on
2254 * RGR configuration.
2256 * Invoked by: Scheduler
2258 * @param[in] RgSchCellCb *cell
2259 * @param[in] RgrCellCfg *cellCfg
2264 PUBLIC Void rgSCHUtlPrachCfgInit
2270 PUBLIC Void rgSCHUtlPrachCfgInit(cell, cellCfg)
2272 RgrCellCfg *cellCfg;
2279 TRC2(rgSCHUtlPrachCfgInit)
2280 if(cellCfg->prachRscInfo.numRsc <= 0)
2282 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid"
2283 "PRACH resources Configuration ");
2287 /* Update SFN occasions */
2288 cell->rachCfg.raOccasion.sfnEnum =
2289 cellCfg->prachRscInfo.prachInfo[0].sfn;
2291 cell->rachCfg.raOccasion.size = 0;
2293 /* Update slot occasions */
2294 for(idx = 0; idx < cellCfg->prachRscInfo.numRsc; idx++)
2296 if(cellCfg->prachRscInfo.prachInfo[idx].freqIdx == 0)
2298 if(cellCfg->prachRscInfo.prachInfo[idx].halfFrm == 0)
2306 if(cellCfg->prachRscInfo.prachInfo[idx].ulStartSfIdx ==
2309 subfrmIdx = cell->rachCfg.raOccasion.size;
2310 cell->rachCfg.raOccasion.slotNum[subfrmIdx] = splFrm;
2311 cell->rachCfg.raOccasion.size++;
2315 rgSCHUtlUpdPrachOcc(cell,
2316 &cellCfg->prachRscInfo.prachInfo[idx]);
2324 * @brief This function performs RGR cell initialization
2328 * Function: rgSCHUtlRgrCellCfg
2329 * Purpose: This function initialises the cell with RGR configuration
2330 * and slot related initialization.
2332 * Invoked by: Scheduler
2334 * @param[in] RgSchCellCb *cell
2335 * @param[in] RgrCellCfg *cellCfg
2336 * @param[in] RgSchErrInfo *errInfo
2341 PUBLIC S16 rgSCHUtlRgrCellCfg
2344 RgrCellCfg *cellCfg,
2345 RgSchErrInfo *errInfo
2348 PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2350 RgrCellCfg *cellCfg;
2351 RgSchErrInfo *errInfo;
2358 CmLteTimingInfo frm;
2359 U8 ulDlCfgIdx = cellCfg->ulDlCfgIdx;
2363 U16 bw; /*!< Number of RBs in the cell */
2365 TRC2(rgSCHUtlRgrCellCfg);
2367 cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo));
2369 /* ccpu00132657-MOD- Determining DLSF array size independent of DELTAS */
2370 maxDlslots = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
2371 maxslots = 2 * maxDlslots;
2372 cell->numDlSubfrms = maxslots;
2373 /* ACC-TDD <ccpu00130639> */
2374 cell->tddHqSfnCycle = -1;
2375 cell->ulDlCfgIdx = ulDlCfgIdx;
2377 /* PRACH Occasions Initialization */
2378 rgSCHUtlPrachCfgInit(cell, cellCfg);
2380 /* ccpu00132658- Moved out of below for loop since the updating rbgSize and
2381 * bw are independent of sfNum*/
2382 /* determine the RBG size and no of RBGs for the configured
2384 if (cell->bwCfg.dlTotalBw > 63)
2388 else if (cell->bwCfg.dlTotalBw > 26)
2392 else if (cell->bwCfg.dlTotalBw > 10)
2400 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2402 bw = cell->bwCfg.dlTotalBw;
2404 rgSCHUtlAllocSBuf(cell->instIdx,
2405 (Data **)&cell->subFrms, sizeof(RgSchDlSf *) * maxslots);
2406 if (cell->subFrms == NULLP)
2411 /* Create memory for each frame. */
2412 for(i = 0; i < maxslots; i++)
2414 while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
2417 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2420 rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf, sizeof(RgSchDlSf));
2425 cmMemset((U8 *)sf, 0, sizeof(*sf));
2428 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2436 /* Mark SPS bandwidth to be occupied */
2437 sf->bwAlloced = ((cellCfg->spsCfg.maxSpsDlBw +
2438 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
2439 sf->spsAllocdBw = 0;
2440 sf->type2End = sf->bwAlloced/cell->rbgSize;
2443 /* Fix for ccpu00123918*/
2445 #endif /* LTEMAC_SPS */
2446 /* Initialize the ackNakRepQ here */
2447 #ifdef RG_MAC_MEASGAP
2448 cmLListInit (&(sf->ackNakRepQ));
2450 cell->subFrms[i] = sf;
2451 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2457 /* ccpu00117052 - MOD - Passing double pointer
2458 for proper NULLP assignment*/
2459 rgSCHUtlFreeSBuf(cell->instIdx,
2460 (Data **)(&(cell->subFrms[i-1])), sizeof(RgSchDlSf));
2462 rgSCHLaaDeInitDlSfCb(cell, sf);
2465 /* ccpu00117052 - MOD - Passing double pointer
2466 for proper NULLP assignment*/
2467 rgSCHUtlFreeSBuf(cell->instIdx,
2468 (Data **)(&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2473 if (cell->sc.apis == NULLP)
2475 cell->sc.apis = &rgSchCmnApis;
2477 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2481 /* ccpu00132286- Removed deletion of sf nodes as the deletion will be
2482 * happening during CellDelete. Added return handling to provide negative
2487 /* Release the slots and thereby perform the initialization */
2488 for (i = 0; i < maxslots; i++)
2490 if((i > 0) && (i%maxDlslots == 0))
2495 frm.slot = cell->subFrms[i]->sfNum;
2496 rgSCHUtlDlRlsSubFrm(cell, frm);
2505 * @brief This function performs scheduler related cell creation
2509 * Function: rgSCHUtlRgrCellCfg
2510 * Purpose: This function creates the slots needed for the
2511 * cell. It then peforms init of the scheduler by calling
2512 * scheduler specific cell init function.
2514 * Invoked by: Scheduler
2516 * @param[in] RgSchCellCb *cell
2517 * @param[in] RgrCellCfg *cellCfg
2518 * @param[in] RgSchErrInfo *errInfo
2523 PUBLIC S16 rgSCHUtlRgrCellCfg
2526 RgrCellCfg *cellCfg,
2527 RgSchErrInfo *errInfo
2530 PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2532 RgrCellCfg *cellCfg;
2533 RgSchErrInfo *errInfo;
2538 CmLteTimingInfo frm;
2540 Inst inst = cell->instIdx;
2541 /* LTE_ADV_FLAG_REMOVED_START */
2543 len = (U16)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /*KW fix for LTE_ADV */
2544 /* LTE_ADV_FLAG_REMOVED_END */
2545 TRC2(rgSCHUtlRgrCellCfg);
2547 cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo));
2549 /* determine the RBG size and no of RBGs for the configured
2551 if (cell->bwCfg.dlTotalBw > 63)
2555 else if (cell->bwCfg.dlTotalBw > 26)
2559 else if (cell->bwCfg.dlTotalBw > 10)
2567 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2568 /* Create memory for each frame. */
2569 /* Changing loop limit from
2570 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2571 for(i = 0; i < RGSCH_NUM_DL_slotS; i++)
2573 rgSCHUtlAllocSBuf(inst, (Data **)&sf, sizeof(RgSchDlSf));
2578 cmMemset((U8 *)sf, 0, sizeof(*sf));
2581 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2586 /* Doing MOD operation before assigning value of i */
2587 sf->sfNum = i % RGSCH_NUM_SUB_FRAMES;
2588 sf->bw = cell->bwCfg.dlTotalBw;
2589 /* Initialize the ackNakRepQ here */
2590 #ifdef RG_MAC_MEASGAP
2591 cmLListInit (&(sf->ackNakRepQ));
2593 cell->subFrms[i] = sf;
2594 /* LTE_ADV_FLAG_REMOVED_START */
2595 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2597 /*initialize the RNTP Buffer*/
2598 if(rgSchDSFRRntpInfoInit(&sf->rntpInfo, cell, sf->bw))
2604 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
2606 /*initialise the pools of CC and CE*/
2607 if(rgSchSFRTotalPoolInit(cell, sf))
2612 /* LTE_ADV_FLAG_REMOVED_END */
2615 /* LTE_ADV_FLAG_REMOVED_START */
2616 /* Allocate memory for "scheduled UE" Info */
2617 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2619 if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val),
2620 (len * sizeof(U8)))) != ROK)
2622 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
2625 cell->rntpAggrInfo.pres = PRSNT_NODEF;
2626 cell->rntpAggrInfo.len = len;
2628 /* LTE_ADV_FLAG_REMOVED_END */
2630 /* Changing loop limit from
2631 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2632 if (i != RGSCH_NUM_DL_slotS)
2636 /* ccpu00117052 - MOD - Passing double pointer
2637 for proper NULLP assignment*/
2638 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i-1])),
2641 rgSCHLaaDeInitDlSfCb(cell, sf);
2647 if (cell->sc.apis == NULLP)
2649 cell->sc.apis = &rgSchCmnApis;
2652 /* Release the slots and thereby perform the initialization */
2653 for (i = 0; i < RGSCH_NUM_DL_slotS; i++)
2655 if (i >= RGSCH_NUM_SUB_FRAMES)
2657 /* [ccpu00123828]-MOD-The below statement sfn += 1incorrectly modified
2658 * the value of sfn for i>=10 thru 19. Correct way is to assign
2662 frm.slot = i % RGSCH_NUM_SUB_FRAMES;
2663 rgSCHUtlDlRlsSubFrm(cell, frm);
2666 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2669 errInfo->errCause = RGSCHERR_SCH_CFG;
2673 if(cell->emtcEnable)
2675 /* TODO: Repetition framework in RGR and APP */
2676 if (rgSCHUtlEmtcResMngmtInit(
2678 RGSCH_IOT_PDSCH_POOLSZ, RGSCH_IOT_PDSCH_DELTA, cellCfg->bwCfg.dlTotalBw,
2679 RGSCH_IOT_PUSCH_POOLSZ, RGSCH_IOT_PUSCH_DELTA, RGSCH_IOT_PUSCH_MAXFREQSZ,
2680 RGSCH_IOT_PUCCH_POOLSZ, RGSCH_IOT_PUCCH_DELTA, RGSCH_IOT_PUCCH_MAXFREQSZ) != ROK)
2682 errInfo->errCause = RGSCHERR_SCH_CFG;
2694 * @brief This function performs the cell reconfiguration at RGR interface
2698 * Function: rgSCHUtlRgrCellRecfg
2699 * Purpose: This function updates the reconfigurable parameters
2700 * on the cell control block for the scheduler.
2702 * Invoked by: Scheduler
2704 * @param[in] RgSchCellCb *cell
2705 * @param[in] RgrCellCfg *cellCfg
2706 * @param[in] RgSchErrInfo *errInfo
2711 PUBLIC S16 rgSCHUtlRgrCellRecfg
2714 RgrCellRecfg *recfg,
2718 PUBLIC S16 rgSCHUtlRgrCellRecfg(cell, recfg, err)
2720 RgrCellRecfg *recfg;
2724 TRC2(rgSCHUtlRgrCellRecfg);
2725 RETVALUE(cell->sc.apis->rgSCHRgrCellRecfg(cell, recfg, err));
2731 * @brief This function returns the Y value of UE for a sub frame
2735 * Function: rgSCHUtlFreeCell
2736 * Purpose: This function updates the value of Y stored in the
2737 * UE control block. It uses the previously computed
2738 * value for computing for this slot.
2740 * Invoked by: Scheduler
2742 * @param[in] RgSchCellCb *cell
2747 PUBLIC S16 rgSCHUtlFreeCell
2752 PUBLIC S16 rgSCHUtlFreeCell(cell)
2759 RgSchPdcchInfo *pdcchInfo;
2760 RgSchPhichInfo *phichInfo;
2762 Inst inst = cell->instIdx;
2765 RgSchRaReqInfo *raReqInfo;
2768 TRC2(rgSCHUtlFreeCell);
2771 maxslots = cell->numDlSubfrms;
2773 maxslots = RGSCH_NUM_DL_slotS;
2777 /* Invoke the index for scheduler, cell deletion */
2778 cell->sc.apis->rgSCHFreeCell(cell);
2780 /* Release the slots allocated */
2781 for (i = 0; i < maxslots; i++)
2784 rgSCHLaaDeInitDlSfCb(cell, cell->subFrms[i]);
2786 pdcchInfo = &cell->subFrms[i]->pdcchInfo;
2787 /* ccpu00117052 - MOD - Passing double pointer
2788 for proper NULLP assignment*/
2789 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)),
2790 (pdcchInfo->nCce + 7) >> 3);
2791 while (pdcchInfo->pdcchs.first != NULLP)
2793 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
2794 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
2795 /* ccpu00117052 - MOD - Passing double pointer
2796 for proper NULLP assignment*/
2797 rgSCHUtlFreeSBuf(inst, (Data **)&pdcch, sizeof(RgSchPdcch));
2800 phichInfo = &cell->subFrms[i]->phichInfo;
2801 while(phichInfo->phichs.first != NULLP)
2803 phich = (RgSchPhich *)phichInfo->phichs.first->node;
2804 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
2805 RGSCH_PHICH_FREE(inst, phich, sizeof(RgSchPhich));
2808 /* LTE_ADV_FLAG_REMOVED_START */
2809 /*releasing SFR pool entries*/
2810 rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell);
2812 /*releasing dsfr rntp pattern info*/
2813 rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell,
2814 cell->bwCfg.dlTotalBw);
2815 /* LTE_ADV_FLAG_REMOVED_END */
2817 /* ccpu00117052 - MOD - Passing double pointer
2818 for proper NULLP assignment*/
2819 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i])), sizeof(RgSchDlSf));
2822 /* Release the slot pointers */
2823 /* ccpu00117052 - MOD - Passing double pointer
2824 for proper NULLP assignment*/
2825 rgSCHUtlFreeSBuf(inst,
2826 (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2828 for(idx=0; idx < cell->raInfo.lstSize; idx++)
2830 lst = &cell->raInfo.raReqLst[idx];
2831 while (lst->first != NULLP)
2833 raReqInfo = (RgSchRaReqInfo *)lst->first->node;
2834 cmLListDelFrm(lst, &raReqInfo->raReqLstEnt);
2835 /* ccpu00117052 - MOD - Passing double pointer
2836 for proper NULLP assignment*/
2837 rgSCHUtlFreeSBuf(inst,(Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
2840 /* ccpu00117052 - MOD - Passing double pointer
2841 for proper NULLP assignment*/
2842 rgSCHUtlFreeSBuf(inst,
2843 (Data **)(&(cell->raInfo.raReqLst)),
2844 sizeof(CmLListCp) * (cell->raInfo.lstSize));
2847 /* Release allocated pdcchs */
2848 lst = &cell->pdcchLst;
2849 while (lst->first != NULLP)
2851 pdcch = (RgSchPdcch *)lst->first->node;
2852 cmLListDelFrm(lst, &pdcch->lnk);
2854 if(cell->emtcEnable)
2856 rgSCHEmtcPdcchFree(cell, pdcch);
2857 rgSCHUtlEmtcResMngmtDeinit(cell);
2860 /* ccpu00117052 - MOD - Passing double pointer
2861 for proper NULLP assignment*/
2862 rgSCHUtlFreeSBuf(inst,(Data **)&pdcch, sizeof(RgSchPdcch));
2865 rgSCHLaaFreeLists(cell);
2868 /* LTE_ADV_FLAG_REMOVED_START */
2869 /* releasing RNTP Aggregation Info from CellCb*/
2870 rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw);
2871 /* LTE_ADV_FLAG_REMOVED_END */
2878 * @brief This function adds the UE to scheduler
2882 * Function: rgSCHUtlRgrUeCfg
2883 * Purpose: This function performs addition of UE to scheduler
2884 * 1. First, it updates the Y table in the UE
2885 * 2. Then, it calls the scheduler's handler for UE addition
2887 * Invoked by: Scheduler
2889 * @param[in] RgSchCellCb *cell
2890 * @param[in] RgSchUeCb *ue
2891 * @param[in] RgrUeCfg *cfg
2892 * @param[in] RgSchErrInfo *err
2897 PUBLIC S16 rgSCHUtlRgrUeCfg
2905 PUBLIC S16 rgSCHUtlRgrUeCfg(cell, ue, cfg, err)
2912 TRC2(rgSCHUtlRgrUeCfg);
2914 /* Assign TM 1 as UE's default TM */
2915 ue->mimoInfo.txMode = RGR_UE_TM_1;
2916 ue->txModeTransCmplt = TRUE;
2917 cmInitTimers(&ue->txModeTransTmr, 1);
2918 if (cfg->txMode.pres == PRSNT_NODEF)
2920 /* DL MU-MIMO not supported */
2921 if (cfg->txMode.txModeEnum == RGR_UE_TM_5)
2923 err->errCause = RGSCHERR_SCH_CFG;
2926 ue->mimoInfo.txMode = cfg->txMode.txModeEnum;
2928 ue->ul.ulTxAntSel = cfg->ulTxAntSel;
2929 ue->mimoInfo.cdbkSbstRstrctn = cfg->ueCodeBookRstCfg;
2931 ue->ueCatEnum = cfg->ueCatEnum;
2932 if ((cfg->puschDedCfg.bACKIdx > 15) ||
2933 (cfg->puschDedCfg.bCQIIdx > 15) ||
2934 (cfg->puschDedCfg.bRIIdx > 15))
2936 err->errCause = RGSCHERR_SCH_CFG;
2939 ue->ul.betaHqOffst = cfg->puschDedCfg.bACKIdx;
2940 ue->ul.betaCqiOffst = cfg->puschDedCfg.bCQIIdx;
2941 ue->ul.betaRiOffst = cfg->puschDedCfg.bRIIdx;
2943 ue->csgMmbrSta = cfg->csgMmbrSta;
2945 cmMemset((U8 *)&ue->pfsStats, 0, sizeof(RgSchPfsStats));
2947 /* Call the handler of the scheduler based on cell configuration */
2948 RETVALUE(cell->sc.apis->rgSCHRgrUeCfg(cell, ue, cfg, err));
2950 /* Start : LTEMAC_2.1_DEV_CFG */
2953 * @brief This function adds a service to scheduler
2957 * Function: rgSCHUtlRgrLcCfg
2958 * Purpose: This function performs addition of service to scheduler
2959 * The addition is performed for each direction based
2960 * the direction field of the configuration
2962 * Invoked by: Scheduler
2964 * @param[in] RgSchCellCb *cell
2965 * @param[in] RgSchUeCb *ue
2966 * @param[in] RgSchDlLcCb *dlLc
2967 * @param[in] RgrLchCfg *cfg
2968 * @param[in] RgSchErrInfo *err
2973 PUBLIC S16 rgSCHUtlRgrLcCfg
2979 RgSchErrInfo *errInfo
2982 PUBLIC S16 rgSCHUtlRgrLcCfg(cell, ue, dlLc, cfg, errInfo)
2987 RgSchErrInfo *errInfo;
2990 TRC2(rgSCHUtlRgrLcCfg);
2991 RETVALUE(cell->sc.apis->rgSCHRgrLchCfg(cell, ue, dlLc, cfg, errInfo));
2996 * @brief This function modifies a service to scheduler
3000 * Function: rgSCHUtlRgrLcRecfg
3001 * Purpose: This function performs modification of a service in
3002 * scheduler. The modification is performed for each direction
3003 * based the direction field of the configuration
3005 * Invoked by: Scheduler
3007 * @param[in] RgSchCellCb *cell
3008 * @param[in] RgSchUeCb *ue
3009 * @param[in] RgSchDlLcCb *dlLc
3010 * @param[in] RgrLchRecfg *recfg
3011 * @param[in] RgSchErrInfo *err
3016 PUBLIC S16 rgSCHUtlRgrLcRecfg
3025 PUBLIC S16 rgSCHUtlRgrLcRecfg(cell, ue, dlLc, recfg, err)
3033 TRC2(rgSCHUtlRgrLcRecfg);
3034 RETVALUE(cell->sc.apis->rgSCHRgrLchRecfg(cell, ue, dlLc, recfg, err));
3038 * @brief This function deletes a Lc in scheduler
3042 * Function: rgSCHUtlRgrLcDel
3043 * Purpose: This function performs deletion of Lc in scheduler
3045 * Invoked by: Scheduler
3047 * @param[in] RgSchCellCb *cell
3048 * @param[in] RgSchUeCb *ue
3049 * @param[in] CmLteLcId lcId
3050 * @param[in] U8 lcgId
3055 PUBLIC S16 rgSCHUtlRgrLcDel
3063 PUBLIC S16 rgSCHUtlRgrLcDel(cell, ue, lcId, lcgId)
3070 TRC2(rgSCHUtlRgrLcDel);
3071 cell->sc.apis->rgSCHRgrLchDel(cell, ue, lcId, lcgId);
3074 } /* rgSCHUtlRgrLcDel */
3077 * @brief This function adds a service to scheduler
3081 * Function: rgSCHUtlRgrLcgCfg
3082 * Purpose: This function performs addition of service to scheduler
3083 * The addition is performed for each direction based
3084 * the direction field of the configuration
3086 * Invoked by: Scheduler
3088 * @param[in] RgSchCellCb *cell
3089 * @param[in] RgSchUeCb *ue
3090 * @param[in] RgrLchCfg *cfg
3091 * @param[in] RgSchErrInfo *err
3096 PUBLIC S16 rgSCHUtlRgrLcgCfg
3101 RgSchErrInfo *errInfo
3104 PUBLIC S16 rgSCHUtlRgrLcgCfg(cell, ue, cfg, errInfo)
3108 RgSchErrInfo *errInfo;
3111 TRC2(rgSCHUtlRgrLcgCfg);
3112 RETVALUE(cell->sc.apis->rgSCHRgrLcgCfg(cell, ue, &(ue->ul.lcgArr[cfg->ulInfo.lcgId]), cfg, errInfo));
3117 * @brief This function modifies a service to scheduler
3121 * Function: rgSCHUtlRgrLcgRecfg
3122 * Purpose: This function performs modification of a service in
3123 * scheduler. The modification is performed for each direction
3124 * based the direction field of the configuration
3126 * Invoked by: Scheduler
3128 * @param[in] RgSchCellCb *cell
3129 * @param[in] RgSchUeCb *ue
3130 * @param[in] RgrLcgRecfg *recfg
3131 * @param[in] RgSchErrInfo *err
3136 PUBLIC S16 rgSCHUtlRgrLcgRecfg
3144 PUBLIC S16 rgSCHUtlRgrLcgRecfg(cell, ue, recfg, err)
3151 TRC2(rgSCHUtlRgrLcgRecfg);
3152 RETVALUE(cell->sc.apis->rgSCHRgrLcgRecfg(cell, ue, &(ue->ul.lcgArr[recfg->ulRecfg.lcgId]), recfg, err));
3153 } /* rgSCHUtlRgrLcRecfg */
3156 * @brief This function modifies a service to scheduler
3160 * Function: rgSCHUtlRgrLcgDel
3161 * Purpose: This function performs modification of a service in
3162 * scheduler. The modification is performed for each direction
3163 * based the direction field of the configuration
3165 * Invoked by: Scheduler
3167 * @param[in] RgSchCellCb *cell
3168 * @param[in] RgSchUeCb *ue
3169 * @param[in] RgrDel *lcDelInfo
3174 PUBLIC Void rgSCHUtlRgrLcgDel
3181 PUBLIC Void rgSCHUtlRgrLcgDel(cell, ue, lcgId)
3187 TRC2(rgSCHUtlRgrLcgDel);
3188 cell->sc.apis->rgSCHFreeLcg(cell, ue, &ue->ul.lcgArr[lcgId]);
3190 /* Stack Crash problem for TRACE5 changes. added the return below . */
3193 } /* rgSCHUtlRgrLcgDel */
3196 /* End: LTEMAC_2.1_DEV_CFG */
3199 * @brief This function is a wrapper to call scheduler specific API.
3203 * Function: rgSCHUtlDoaInd
3204 * Purpose: Updates the DOA for the UE
3208 * @param[in] RgSchCellCb *cell
3209 * @param[in] RgSchUeCb *ue
3210 * @param[in] TfuDoaRpt *doaRpt
3215 PUBLIC Void rgSCHUtlDoaInd
3222 PUBLIC Void rgSCHUtlDoaInd(cell, ue, doaRpt)
3228 TRC2(rgSCHUtlDoaInd);
3229 ue->mimoInfo.doa.pres = PRSNT_NODEF;
3230 ue->mimoInfo.doa.val = doaRpt->doa;
3235 * @brief This function is a wrapper to call scheduler specific API.
3239 * Function: rgSCHUtlDlCqiInd
3240 * Purpose: Updates the DL CQI for the UE
3244 * @param[in] RgSchCellCb *cell
3245 * @param[in] RgSchUeCb *ue
3246 * @param[in] TfuDlCqiRpt *dlCqiRpt
3247 * @param[in] CmLteTimingInfo timingInfo
3252 PUBLIC Void rgSCHUtlDlCqiInd
3256 TfuDlCqiRpt *dlCqiRpt,
3257 CmLteTimingInfo timingInfo
3260 PUBLIC Void rgSCHUtlDlCqiInd(cell, ue, dlCqiRpt, timingInfo)
3263 TfuDlCqiRpt *dlCqiRpt;
3264 CmLteTimingInfo timingInfo;
3267 RgSchCellCb *sCellCb = NULLP;
3268 TRC2(rgSCHUtlDlCqiInd);
3269 if (dlCqiRpt->isPucchInfo)
3271 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pucchCqi.cellIdx]->cell;
3272 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3273 (Void *)&dlCqiRpt->dlCqiInfo.pucchCqi, timingInfo);
3278 for (idx = 0; idx < dlCqiRpt->dlCqiInfo.pusch.numOfCells; idx++)
3280 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx].cellIdx]->cell;
3281 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3282 (Void *)&dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx], timingInfo);
3291 * @brief This function is a wrapper to call scheduler specific API.
3295 * Function: rgSCHUtlSrsInd
3296 * Purpose: Updates the UL SRS for the UE
3300 * @param[in] RgSchCellCb *cell
3301 * @param[in] RgSchUeCb *ue
3302 * @param[in] TfuSrsRpt* srsRpt
3303 * @param[in] CmLteTimingInfo timingInfo
3308 PUBLIC Void rgSCHUtlSrsInd
3313 CmLteTimingInfo timingInfo
3316 PUBLIC Void rgSCHUtlSrsInd(cell, ue, srsRpt, timingInfo)
3320 CmLteTimingInfo timingInfo;
3323 TRC2(rgSCHUtlSrsInd);
3324 cell->sc.apis->rgSCHSrsInd(cell, ue, srsRpt, timingInfo);
3330 * @brief This function is a wrapper to call scheduler specific API.
3334 * Function: rgSCHUtlDlTARpt
3335 * Purpose: Reports PHY TA for a UE.
3339 * @param[in] RgSchCellCb *cell
3340 * @param[in] RgSchUeCb *ue
3345 PUBLIC Void rgSCHUtlDlTARpt
3351 PUBLIC Void rgSCHUtlDlTARpt(cell, ue)
3356 TRC2(rgSCHUtlDlTARpt);
3357 cell->sc.apis->rgSCHDlTARpt(cell, ue);
3363 * @brief This function is a wrapper to call scheduler specific API.
3367 * Function: rgSCHUtlDlRlsSubFrm
3368 * Purpose: Releases scheduler Information from DL SubFrm.
3372 * @param[in] RgSchCellCb *cell
3373 * @param[out] CmLteTimingInfo subFrm
3378 PUBLIC Void rgSCHUtlDlRlsSubFrm
3381 CmLteTimingInfo subFrm
3384 PUBLIC Void rgSCHUtlDlRlsSubFrm(cell, subFrm)
3386 CmLteTimingInfo subFrm;
3389 TRC2(rgSCHUtlDlRlsSubFrm);
3390 cell->sc.apis->rgSCHDlRlsSubFrm(cell, subFrm);
3396 * @brief This API is invoked to update the AperCQI trigger
3401 * Function : rgSCHUtlUpdACqiTrigWt
3402 * - If HqFdbk is ACK then add up weight corresponding
3403 * to ACK to the AcqiTrigWt.
3404 * - If HqFdbk is NACK then add up weight corresponding
3405 * to NACK to the AcqiTrigWt.
3406 * - If AcqiTrigWt crosses threshold then trigger
3407 * grant req for APERCQI to SCH.
3409 * @param[in] RgSchUeCb *ue
3410 * @param[in] U8 isAck
3415 PUBLIC Void rgSCHUtlUpdACqiTrigWt
3418 RgSchUeCellInfo *cellInfo,
3422 PUBLIC Void rgSCHUtlUpdACqiTrigWt(ue,cellInfo, isAck)
3424 RgSchUeCellInfo *cellInfo;
3433 TRC2(rgSCHUtlUpdACqiTrigWt);
3435 if (isAck == TFU_HQFDB_ACK)
3437 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_ACK_WGT;
3441 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_NACK_WGT;
3444 if (cellInfo->acqiCb.aCqiTrigWt > RG_APER_CQI_THRESHOLD_WGT)
3446 RgSchCellCb *cell = ue->cell;
3447 RgSchErrInfo unUsed;
3449 if(ue->dl.reqForCqi)
3451 /* Already one ACQI trigger procedure is going on
3452 * which is not yet satisfied. Delaying this request till
3453 * the previous is getting satisfied*/
3457 ue->dl.reqForCqi = TRUE;
3459 rgSchCmnSetCqiReqField(cellInfo,ue,&ue->dl.reqForCqi);
3460 //Reset aCqiTrigWt for all the serving cells for which we have triggered ACQI
3461 rgSCHTomUtlGetTrigSet(cell, ue, ue->dl.reqForCqi, &triggerSet);
3462 for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++)
3464 /* The Aperiodic requested for SCell index sIdx */
3465 if ((triggerSet >> (7 - sIdx)) & 0x01)
3467 /* The Aperiodic request for SCell index sIdx */
3468 ue->cellInfo[sIdx]->acqiCb.aCqiTrigWt = 0;
3473 /* Force SCH to send UL grant by indicating fake SR.
3474 * If this UE already in UL SCH Qs this SR Ind will
3476 rgSCHUtlSrRcvd(cell, ue, cell->crntTime, &unUsed);
3484 * @brief This API is invoked to indicate scheduler of a CRC indication.
3488 * Function : rgSCHUtlHdlUlTransInd
3489 * This API is invoked to indicate scheduler of a CRC indication.
3491 * @param[in] RgSchCellCb *cell
3492 * @param[in] RgSchUeCb *ue
3493 * @param[in] CmLteTimingInfo timingInfo
3498 PUBLIC Void rgSCHUtlHdlUlTransInd
3502 CmLteTimingInfo timingInfo
3505 PUBLIC Void rgSCHUtlHdlUlTransInd(cell, ue, timingInfo)
3508 CmLteTimingInfo timingInfo;
3511 TRC2(rgSCHUtlHdlUlTransInd);
3512 cell->sc.apis->rgSCHHdlUlTransInd(cell, ue, timingInfo);
3517 * @brief This API is invoked to indicate scheduler of a CRC failure.
3521 * Function : rgSCHUtlHdlCrcInd
3522 * This API is invoked to indicate CRC to scheduler.
3524 * @param[in] RgSchCellCb *cell
3525 * @param[in] RgSchUeCb *ue
3526 * @param[in] CmLteTimingInfo timingInfo
3531 PUBLIC Void rgSCHUtlHdlCrcInd
3535 CmLteTimingInfo timingInfo
3538 PUBLIC Void rgSCHUtlHdlCrcInd(cell, ue, timingInfo)
3541 CmLteTimingInfo timingInfo;
3544 TRC2(rgSCHUtlHdlCrcFail);
3545 cell->sc.apis->rgSCHUlCrcInd(cell, ue, timingInfo);
3547 } /* end of rgSCHUtlHdlCrcFailInd */
3550 * @brief This API is invoked to indicate scheduler of a CRC failure.
3554 * Function : rgSCHUtlHdlCrcFailInd
3555 * This API is invoked to indicate CRC failure to scheduler.
3557 * @param[in] RgSchCellCb *cell
3558 * @param[in] RgSchUeCb *ue
3559 * @param[in] CmLteTimingInfo timingInfo
3564 PUBLIC Void rgSCHUtlHdlCrcFailInd
3568 CmLteTimingInfo timingInfo
3571 PUBLIC Void rgSCHUtlHdlCrcFailInd(cell, ue, timingInfo)
3574 CmLteTimingInfo timingInfo;
3577 TRC2(rgSCHUtlHdlCrcFail);
3578 cell->sc.apis->rgSCHUlCrcFailInd(cell, ue, timingInfo);
3580 } /* end of rgSCHUtlHdlCrcFailInd */
3581 #endif /* LTEMAC_SPS */
3585 * @brief This function is a wrapper to call scheduler specific API.
3589 * Function: rgSCHUtlDlProcAddToRetx
3590 * Purpose: This function adds a HARQ process to retransmission
3591 * queue. This may be performed when a HARQ ack is
3594 * Invoked by: HARQ feedback processing
3596 * @param[in] RgSchCellCb* cell
3597 * @param[in] RgSchDlHqProc* hqP
3602 PUBLIC Void rgSCHUtlDlProcAddToRetx
3605 RgSchDlHqProcCb *hqP
3608 PUBLIC Void rgSCHUtlDlProcAddToRetx(cell, hqP)
3610 RgSchDlHqProcCb *hqP;
3613 TRC2(rgSCHUtlDlProcAddToRetx);
3614 cell->sc.apis->rgSCHDlProcAddToRetx(cell, hqP);
3620 * @brief This function adds a HARQ process TB to transmission
3624 * Function: rgSCHUtlDlHqPTbAddToTx
3625 * Purpose: This function a HarqProcess TB to the slot
3628 * Invoked by: Scheduler
3630 * @param[in] RgSubFrm* subFrm
3631 * @param[in] RgDlHqProc* hqP
3632 * @param[in] U8 tbIdx
3637 PUBLIC Void rgSCHUtlDlHqPTbAddToTx
3640 RgSchDlHqProcCb *hqP,
3644 PUBLIC Void rgSCHUtlDlHqPTbAddToTx(subFrm, hqP, tbIdx)
3646 RgSchDlHqProcCb *hqP;
3650 RgSchUeCb *ue = NULLP;
3651 RgSchCellCb *cell = hqP->hqE->cell;
3653 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3654 /* ue->cell will always hold PCell information */
3655 if (NULLP == hqP->hqPSfLnk.node)
3660 if(NULLP == ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node)
3662 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)ue;
3663 cmLListAdd2Tail(&cell->subFrms[subFrm->dlIdx]->ueLst,
3664 &ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3666 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].isPuschHarqRecpPres = FALSE;
3670 /* Add Hq proc in particular dlIdx List for this UE
3671 This list will be used while processing feedback*/
3672 hqP->hqPSfLnk.node = (PTR)hqP;
3673 cmLListAdd2Tail(&ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3676 extern U32 gSCellSchedCount,gPrimarySchedCount;
3677 if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue,hqP->hqE->cell))
3681 gPrimarySchedCount++;
3685 else if (hqP->hqE->msg4Proc == hqP)
3687 /* Msg4 will be scheduled on PCELL only hence add directly to subFrm msg4HqpList */
3688 hqP->hqPSfLnk.node = (PTR)hqP;
3689 cmLListAdd2Tail(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3696 if((ue) && (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state))
3699 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt++;
3701 /*totalTbCnt will hold the total number of TBs across all harq Proc from all
3704 hqP->subFrm = subFrm;
3713 * @brief This function removes a HARQ process TB from transmission
3717 * Function: rgSCHUtlDlHqPTbRmvFrmTx
3718 * Purpose: This function removes a HarqProcess TB to the slot
3721 * Invoked by: Scheduler
3723 * @param[in] RgSubFrm* subFrm
3724 * @param[in] RgDlHqProc* hqP
3725 * @param[in] U8 tbIdx
3726 * @param[in] Bool isRepeting
3731 PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx
3734 RgSchDlHqProcCb *hqP,
3739 PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx(subFrm, hqP, tbIdx, isRepeting)
3741 RgSchDlHqProcCb *hqP;
3746 RgSchCellCb *cell = NULLP;
3747 /* Check with TDD */
3749 (hqP->hqE->ue->ackNakRepCb.cfgRepCnt !=
3750 hqP->tbInfo[tbIdx].fbkRepCntr))
3752 cmLListDelFrm(&subFrm->ackNakRepQ,
3753 &hqP->tbInfo[tbIdx].anRepLnk[hqP->tbInfo[tbIdx].fbkRepCntr]);
3757 if (NULLP != hqP->hqPSfLnk.node)
3760 if (hqP->hqE->msg4Proc == hqP)
3762 /* Msg4 will be scheduled on PCELL only hence delete directly from subFrm msg4HqpList */
3763 cmLListDelFrm(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3767 cell = hqP->hqE->cell;
3768 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3769 /* ue->cell will always hold PCell information */
3770 cmLListDelFrm(&hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3771 if (0 == hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst.count)
3774 cmLListDelFrm(&cell->subFrms[subFrm->dlIdx]->ueLst,
3775 &hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3776 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)NULLP;
3777 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt = 0;
3780 hqP->hqPSfLnk.node = NULLP;
3782 hqP->subFrm = NULLP;
3789 * @brief Handler for accessing the existing SCellCb identified by the key
3790 * SCellId under the CellCb.
3794 * Function : rgSchUtlGetCellCb
3797 * @param[in] *cellCb
3799 * @return RgSchUeCb*
3802 PUBLIC RgSchCellCb* rgSchUtlGetCellCb
3808 PUBLIC RgSchCellCb* rgSchUtlGetCellCb(inst, cellId)
3813 RgSchCellCb *cellCb = NULLP;
3816 TRC2(rgSchUtlGetCellCb);
3818 strtCellId = rgSchCb[inst].genCfg.startCellId;
3819 cellCb = rgSchCb[inst].cells[cellId - strtCellId];
3823 } /* rgSchUtlGetCellCb */
3826 * @brief Handler for deriving the servCellidx
3830 * Function : rgSchUtlGetServCellIdx
3833 * @param[in] *cellId
3834 * @param[in] RgSchUeCb *ue
3835 * @return U8 servCellIdx
3838 PUBLIC U8 rgSchUtlGetServCellIdx
3845 PUBLIC U8 rgSchUtlGetServCellIdx(inst,cellId,ue)
3854 TRC2(rgSchUtlGetCellCb);
3856 strtCellId = rgSchCb[inst].genCfg.startCellId;
3858 servCellIdx = ue->cellIdToCellIdxMap[cellId - strtCellId];
3860 RETVALUE(servCellIdx);
3862 } /* rgSchUtlGetCellCb */
3865 * @brief Handler for validating the Cell Id received secondary Cell Addition
3869 * Function : rgSchUtlGetCellId
3872 * @param[in] *cellCb
3874 * @return RgSchUeCb*
3877 PUBLIC S16 rgSchUtlVldtCellId
3883 PUBLIC S16 rgSchUtlVldtCellId(inst, cellId)
3890 TRC2(rgSchUtlVldtCellId);
3892 strtCellId = rgSchCb[inst].genCfg.startCellId;
3893 if((cellId >= strtCellId) && ((cellId - strtCellId) < CM_LTE_MAX_CELLS))
3898 } /* rgSchUtlVldtCellId */
3902 * @brief UE reconfiguration for scheduler
3906 * Function : rgSCHUtlRgrUeRecfg
3908 * This functions updates UE specific scheduler
3909 * information upon UE reconfiguration
3911 * @param[in] RgSchCellCb *cell
3912 * @param[in] RgSchUeCb *ue
3913 * @param[int] RgrUeRecfg *ueRecfg
3914 * @param[out] RgSchErrInfo *err
3920 PUBLIC S16 rgSCHUtlRgrUeRecfg
3924 RgrUeRecfg *ueRecfg,
3928 PUBLIC S16 rgSCHUtlRgrUeRecfg(cell, ue, ueRecfg, err)
3931 RgrUeRecfg *ueRecfg;
3935 /* Changes for UE Category Reconfiguration feature addition */
3936 RgSchCmnUe *ueSch = RG_SCH_CMN_GET_UE(ue, cell);
3938 TRC2(rgSCHUtlRgrUeRecfg);
3940 /* Changes for UE Category Reconfiguration feature addition */
3941 if (ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
3943 ueSch->cmn.ueCat = ueRecfg->ueCatEnum-1;
3945 ue->ueCatEnum = ueRecfg->ueCatEnum;
3949 /* DL MU-MIMO not supported */
3950 if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
3953 if (ueRecfg->txMode.pres == PRSNT_NODEF)
3955 if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_5)
3957 err->errCause = RGSCHERR_SCH_CFG;
3961 if(ue->mimoInfo.txMode != ueRecfg->txMode.txModeEnum)
3963 /* Decremnt the previos A value for this cell */
3964 ue->f1bCsAVal -= rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode);
3965 /* Update A value with the new TM Mode */
3966 ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(ueRecfg->txMode.txModeEnum);
3969 RLOG1(L_INFO,"UeReCfg A valie is %d\n",ue->f1bCsAVal);
3972 ue->mimoInfo.txMode = ueRecfg->txMode.txModeEnum;
3976 /* [ccpu00123958]-ADD- Check for PUSCH related Reconfig from the bit mask */
3977 if(ueRecfg->ueRecfgTypes & RGR_UE_PUSCH_RECFG)
3979 /* Fix: ccpu00124012 */
3980 /* TODO:: Need to check if this is
3981 mandatory to be re-configured on UE category re-configuration */
3982 /* ue->ul.betaHqOffst = ueRecfg->puschDedCfg.bACKIdx;
3983 ue->ul.betaCqiOffst = ueRecfg->puschDedCfg.bCQIIdx;
3984 ue->ul.betaRiOffst = ueRecfg->puschDedCfg.bRIIdx;*/
3987 if (ueRecfg->ueRecfgTypes & RGR_UE_ULTXANTSEL_RECFG)
3989 ue->ul.ulTxAntSel = ueRecfg->ulTxAntSel;
3991 if (ueRecfg->ueRecfgTypes & RGR_UE_CDBKSBST_RECFG)
3993 ue->mimoInfo.cdbkSbstRstrctn = ueRecfg->ueCodeBookRstRecfg;
3996 /* Commenting here to assign garbage value when it is not set in APP. */
3997 //ue->accessStratumRls = ueRecfg->accessStratumRls;
3998 RETVALUE(cell->sc.apis->rgSCHRgrUeRecfg(cell, ue, ueRecfg, err));
3999 } /* rgSCHUtlRgrUeRecfg */
4002 * @brief This function deletes a service from scheduler
4006 * Function: rgSCHUtlFreeDlLc
4007 * Purpose: This function is made available through a FP for
4008 * making scheduler aware of a service being deleted from UE
4010 * Invoked by: BO and Scheduler
4012 * @param[in] RgSchCellCb* cell
4013 * @param[in] RgSchUeCb* ue
4014 * @param[in] RgSchDlLcCb* svc
4018 PUBLIC Void rgSCHUtlFreeDlLc
4025 PUBLIC Void rgSCHUtlFreeDlLc(cell, ue, svc)
4031 TRC2(rgSCHUtlFreeDlLc);
4032 cell->sc.apis->rgSCHFreeDlLc(cell, ue, svc);
4034 /* Stack Crash problem for TRACE5 changes. added the return below . */
4040 * @brief UE deletion for scheduler
4044 * Function : rgSCHUtlFreeUe
4046 * This functions deletes all scheduler information
4047 * pertaining to a UE
4049 * @param[in] RgSchCellCb *cell
4050 * @param[in] RgSchUeCb *ue
4054 PUBLIC Void rgSCHUtlFreeUe
4060 PUBLIC Void rgSCHUtlFreeUe(cell, ue)
4065 TRC2(rgSCHUtlFreeUe);
4067 rgSCHUtlDelUeANFdbkInfo(ue,RGSCH_PCELL_INDEX);
4069 cell->sc.apis->rgSCHFreeUe(cell, ue);
4071 /* Stack Crash problem for TRACE5 changes. added the return below . */
4074 } /* rgSCHUtlFreeUe */
4077 * @brief This function updates the scheduler with service for a UE
4081 * Function: rgSCHUtlDlDedBoUpd
4082 * Purpose: This function should be called whenever there is a
4083 * change BO for a service.
4085 * Invoked by: BO and Scheduler
4087 * @param[in] RgSchCellCb* cell
4088 * @param[in] RgSchUeCb* ue
4089 * @param[in] RgSchDlLcCb* lc
4093 PUBLIC Void rgSCHUtlDlDedBoUpd
4100 PUBLIC Void rgSCHUtlDlDedBoUpd(cell, ue, lc)
4106 TRC2(rgSCHUtlDlDedBoUpd);
4107 cell->sc.apis->rgSCHDlDedBoUpd(cell, ue, lc);
4111 * @brief Record MSG3 allocation into the UE
4115 * Function : rgSCHUtlRecMsg3Alloc
4117 * This function is invoked to update record msg3 allocation information
4118 * in the UE when UE is detected for RaCb
4120 * @param[in] RgSchCellCb *cell
4121 * @param[in] RgSchUeCb *ue
4122 * @param[in] RgSchRaCb *raCb
4126 PUBLIC Void rgSCHUtlRecMsg3Alloc
4133 PUBLIC Void rgSCHUtlRecMsg3Alloc(cell, ue, raCb)
4139 TRC2(rgSCHUtlRecMsg3Alloc)
4140 cell->sc.apis->rgSCHUlRecMsg3Alloc(cell, ue, raCb);
4143 } /* rgSCHRecMsg3Alloc */
4147 * @brief Update harq process for allocation
4151 * Function : rgSCHUtlUpdUlHqProc
4153 * This function is invoked when harq process
4154 * control block is now in a new memory location
4155 * thus requiring a pointer/reference update.
4157 * @param[in] RgSchCellCb *cell
4158 * @param[in] RgSchUlHqProcCb *curProc
4159 * @param[in] RgSchUlHqProcCb *oldProc
4165 PUBLIC S16 rgSCHUtlUpdUlHqProc
4168 RgSchUlHqProcCb *curProc,
4169 RgSchUlHqProcCb *oldProc
4172 PUBLIC S16 rgSCHUtlUpdUlHqProc(cell, curProc, oldProc)
4174 RgSchUlHqProcCb *curProc;
4175 RgSchUlHqProcCb *oldProc;
4178 TRC2(rgSCHUtlUpdUlHqProc);
4179 RETVALUE(cell->sc.apis->rgSCHUpdUlHqProc(cell, curProc, oldProc));
4180 } /* rgSCHUtlUpdUlHqProc */
4183 * @brief UL grant for contention resolution
4187 * Function : rgSCHUtlContResUlGrant
4189 * Add UE to another queue specifically for CRNTI based contention
4192 * @param[in] RgSchCellCb *cell
4193 * @param[in] RgSchUeCb *ue
4194 * @param[out] RgSchErrInfo *err
4200 PUBLIC S16 rgSCHUtlContResUlGrant
4207 PUBLIC S16 rgSCHUtlContResUlGrant(cell, ue, err)
4213 TRC2(rgSCHUtlContResUlGrant);
4216 ue->isMsg4PdcchWithCrnti = TRUE;
4218 RETVALUE(cell->sc.apis->rgSCHContResUlGrant(cell, ue, err));
4219 } /* rgSCHUtlContResUlGrant */
4222 * @brief SR reception handling
4226 * Function : rgSCHUtlSrRcvd
4228 * - Handles SR reception for UE
4230 * @param[in] RgSchCellCb *cell
4231 * @param[in] RgSchUeCb *ue
4232 * @param[out] RgSchErrInfo *err
4238 PUBLIC S16 rgSCHUtlSrRcvd
4242 CmLteTimingInfo frm,
4246 PUBLIC S16 rgSCHUtlSrRcvd(cell, ue, frm, err)
4249 CmLteTimingInfo frm;
4253 TRC2(rgSCHUtlSrRcvd);
4254 RETVALUE(cell->sc.apis->rgSCHSrRcvd(cell, ue, frm, err));
4255 } /* rgSCHUtlSrRcvd */
4258 * @brief Short BSR update
4262 * Function : rgSCHUtlUpdBsrShort
4264 * This functions does requisite updates to handle short BSR reporting
4266 * @param[in] RgSchCellCb *cell
4267 * @param[in] RgSchUeCb *ue
4268 * @param[in] U8 lcgId
4270 * @param[out] RgSchErrInfo *err
4276 PUBLIC Void rgSCHUtlUpdBsrShort
4285 PUBLIC Void rgSCHUtlUpdBsrShort(cell, ue, lcgId, bsr, err)
4293 TRC2(rgSCHUtlUpdBsrShort);
4294 cell->sc.apis->rgSCHUpdBsrShort(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4296 } /* rgSCHUtlUpdBsrShort */
4300 * @brief Truncated BSR update
4304 * Function : rgSCHUtlUpdBsrTrunc
4306 * This functions does required updates to handle truncated BSR report
4309 * @param[in] RgSchCellCb *cell
4310 * @param[in] RgSchUeCb *ue
4311 * @param[in] U8 lcgId
4313 * @param[out] RgSchErrInfo *err
4319 PUBLIC Void rgSCHUtlUpdBsrTrunc
4328 PUBLIC Void rgSCHUtlUpdBsrTrunc(cell, ue, lcgId, bsr, err)
4336 TRC2(rgSCHUtlUpdBsrTrunc);
4337 cell->sc.apis->rgSCHUpdBsrTrunc(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4339 } /* rgSCHUtlUpdBsrTrunc */
4343 * @brief Long BSR update
4347 * Function : rgSCHUtlUpdBsrLong
4349 * - Update BSRs for all configured LCGs
4350 * - Update priority of LCGs if needed
4351 * - Update UE's position within/across uplink scheduling queues
4354 * @param[in] RgSchCellCb *cell
4355 * @param[in] RgSchUeCb *ue
4356 * @param[in] U8 bsr0
4357 * @param[in] U8 bsr1
4358 * @param[in] U8 bsr2
4359 * @param[in] U8 bsr3
4360 * @param[out] RgSchErrInfo *err
4366 PUBLIC Void rgSCHUtlUpdBsrLong
4377 PUBLIC Void rgSCHUtlUpdBsrLong(cell, ue, bsr0, bsr1, bsr2, bsr3, err)
4388 TRC2(rgSCHUtlUpdBsrLong);
4394 cell->sc.apis->rgSCHUpdBsrLong(cell, ue, bsArr, err);
4396 } /* rgSCHUtlUpdBsrLong */
4399 * @brief EXT PHR update
4403 * Function : rgSCHUtlUpdExtPhr
4405 * Updates extended power headroom info for a UE
4407 * @param[in] RgSchCellCb *cell
4408 * @param[in] RgSchUeCb *ue
4410 * @param[out] RgSchErrInfo *err
4416 PUBLIC S16 rgSCHUtlUpdExtPhr
4420 RgInfExtPhrCEInfo * extPhr,
4424 PUBLIC S16 rgSCHUtlUpdExtPhr(cell, ue, extPhr, err)
4427 RgInfExtPhrCEInfo * extPhr;
4431 TRC2(rgSCHUtlUpdExtPhr);
4432 RETVALUE(cell->sc.apis->rgSCHUpdExtPhr(cell, ue, extPhr, err));
4433 } /* rgSCHUtlUpdExtPhr */
4442 * Function : rgSCHUtlUpdPhr
4444 * Updates power headroom info for a UE
4446 * @param[in] RgSchCellCb *cell
4447 * @param[in] RgSchUeCb *ue
4449 * @param[out] RgSchErrInfo *err
4455 PUBLIC S16 rgSCHUtlUpdPhr
4463 PUBLIC S16 rgSCHUtlUpdPhr(cell, ue, phr, err)
4470 TRC2(rgSCHUtlUpdPhr);
4471 RETVALUE(cell->sc.apis->rgSCHUpdPhr(cell, ue, phr, err));
4472 } /* rgSCHUtlUpdPhr */
4476 * @brief Indication of UL CQI
4480 * Function : rgSCHUtlUlCqiInd
4482 * - Updates uplink CQI information for the UE. Computes and
4483 * stores the lowest CQI of CQIs reported in all subbands
4485 * @param[in] RgSchCellCb *cell
4486 * @param[in] RgSchUeCb *ue
4487 * @param[in] TfuUlCqiRpt *ulCqiInfo
4491 PUBLIC Void rgSCHUtlUlCqiInd
4495 TfuUlCqiRpt *ulCqiInfo
4498 PUBLIC Void rgSCHUtlUlCqiInd(cell, ue, ulCqiInfo)
4501 TfuUlCqiRpt *ulCqiInfo;
4504 TRC2(rgSCHUtlUlCqiInd);
4505 cell->sc.apis->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
4507 } /* rgSCHUtlUlCqiInd */
4510 * @brief Indication of PUCCH power adjustment
4514 * Function : rgSCHUtlPucchDeltaPwrInd
4516 * - Updates uplink CQI information for the UE. Computes and
4517 * stores the lowest CQI of CQIs reported in all subbands
4519 * @param[in] RgSchCellCb *cell
4520 * @param[in] RgSchUeCb *ue
4521 * @param[in] U8 delta
4525 PUBLIC Void rgSCHUtlPucchDeltaPwrInd
4532 PUBLIC Void rgSCHUtlPucchDeltaPwrInd(cell, ue, delta)
4538 TRC2(rgSCHUtlPucchDeltaPwrInd);
4539 cell->sc.apis->rgSCHPucchDeltaPwrInd(cell, ue, delta);
4541 } /* rgSCHUtlPucchDeltaPwrInd */
4543 /* Start: LTEMAC_2.1_DEV_CFG */
4545 * @brief Ue Reset Request
4549 * Function : rgSCHUtlUeReset
4552 * @param[in] RgSchCellCb *cell
4553 * @param[in] RgSchUeCb *ue
4557 PUBLIC Void rgSCHUtlUeReset
4563 PUBLIC Void rgSCHUtlUeReset(cell, ue)
4568 TRC2(rgSCHUtlUeReset);
4570 cell->sc.apis->rgSCHUeReset(cell, ue);
4572 } /* rgSCHUtlUeReset */
4573 /* End: LTEMAC_2.1_DEV_CFG */
4576 * @brief Returns HARQ proc for which data expected now
4580 * Function: rgSCHUtlUlHqProcForUe
4581 * Purpose: This function returns the harq process for
4582 * which data is expected in the current slot.
4583 * It does not validate if the HARQ process
4584 * has an allocation.
4588 * @param[in] RgSchCellCb *cell
4589 * @param[in] CmLteTimingInfo frm
4590 * @param[in] RgSchUeCb *ue
4591 * @param[out] RgSchUlHqProcCb **procRef
4595 PUBLIC Void rgSCHUtlUlHqProcForUe
4598 CmLteTimingInfo frm,
4600 RgSchUlHqProcCb **procRef
4603 PUBLIC Void rgSCHUtlUlHqProcForUe(cell, frm, ue, procRef)
4605 CmLteTimingInfo frm;
4607 RgSchUlHqProcCb **procRef;
4610 TRC2(rgSCHUtlUlHqProcForUe);
4611 cell->sc.apis->rgSCHUlHqProcForUe(cell, frm, ue, procRef);
4613 /* Stack Crash problems for TRACE5 changes. added the return below */
4619 * @brief Returns first uplink allocation to send reception
4624 * Function: rgSCHUtlFirstRcptnReq(cell)
4625 * Purpose: This function returns the first uplink allocation
4626 * (or NULLP if there is none) in the slot
4627 * in which is expected to prepare and send reception
4632 * @param[in] RgSchCellCb *cell
4633 * @return RgSchUlAlloc*
4636 PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq
4641 PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq(cell)
4645 TRC2(rgSCHUtlFirstRcptnReq);
4646 RETVALUE(cell->sc.apis->rgSCHFirstRcptnReq(cell));
4650 * @brief Returns first uplink allocation to send reception
4655 * Function: rgSCHUtlNextRcptnReq(cell)
4656 * Purpose: This function returns the next uplink allocation
4657 * (or NULLP if there is none) in the slot
4658 * in which is expected to prepare and send reception
4663 * @param[in] RgSchCellCb *cell
4664 * @return RgSchUlAlloc*
4667 PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq
4673 PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq(cell, alloc)
4675 RgSchUlAlloc *alloc;
4678 TRC2(rgSCHUtlNextRcptnReq);
4679 RETVALUE(cell->sc.apis->rgSCHNextRcptnReq(cell, alloc));
4683 * @brief Returns first uplink allocation to send HARQ feedback
4688 * Function: rgSCHUtlFirstHqFdbkAlloc
4689 * Purpose: This function returns the first uplink allocation
4690 * (or NULLP if there is none) in the slot
4691 * in which it is expected to prepare and send HARQ
4696 * @param[in] RgSchCellCb *cell
4698 * @return RgSchUlAlloc*
4701 PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc
4707 PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc(cell, idx)
4712 TRC2(rgSCHUtlFirstHqFdbkAlloc);
4713 RETVALUE(cell->sc.apis->rgSCHFirstHqFdbkAlloc(cell, idx));
4718 * @brief Returns next allocation to send HARQ feedback for
4722 * Function: rgSCHUtlNextHqFdbkAlloc(cell)
4723 * Purpose: This function returns the next uplink allocation
4724 * (or NULLP if there is none) in the slot
4725 * for which HARQ feedback needs to be sent.
4729 * @param[in] RgSchCellCb *cell
4730 * @return RgSchUlAlloc*
4733 PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc
4736 RgSchUlAlloc *alloc,
4740 PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc(cell, alloc, idx)
4742 RgSchUlAlloc *alloc;
4746 TRC2(rgSCHUtlNextHqFdbkAlloc);
4747 RETVALUE(cell->sc.apis->rgSCHNextHqFdbkAlloc(cell, alloc, idx));
4750 /***********************************
4751 ***********************************/
4753 * @brief This API is invoked to send TFU SAP bind request to PHY.
4757 * Function : rgSCHUtlTfuBndReq
4759 * This API is invoked to send TFU SAP bind request to PHY from scheduler
4760 * isntance. It fills in the Pst structure, spId and suId values and
4761 * invokes bind request primitive at TFU.
4763 * @param[in] Inst instId
4764 * @param[in] SuId suId
4765 * @param[in] SpId spId
4771 PUBLIC S16 rgSCHUtlTfuBndReq
4778 PUBLIC S16 rgSCHUtlTfuBndReq(instId, suId, spId)
4785 RgSchLowSapCb *tfuSap;
4787 TRC2(rgSCHUtlTfuBndReq);
4789 /* Get the lower SAP control block from the layer control block. */
4790 tfuSap = &(rgSchCb[instId].tfuSap[suId]);
4791 (Void)cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
4792 if((ret = RgLiTfuSchBndReq (&pst, suId, spId)) != ROK)
4794 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlTfuBndReq() Call to RgLiTfuBndReq()"
4798 } /* rgSCHUtlTfuBndReq */
4801 * @brief This API is invoked to send TFU SAP unbind request to PHY.
4805 * Function : rgSCHUtlTfuUBndReq
4806 * This API is invoked to send TFU SAP unbind request to PHY from Scheduler
4807 * isntance. It fills in the Pst structure and spId value and invokes
4808 * unbind request primitive at TFU.
4810 * @param[in] SpId spId
4816 PUBLIC S16 rgSCHUtlTfuUBndReq
4819 RgSchLowSapCfgInfo sapCfg,
4823 PUBLIC S16 rgSCHUtlTfuUBndReq(inst, sapCfg, reason)
4825 RgSchLowSapCfgInfo sapCfg;
4832 TRC2(rgSCHUtlTfuUBndReq);
4834 /* Get the lower SAP control block from the layer control block. */
4835 cmMemcpy ((U8*)&pst, (U8*)&(sapCfg.sapPst), sizeof(Pst));
4836 if((ret = RgLiTfuSchUbndReq (&pst, sapCfg.spId, reason)) != ROK)
4838 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuUBndReq() Call to"
4839 " RgLiTfuUbndReq() failed");
4843 } /* rgSCHUtlTfuUBndReq */
4845 /***********************************************************
4847 * Func : rgSCHUtlResetSfAlloc
4849 * Desc : Utility Function to Reset slot allocation information.
4858 **********************************************************/
4860 PUBLIC S16 rgSCHUtlResetSfAlloc
4862 RgInfSfAlloc *sfAlloc,
4863 Bool resetCmnLcInfo,
4867 PUBLIC S16 rgSCHUtlResetSfAlloc(sfAlloc,resetCmnLcInfo,restAlloc)
4868 RgInfSfAlloc *sfAlloc;
4869 Bool resetCmnLcInfo;
4873 TRC2(rgSCHUtlResetSfAlloc);
4874 if(TRUE == restAlloc)
4876 if(sfAlloc->ueInfo.numUes)
4878 cmMemset((U8 *)sfAlloc->ueInfo.allocInfo,0x00,
4879 (sizeof(RgInfUeAlloc)*sfAlloc->ueInfo.numUes));
4881 sfAlloc->ueInfo.numUes = 0;
4882 sfAlloc->rarInfo.numRaRntis = 0;
4883 sfAlloc->flowCntrlInfo.numUes = 0;
4885 if(TRUE == resetCmnLcInfo)
4887 sfAlloc->cmnLcInfo.bitMask = 0;
4892 /***********************************************************
4894 * Func : rgSCHUtlGetRlsHqAlloc
4896 * Desc : Utility Function to Allocate slot allocation information.
4905 **********************************************************/
4907 PUBLIC S16 rgSCHUtlGetRlsHqAlloc
4912 PUBLIC S16 rgSCHUtlGetRlsHqAlloc(cell)
4917 Inst inst = cell->instIdx;
4918 TRC2(rgSCHUtlGetRlsHqAlloc);
4919 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4921 cell->rlsHqArr[idx].cellId = cell->cellId;
4923 /* Allocating with additional location, to accommodate
4924 TA scheduling along with maximum no of UEs per SF */
4926 /* Allocate memory for "scheduled UE" Info */
4927 if((rgSCHUtlAllocSBuf(inst,
4928 (Data**)&(cell->rlsHqArr[idx].ueHqInfo),
4929 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
4931 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4941 /***********************************************************
4943 * Func : rgSCHUtlPutRlsHqAlloc
4945 * Desc : Utility Function to deallocate slot allocation information.
4954 **********************************************************/
4956 PUBLIC S16 rgSCHUtlPutRlsHqAlloc
4961 PUBLIC S16 rgSCHUtlPutRlsHqAlloc(cell)
4966 Inst inst = cell->instIdx;
4967 TRC2(rgSCHUtlPutRlsHqAlloc);
4969 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4971 /* Deallocate memory for "scheduled UE" Info */
4972 if (cell->rlsHqArr[idx].ueHqInfo != NULLP)
4974 /* Freeing with additional location, to accommodate TA
4975 scheduling along with maximum no of UEs per SF */
4976 /* ccpu00117052 - MOD - Passing double pointer
4977 for proper NULLP assignment*/
4978 rgSCHUtlFreeSBuf(inst,
4979 (Data **)(&(cell->rlsHqArr[idx].ueHqInfo)),
4980 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF));
4989 /***********************************************************
4991 * Func : rgSCHUtlGetSfAlloc
4993 * Desc : Utility Function to Allocate slot allocation information.
5002 **********************************************************/
5004 PUBLIC S16 rgSCHUtlGetSfAlloc
5009 PUBLIC S16 rgSCHUtlGetSfAlloc(cell)
5015 Inst inst = cell->instIdx;
5016 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5017 TRC2(rgSCHUtlGetSfAlloc);
5020 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5022 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5025 cell->sfAllocArr[idx].cellId = cell->cellId;
5027 /* Allocating with additional location, to accommodate
5028 TA scheduling along with maximum no of UEs per SF */
5030 /* Allocate memory for "scheduled UE" Info */
5031 if((rgSCHUtlAllocSBuf(inst,
5032 (Data**)&(cell->sfAllocArr[idx].ueInfo.allocInfo),
5033 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
5035 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5040 /* Allocate memory for "scheduled RAR" Info */
5041 if((rgSCHUtlAllocSBuf(inst,
5042 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo),
5043 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF))) != ROK)
5045 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5049 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5051 if((rgSCHUtlAllocSBuf(inst,
5052 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo),
5053 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)))) != ROK)
5055 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5064 rgSCHEmtcUtlGetSfAlloc(cell);
5071 /***********************************************************
5073 * Func : rgSCHUtlPutSfAlloc
5075 * Desc : Utility Function to deallocate slot allocation information.
5084 **********************************************************/
5086 PUBLIC S16 rgSCHUtlPutSfAlloc
5091 PUBLIC S16 rgSCHUtlPutSfAlloc(cell)
5097 Inst inst = cell->instIdx;
5098 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5099 TRC2(rgSCHUtlPutSfAlloc);
5102 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5104 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5107 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo != NULLP)
5109 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5111 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo != NULLP)
5112 /* ccpu00117052 - MOD - Passing double pointer
5113 for proper NULLP assignment*/
5114 rgSCHUtlFreeSBuf(inst,
5115 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].\
5117 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)));
5119 /* Deallocate memory for "scheduled RAR" Info */
5120 /* ccpu00117052 - MOD - Passing double pointer
5121 for proper NULLP assignment*/
5122 rgSCHUtlFreeSBuf(inst,
5123 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo)),
5124 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF));
5126 /* Deallocate memory for "scheduled UE" Info */
5127 if (cell->sfAllocArr[idx].ueInfo.allocInfo != NULLP)
5129 /* Freeing with additional location, to accommodate TA
5130 scheduling along with maximum no of UEs per SF */
5131 /* ccpu00117052 - MOD - Passing double pointer
5132 for proper NULLP assignment*/
5133 rgSCHUtlFreeSBuf(inst,
5134 (Data**)(&(cell->sfAllocArr[idx].ueInfo.allocInfo)),
5135 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF));
5140 rgSCHEmtcUtlPutSfAlloc(cell);
5146 /***********************************************************
5148 * Func : rgSCHUtlAllocSBuf
5150 * Desc : Utility Function to Allocate static buffer.
5151 * Memory allocated is assumed contiguous.
5157 * Notes: Caller doesnt need to raise the alarm in case of memory
5158 * allocation gets failed.
5162 **********************************************************/
5164 PUBLIC S16 rgSCHUtlAllocSBuf
5166 Inst inst, /* Instance of the invoking scheduler */
5167 Data **pData, /* Pointer of the data to be returned */
5168 Size size /* size */
5171 PUBLIC S16 rgSCHUtlAllocSBuf(inst, pData, size)
5172 Inst inst; /* Instance of the invoking scheduler */
5173 Data **pData; /* Pointer of the data to be returned */
5174 Size size; /* size */
5177 /* Moving alarm diagnostics to available scope */
5179 TRC2(rgSCHUtlAllocSBuf)
5181 /* Initialize the param to NULLP */
5184 /* May not be necessary for data performance path */
5192 /* allocate buffer */
5193 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5194 MS_BUF_ADD_ALLOC_CALLER();
5196 if (SGetSBuf(rgSchCb[inst].rgSchInit.region, rgSchCb[inst].rgSchInit.pool,
5197 pData, size) != ROK)
5199 RgUstaDgn dgn; /* Alarm diagnostics structure */
5200 dgn.type = LRG_USTA_DGNVAL_MEM;
5201 dgn.u.mem.region = rgSchCb[inst].rgSchInit.region;
5202 dgn.u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5203 /* Send an alarm to Layer Manager */
5204 rgSCHLmmStaInd(inst, LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
5205 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
5206 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG015, 0, "Unable to Allocate Buffer");
5207 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Unable to Allocate the Buffer");
5212 /* zero out the allocated memory */
5213 cmMemset((U8 *)*pData, 0x00, size);
5217 } /* end of rgSCHUtlAllocSBuf */
5222 * Fun: rgSCHUtlFreeSBuf
5224 * Desc: The argument to rgSCHUtlFreeSBuf() is a pointer to a block
5225 * previously allocated by rgSCHUtlAllocSBuf() and size. It
5226 * deallocates the memory.
5234 PUBLIC Void rgSCHUtlFreeSBuf
5236 Inst inst, /* Instance of the invoking scheduler */
5237 Data **data, /* pointer to data */
5238 Size size /* size */
5241 PUBLIC Void rgSCHUtlFreeSBuf(inst, data, size)
5242 Inst inst; /* Instance of the invoking scheduler */
5243 Data **data; /* pointer to data */
5244 Size size; /* size */
5250 TRC2(rgSCHUtlFreeSBuf)
5252 if ((data == NULLP) || (*data == NULLP) || (size == 0))
5258 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5259 MS_BUF_ADD_CALLER();
5261 /* Deallocate buffer */
5262 ret = SPutSBuf(rgSchCb[inst].rgSchInit.region,
5263 rgSchCb[inst].rgSchInit.pool, (*data), size);
5267 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG016, (ErrVal) 0,
5268 "rgSCHUtlFreeSBuf failed.\n");
5269 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHUtlFreeSBuf failed");
5273 /* ccpu00117052 - ADD - Assigning the pointer to NULLP */
5277 } /* end of rgSCHUtlFreeSBuf */
5283 * Fun: rgSCHUtlFreeWarningSiSeg
5285 * Desc: This is used to deallocate Warning SI Seg.
5294 PUBLIC Void rgSCHUtlFreeWarningSiSeg
5301 PUBLIC Void rgSCHUtlFreeWarningSiSeg(reg, pool, siPduLst)
5304 CmLListCp *siPduLst;
5310 TRC2(rgSCHUtlFreeWarningSiSeg)
5312 while (siPduLst->first != NULLP)
5314 node = siPduLst->first;
5315 pdu = (Buffer *)node->node;
5316 cmLListDelFrm(siPduLst, node);
5317 RGSCH_FREE_MSG(pdu);
5318 SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList));
5323 } /* end of rgSCHUtlFreeWarningSiSeg */
5328 * Fun: rgSCHUtlFreeWarningSiPdu
5330 * Desc: This is used to deallocate Warning SI PDU.
5339 PUBLIC Void rgSCHUtlFreeWarningSiPdu
5344 PUBLIC Void rgSCHUtlFreeWarningSiPdu(cell)
5350 RgSchWarningSiInfo *warningSi;
5351 RgSchWarningSiPdu *warningSiPdu;
5353 TRC2(rgSCHUtlFreeWarningSiPdu)
5355 warningSi = (RgSchWarningSiInfo *) cell->siCb.\
5356 siArray[cell->siCb.siCtx.siId-1].si;
5357 /* ccpu00136659: CMAS ETWS design changes */
5358 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5364 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5365 pdu = warningSiPdu->pdu;
5366 /* ccpu00136659: CMAS ETWS design changes */
5367 cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node);
5368 RGSCH_FREE_MSG(pdu);
5369 if(warningSi->warningSiMsg.segLstCp.count == 0)
5371 /* ccpu00136659: CMAS ETWS design changes */
5372 cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP;
5373 rgSCHUtlRgrWarningSiCfgCfm(cell->instIdx,
5374 rgSchCb[cell->instIdx].rgrSap->sapCfg.spId,
5375 cell->siCb.warningSi[warningSi->idx].siId,
5376 warningSi->warningSiMsg.transId, RGR_CFG_CFM_TX_COMPLETE);
5381 } /* end of rgSCHUtlFreeWarningSiPdu */
5386 * Fun: rgSCHUtlGetWarningSiPdu
5388 * Desc: This is used to get Warning SI PDU for Scheduling.
5397 PUBLIC Buffer *rgSCHUtlGetWarningSiPdu
5402 PUBLIC Buffer *rgSCHUtlGetWarningSiPdu(cell)
5406 RgSchWarningSiInfo *warningSi;
5407 RgSchWarningSiPdu *warningSiPdu;
5411 TRC2(rgSCHUtlGetWarningSiPdu)
5413 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5414 siArray[cell->siCb.siCtx.siId-1].si;
5415 /* ccpu00136659: CMAS ETWS design changes */
5416 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5419 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5420 pdu = warningSiPdu->pdu;
5427 } /* rgSCHUtlGetWarningSiPdu */
5432 * Fun: rgSCHUtlGetMcsAndNPrb
5434 * Desc: This is used to get mcs and nPrb value.
5443 PUBLIC S16 rgSCHUtlGetMcsAndNPrb
5451 PUBLIC S16 rgSCHUtlGetMcsAndNPrb(cell, nPrb, mcs, msgLen)
5458 RgSchWarningSiInfo *warningSi;
5459 RgSchWarningSiPdu *warningSiPdu;
5462 TRC2(rgSCHUtlGetMcsAndNPrb)
5464 if(cell->siCb.siCtx.warningSiFlag == FALSE)
5466 *mcs = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].mcs;
5467 *nPrb = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].nPrb;
5468 *msgLen = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].msgLen;
5472 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5473 siArray[cell->siCb.siCtx.siId-1].si;
5474 /* ccpu00136659: CMAS ETWS design changes */
5475 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5481 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5482 *mcs = warningSiPdu->mcs;
5483 *nPrb = warningSiPdu->nPrb;
5484 *msgLen = warningSiPdu->msgLen;
5489 } /* rgSCHUtlGetMcsAndNPrb */
5493 * Fun: rgSCHUtlCalMacAndPrb
5495 * Desc: This is used to Calculate mcs and nPrb value for SIB1 and SIs.
5504 PUBLIC S16 rgSCHUtlCalMcsAndNPrb
5512 PUBLIC S16 rgSCHUtlCalMcsAndNPrb(cell, nPrb, mcs, msgLen)
5522 TRC2(rgSCHUtlCalMcsAndNPrb)
5524 /*Get the nPrb and mcs parametr values */
5525 if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8))
5527 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "msgLen does "
5528 "not match any valid TB Size");
5533 if(cfgType == RGR_SI_CFG_TYPE_SIB1 || cfgType == RGR_SI_CFG_TYPE_SIB1_PWS)
5536 if(cell->siCb.crntSiInfo.sib1Info.sib1 == NULLP)
5538 cell->siCb.crntSiInfo.sib1Info.mcs = mcs;
5539 cell->siCb.crntSiInfo.sib1Info.nPrb = nPrb;
5540 cell->siCb.crntSiInfo.sib1Info.msgLen = msgLen;
5544 cell->siCb.newSiInfo.sib1Info.mcs = mcs;
5545 cell->siCb.newSiInfo.sib1Info.nPrb= nPrb;
5546 cell->siCb.newSiInfo.sib1Info.msgLen = msgLen;
5551 if(cfgType == RGR_SI_CFG_TYPE_SI)
5553 if(cell->siCb.crntSiInfo.siInfo[siId-1].si == NULLP &&
5554 !(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD))
5556 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5557 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5558 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5562 cell->siCb.newSiInfo.siInfo[siId-1].mcs = mcs;
5563 cell->siCb.newSiInfo.siInfo[siId-1].nPrb= nPrb;
5564 cell->siCb.newSiInfo.siInfo[siId-1].msgLen = msgLen;
5568 if(cfgType == RGR_SI_CFG_TYPE_SIB8_CDMA)
5570 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5571 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5572 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5579 /***********************************************************
5581 * Func : rgSCHUtlFillDgnParams
5583 * Desc : Utility Function to Fill Diagonostic params.
5591 **********************************************************/
5593 PUBLIC Void rgSCHUtlFillDgnParams
5600 PUBLIC Void rgSCHUtlFillDgnParams(inst, dgn, dgnType)
5607 TRC2(rgSCHUtlFillDgnParams)
5611 case LRG_USTA_DGNVAL_MEM:
5612 dgn->type = (U8) LRG_USTA_DGNVAL_MEM;
5613 dgn->u.mem.region = rgSchCb[inst].rgSchInit.region;
5614 dgn->u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5622 } /* end of rgSCHUtlFillDgnParams */
5624 /***********************************************************
5626 * Func : rgSCHUtlGetPstToLyr
5628 * Desc : Utility Function to get the pst structure to post a message to MAC
5634 * Notes: This function should be called while sending a msg from
5635 * scheduler instance to MAC
5639 **********************************************************/
5641 PUBLIC Void rgSCHUtlGetPstToLyr
5648 PUBLIC Void rgSCHUtlGetPstToLyr (pst, schCb, macInst)
5654 TRC2(rgSCHUtlGetPstToLyr);
5656 /* Only the needed params are filled */
5657 pst->region = schCb->rgSchInit.region;
5658 pst->pool = schCb->rgSchInit.pool;
5659 pst->srcInst = schCb->rgSchInit.inst+SCH_INST_START;
5660 pst->srcProcId = schCb->rgSchInit.procId;
5661 pst->dstProcId = schCb->rgSchInit.procId;
5663 pst->dstInst = macInst;
5664 pst->dstEnt = ENTRG;
5665 pst->srcEnt = ENTRG;
5667 pst->prior = PRIOR0;
5669 pst->route = RTESPEC;
5672 } /* end of rgSCHUtlGetPstToLyr */
5674 /** @brief This function fills in the common lc information to be sent to MAC
5678 * Function: rgSCHUtlFillRgInfCmnLcInfo
5679 * @param RgSchDlSf *sf,
5680 * @param RgInfSfAlloc *sfAlloc,
5681 * @param CmLteLcId lcId,
5682 * @param Bool sendInd
5689 PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo
5692 RgInfSfAlloc *sfAlloc,
5697 PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo(sf, sfAlloc, lcId, sendInd)
5699 RgInfSfAlloc *sfAlloc;
5704 TRC2(rgSCHUtlFillRgInfCmnLcInfo);
5706 if((sf->bch.tbSize)&&
5707 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCH_INFO))
5710 sfAlloc->cmnLcInfo.bchInfo.lcId = lcId;
5712 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCH_INFO;
5714 else if((sf->bcch.pdcch != NULLP)&&
5715 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCCH_INFO))
5717 sfAlloc->cmnLcInfo.bcchInfo.rnti = RGSCH_SI_RNTI;
5718 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.bcchInfo.dciInfo),
5719 &(sf->bcch.pdcch->dci));
5721 sfAlloc->cmnLcInfo.bcchInfo.lcId = lcId;
5722 sfAlloc->cmnLcInfo.bcchInfo.sndStatInd = sendInd;
5724 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCCH_INFO;
5726 else if((sf->pcch.pdcch != NULLP) &&
5727 !(sfAlloc->cmnLcInfo.bitMask & RGINF_PCCH_INFO))
5729 sfAlloc->cmnLcInfo.pcchInfo.rnti = RGSCH_P_RNTI;
5730 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.pcchInfo.dciInfo),
5731 &(sf->pcch.pdcch->dci));
5732 sfAlloc->cmnLcInfo.pcchInfo.lcId = lcId;
5733 sfAlloc->cmnLcInfo.bitMask |= RGINF_PCCH_INFO;
5738 /** @brief This function fills in the RAR information to be sent to MAC
5742 * Function: rgSCHUtlFillRgInfRarInfo
5744 * @param RgSchCellCb *cell
5745 * @param RgSchDlSf *sf
5746 * @param RgInfSfAlloc *sfAlloc
5752 PUBLIC S16 rgSCHUtlFillRgInfRarInfo
5755 RgInfSfAlloc *sfAlloc,
5759 PUBLIC S16 rgSCHUtlFillRgInfRarInfo(sf, sfAlloc, cell)
5761 RgInfSfAlloc *sfAlloc;
5770 RgInfRaRntiInfo *raRntiAlloc;
5772 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5774 TRC2(rgSCHUtlFillRgInfRarInfo);
5777 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
5779 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
5782 for(idx =0; idx < noRaRsps; idx++)
5784 if (sf->raRsp[idx].pdcch == NULLP)
5786 /* No further raResp Allocations. */
5789 /* Added Dl TB count for RACH Response transmission*/
5791 cell->dlUlTbCnt.tbTransDlTotalCnt++;
5793 raRntiAlloc = &(sfAlloc->rarInfo.raRntiInfo[idx]);
5794 raRntiAlloc->raRnti = sf->raRsp[idx].raRnti;
5795 raRntiAlloc->schdTbSz = sf->raRsp[idx].tbSz;
5796 raRntiAlloc->numCrnti = 0;
5797 rgSCHUtlFillPdschDciInfo(&(raRntiAlloc->dciInfo),
5798 &(sf->raRsp[idx].pdcch->dci));
5799 /* RACHO : fill backoff indicator information */
5800 raRntiAlloc->backOffInd = sf->raRsp[idx].backOffInd;
5802 /* Fill for contention free UEs*/
5803 lnkLst = &(sf->raRsp[idx].contFreeUeLst);
5804 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5807 ue = (RgSchUeCb *)tmp->node;
5809 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = ue->ueId;
5810 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = TRUE;
5811 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = ue->ul.rarGrnt.rapId;
5812 #ifndef MAC_5GTF_UPDATE
5813 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5815 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit =
5816 ue->ul.rarGrnt.cqiReqBit;
5818 /* SHASHAHNK ADD RIV CALC */
5819 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5820 ue->ul.rarGrnt.rbStart;
5821 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5822 ue->ul.rarGrnt.numRb;
5823 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5825 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5826 ue->ul.rarGrnt.iMcsCrnt;
5827 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta = ue->ul.rarGrnt.ta;
5828 raRntiAlloc->numCrnti++;
5829 cmLListDelFrm(lnkLst, &ue->ul.rarGrnt.raRspLnk);
5830 ue->ul.rarGrnt.raRspLnk.node = (PTR)NULLP;
5832 /* Fill for contention based UEs*/
5833 lnkLst = &(sf->raRsp[idx].raRspLst);
5835 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5837 while((NULLP != tmp) && ((RgSchRaCb *)tmp->node != NULLP))
5839 raCb = (RgSchRaCb *)tmp->node;
5841 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = raCb->tmpCrnti;
5842 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = FALSE;
5843 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = raCb->rapId;
5844 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.pres = TRUE;
5845 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.val = raCb->ta.val;
5846 #ifndef MAC_5GTF_UPDATE
5847 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5849 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = FALSE;
5851 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5852 raCb->msg3Grnt.rbStart;
5853 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5854 raCb->msg3Grnt.numRb;
5855 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5857 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5858 raCb->msg3Grnt.iMcsCrnt;
5859 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.delayBit =
5860 raCb->msg3Grnt.delayBit;
5861 /* For initial attaching UEs Aperiodic CQI need not be triggered */
5862 raRntiAlloc->numCrnti++;
5863 /* Search the next node */
5864 CM_LLIST_NEXT_NODE(lnkLst, tmp);
5867 sfAlloc->rarInfo.numRaRntis = idx;
5868 /* ccpu00132314-ADD-Update the tx power allocation info
5869 TODO-Need to add a check for max tx power per symbol */
5870 sfAlloc->rarInfo.txPwrOffset = cellDl->rarTxPwrOffset;
5873 } /* end of rgSCHUtlFillRgInfRarInfo */
5875 /** @brief This function fills in the pdsch data related allocation Info
5876 * from the pdcch DCI info.
5881 * Function: rgSCHUtlFillPdschDciInfo
5884 * - Depending upon the DCI Format, fill the appropriate fields.
5886 * @param [out] TfuPdschDciInfo *pdschDci
5887 * @param [in] TfuDciInfo *pdcchDci
5893 PUBLIC S16 rgSCHUtlFillPdschDciInfo
5895 TfuPdschDciInfo *pdsch,
5896 TfuDciInfo *pdcchDci
5899 PUBLIC S16 rgSCHUtlFillPdschDciInfo(pdsch, pdcchDci)
5900 TfuPdschDciInfo *pdsch;
5901 TfuDciInfo *pdcchDci;
5904 TRC2(rgSCHUtlFillPdschDciInfo)
5909 pdsch->format = pdcchDci->dciFormat;
5910 switch(pdcchDci->dciFormat)
5912 case TFU_DCI_FORMAT_1:
5913 pdsch->u.format1AllocInfo = pdcchDci->u.format1Info.allocInfo;
5915 case TFU_DCI_FORMAT_1A:
5916 if (pdcchDci->u.format1aInfo.isPdcchOrder == FALSE)
5918 pdsch->u.format1aAllocInfo = pdcchDci->u.format1aInfo.t.pdschInfo.allocInfo;
5921 case TFU_DCI_FORMAT_1B:
5922 pdsch->u.format1bAllocInfo = pdcchDci->u.format1bInfo.allocInfo;
5924 case TFU_DCI_FORMAT_1C:
5925 pdsch->u.format1cAllocInfo = pdcchDci->u.format1cInfo;
5927 case TFU_DCI_FORMAT_1D:
5928 pdsch->u.format1dAllocInfo = pdcchDci->u.format1dInfo.allocInfo;
5930 case TFU_DCI_FORMAT_2:
5931 pdsch->u.format2AllocInfo = pdcchDci->u.format2Info.allocInfo;
5933 case TFU_DCI_FORMAT_2A:
5934 pdsch->u.format2AAllocInfo = pdcchDci->u.format2AInfo.allocInfo;
5937 case TFU_DCI_FORMAT_B1:
5938 pdsch->u.formatB1Info = pdcchDci->u.formatB1Info;
5940 case TFU_DCI_FORMAT_B2:
5941 pdsch->u.formatB2Info = pdcchDci->u.formatB2Info;
5946 ret = rgSCHEmtcUtlFillPdschDciInfo(pdsch, pdcchDci);
5958 /* LTE_ADV_FLAG_REMOVED_START */
5960 * @brief This function resets temporary variables in Pool
5963 * Function: rgSchSFRResetPoolVariables
5965 * Invoked by: rgSCHSFRUtlTotalPoolInit
5967 * @param[in] RgSchCellCb* cell
5968 * @param[in] RgSubFrm* subFrm
5973 PUBLIC Void rgSchDSFRPwrCheck
5976 Bool *isAllUePwrHigh
5979 PRIVATE Void rgSchDSFRPwrCheck(sf, isAllUePwrHigh)
5981 Bool *isAllUePwrHigh;
5985 RgSchSFRPoolInfo *sfrCCPool;
5990 TRC2(rgSchDSFRPwrCheck);
5992 l = &sf->sfrTotalPoolInfo.ccPool;
5993 n = cmLListFirst(l);
5996 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
5997 if((sfrCCPool->poolstartRB == sfrCCPool->pwrHiCCRange.startRb) &&
5998 (sfrCCPool->poolendRB == sfrCCPool->pwrHiCCRange.endRb))
6005 *isAllUePwrHigh = TRUE;
6012 /* LTE_ADV_FLAG_REMOVED_END */
6013 /***********************************************************
6015 * Func : rgSCHUtlFillRgInfTbInfo
6017 * Desc : Utility Function to fill the allocation info of each Tb
6023 * Notes: This function should be called while sending a msg from
6024 * scheduler instance to MAC
6028 **********************************************************/
6030 PRIVATE Void rgSCHUtlFillRgInfTbInfo
6032 RgSchDlHqProcCb *hqP,
6033 RgInfUeAlloc *allocInfo,
6037 PRIVATE Void rgSCHUtlFillRgInfTbInfo (hqP, allocInfo, cell)
6038 RgSchDlHqProcCb *hqP;
6039 RgInfUeAlloc *allocInfo;
6045 RgInfUeTbInfo *tbInfo;
6047 /* LTE_ADV_FLAG_REMOVED_START */
6049 PRIVATE U32 tmpCnt = 0;
6050 Bool isAllUePwrHigh = FALSE;
6052 /* LTE_ADV_FLAG_REMOVED_END */
6053 RgSchDlLcCb *dlLcCb = NULLP;
6062 CmLteTimingInfo frm;
6064 /* Get Downlink slot */
6065 frm = cell->crntTime;
6066 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
6067 sf = rgSCHUtlSubFrmGet(cell, frm);
6068 /* Setting of fillCtrlPdu flag
6069 If both P-cell and S-cell are present,
6070 make TRUE for P-cell and FALSE for all s-cells
6071 For all other cases set TRUE */
6073 if ((rgSchCb[cell->instIdx].genCfg.forceCntrlSrbBoOnPCel) &&
6074 !RG_SCH_CMN_IS_PCELL_HQP(hqP))
6076 allocInfo->fillCtrlPdu = FALSE;
6080 allocInfo->fillCtrlPdu = TRUE;
6084 allocInfo->tbStrtIdx = -1;
6088 allocInfo->tbReqInfo.sCellHqPId = 0xff;
6089 rgSCHLaaHndlFillRgInfTbInfo(cell, hqP, allocInfo);
6092 /*TODO:REEMA: Check and fill the isRetx */
6093 for(tbCnt = 0; tbCnt < 2; tbCnt++)
6095 RgSchUeCb *ue = NULLP;
6096 /*Changed as a result of CR timer*/
6097 if ((hqP->hqE->ue != NULLP)/* &&
6098 ((hqP->tbInfo[tbCnt].lchSchdData[0].lcId != 0) || \
6099 (hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF))*/)
6102 allocInfo->rnti = ue->ueId;
6103 allocInfo->doa = hqP->hqE->ue->mimoInfo.doa;
6104 allocInfo->txMode = (TfuTxMode)(hqP->hqE->ue->mimoInfo.txMode);
6105 allocInfo->puschRptUsd = hqP->hqE->ue->mimoInfo.puschFdbkVld;
6106 allocInfo->puschPmiInfo = hqP->hqE->ue->mimoInfo.puschPmiInfo;
6107 if(hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF)
6109 hqP->tbInfo[tbCnt].taSnt = TRUE;
6112 if (RG_SCH_IS_PAPRSNT(ue,hqP->hqE->cell))
6114 /*update pA value */
6115 allocInfo->pa = (RG_SCH_CMN_GET_PA(ue,hqP->hqE->cell)).val;
6119 /* LTE_ADV_FLAG_REMOVED_START */
6120 /* If ABS is enabled, calculate resource used */
6121 if((0 == tbCnt) && (RGR_ENABLE == ue->cell->lteAdvCb.absCfg.status))
6123 /* For Macro count number resource used in Non-ABS SF */
6124 if(RGR_ABS_MUTE == ue->cell->lteAdvCb.absCfg.absPatternType)
6126 if(RG_SCH_ABS_ENABLED_NONABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6128 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6129 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6132 /* For pico count number resource used in ABS SF for ABS UE */
6133 else if(RGR_ABS_TRANSMIT == ue->cell->lteAdvCb.absCfg.absPatternType)
6135 if(RG_SCH_ABS_ENABLED_ABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6137 if(TRUE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe)
6139 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6140 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6147 /*if SFR is enabled*/
6148 allocInfo->isEnbSFR = (U8)RG_SCH_CMN_IS_SFR_ENB(ue->cell); /* KW fix for LTE_ADV */
6149 if((ue->cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) &&
6150 (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == FALSE))
6152 rgSchDSFRPwrCheck(sf, &isAllUePwrHigh);
6156 allocInfo->pa = (U8)ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; /* KW fix for LTE_ADV */
6157 if(tmpCnt++ == 100000)
6159 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6160 "DSFR::ll UEs can go HIGH, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6166 if (allocInfo->isEnbSFR)
6168 /*Update pA to Plow if it is cell-centred ,else pA will be pHigh*/
6169 if (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == TRUE)
6171 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6172 if(tmpCnt++ == 100000)
6174 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6175 "SFR::UE is CELL EDGE, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6182 if(TRUE == ue->lteAdvUeCb.isCCUePHigh)
6184 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6185 ue->lteAdvUeCb.isCCUePHigh = FALSE;
6189 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pLow;
6190 if(tmpCnt++ == 100000)
6192 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6193 "SFR::UE is CELL CENTRE, PLow(%d) for UE(%d)\n",allocInfo->pa, ue->ueId);
6200 /* LTE_ADV_FLAG_REMOVED_END */
6208 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
6211 allocInfo->pdcchRnti = hqP->hqE->raCb->tmpCrnti;
6213 allocInfo->rnti = hqP->hqE->raCb->tmpCrnti;
6215 /*ccpu00132314-ADD-Use a default pA value
6217 allocInfo->pa = cellDl->msg4pAVal;
6221 /* If TB Is scheduled for this SF */
6222 if(hqP->tbInfo[tbCnt].state == HQ_TB_WAITING)
6224 if (allocInfo->tbStrtIdx == -1){
6225 allocInfo->tbStrtIdx = tbCnt;
6227 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6228 &(hqP->pdcch->dci));
6232 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6233 &(hqP->pdcch->dci));
6235 else if ((ue) && (ue->dl.spsOccPdcch.rnti == ue->spsRnti))
6237 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6238 &(ue->dl.spsOccPdcch.dci));
6240 #endif /* ifndef LTEMAC_SPS */
6245 allocInfo->pdcchRnti = hqP->pdcch->rnti;
6249 allocInfo->pdcchRnti = ue->spsRnti;
6252 tbInfo = &(allocInfo->tbInfo[tbCnt]);
6253 allocInfo->nmbOfTBs++;
6254 allocInfo->hqProcId = hqP->procId;
6255 allocInfo->tbInfo[tbCnt].schdTbSz = hqP->tbInfo[tbCnt].tbSz;
6257 tbInfo->disTb = FALSE;
6258 if(!(hqP->tbInfo[tbCnt].txCntr))
6261 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6262 rgSCHLaaSCellEnabled(cell))))
6265 hqP->tbInfo[tbCnt].txCntr++;
6267 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6269 tbInfo->schdDat[idx].lcId =\
6270 hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6271 tbInfo->schdDat[idx].numBytes =\
6272 hqP->tbInfo[tbCnt].lchSchdData[idx].schdData;
6275 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6278 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6281 RG_SCH_CMN_DL_GET_HDR_EST(dlLcCb, rlcHdrEstmt);
6282 /* Update the totalBo with the scheduled bo */
6283 (hqP->hqE->ue->totalBo <= tbInfo->schdDat[idx].numBytes - rlcHdrEstmt)?\
6284 (hqP->hqE->ue->totalBo = 0):\
6285 (hqP->hqE->ue->totalBo -= tbInfo->schdDat[idx].numBytes-rlcHdrEstmt);
6289 prbUsed = ((hqP->tbInfo[tbCnt].\
6290 lchSchdData[idx].schdData *
6291 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6292 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6293 dlLcCb->qciCb->dlPrbCount += prbUsed;
6294 if(dlLcCb->qciCb->qci > 0)
6296 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6298 #endif /* RRM_RBC_Y */
6301 //if(!(hqP->hqE->ue->pfsStats.lcStats[lcId-1].isLcCntSet))
6305 if (hqP->hqE->ue->cell == hqP->hqE->cell)
6307 idx = RGSCH_PCELL_INDEX;
6311 idx = RG_SCH_GET_SCELL_INDEX((hqP->hqE->ue), (hqP->hqE->cell));
6313 hqP->hqE->ue->pfsStats.lcStats[lcId-1].ueSchdOcc[idx]++;
6314 hqP->hqE->ue->pfsStats.lcStats[lcId-1].perRefresh[ue->pfsStats.lcStats[lcId-1].lastIdx].lcSchdOcc++;
6321 /* Added Dl TB count for SRB/DRB data transmission*/
6323 cell->dlUlTbCnt.tbTransDlTotalCnt++;
6325 tbInfo->ta.pres = hqP->tbInfo[tbCnt].schdTa.pres;
6326 tbInfo->ta.val = hqP->tbInfo[tbCnt].schdTa.val;
6328 tbInfo->sCellActCe = hqP->tbInfo[tbCnt].schdSCellActCe;
6330 tbInfo->numSchLch = hqP->tbInfo[tbCnt].numLch;
6331 if(!(hqP->tbInfo[tbCnt].numLch))
6333 tbInfo->schdDat[tbInfo->numSchLch].numBytes= hqP->tbInfo[tbCnt].tbSz;
6334 /* Fix: If only TA is scheduled, use some dummy LCID */
6335 if (tbInfo->ta.pres)
6336 tbInfo->schdDat[tbInfo->numSchLch].lcId = RG_TA_LCID;
6339 tbInfo->contResCe = hqP->tbInfo[tbCnt].contResCe;
6340 tbInfo->isReTx = FALSE;
6345 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6346 rgSCHLaaSCellEnabled(cell))))
6349 hqP->tbInfo[tbCnt].txCntr++;
6351 tbInfo->isReTx = TRUE;
6353 /* As per 36.314, harq retransmission also considered for
6354 * prb utilization calculation*/
6355 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6360 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6363 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6366 prbUsed = ((hqP->tbInfo[tbCnt].\
6367 lchSchdData[idx].schdData *
6368 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6369 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6370 if(dlLcCb->qciCb->qci > 0)
6372 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6384 rgSCHLaaResetDlHqProcCb(hqP);
6389 /***********************************************************
6391 * Func : rgSCHUtlFillRgInfUeInfo
6393 * Desc : Utility Function to fill the allocation info of Ue
6394 * : MIMO : Filling 2TB's of each UE
6399 * Notes: This function should be called while sending a msg from
6400 * scheduler instance to MAC
6404 **********************************************************/
6407 PUBLIC Void rgSCHUtlFillRgInfUeInfo
6411 CmLListCp *dlDrxInactvTmrLst,
6412 CmLListCp *dlInActvLst,
6413 CmLListCp *ulInActvLst
6416 PUBLIC Void rgSCHUtlFillRgInfUeInfo (sf,cell, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
6420 CmLListCp *dlDrxInactvTmrLst;
6421 CmLListCp *dlInActvLst;
6422 CmLListCp *ulInActvLst;
6425 RgInfSfAlloc *sfAlloc;
6426 CmLListCp *lnkLst; /* lnkLst assignment */
6429 RgSchUeCb *ue = NULLP;
6430 RgInfUeInfo *ueInfo = NULLP;
6431 RgInfUeAlloc *ueAlloc = NULLP;
6432 RgSchDlHqProcCb *hqCb = NULLP;
6434 /* Since Msg4 is sched only on PCELL, use cell arg's sfAllocArr */
6435 sfAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
6436 ueInfo = &(sfAlloc->ueInfo);
6437 ueAlloc = sfAlloc->ueInfo.allocInfo;
6439 lnkLst = &(sf->msg4HqPLst);
6440 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6443 printf("5GTF_ERROR MSG4 Consolidation\n");
6444 hqCb = (RgSchDlHqProcCb *)(tmp->node);
6445 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6447 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], cell);
6453 if((!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) && (ue->isDrxEnabled))
6455 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6456 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6462 lnkLst = &(sf->ueLst);
6463 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6466 #if defined (TENB_STATS) && defined (RG_5GTF)
6467 cell->tenbStats->sch.dl5gtfPdschCons++;
6469 ue = (RgSchUeCb *)(tmp->node);
6470 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6472 hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first;
6475 hqCb = (RgSchDlHqProcCb *)hqPNode->node;
6476 hqPNode = hqPNode->next;
6478 sfAlloc = &(hqCb->hqE->cell->sfAllocArr[hqCb->hqE->cell->crntSfIdx]);
6479 ueInfo = &(sfAlloc->ueInfo);
6480 ueAlloc = sfAlloc->ueInfo.allocInfo;
6482 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes],
6485 if(ue->isDrxEnabled)
6487 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6488 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6493 if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE)
6495 /*If remaining BO is left then increment the count*/
6499 /* Check if trigger for Activation is met or not */
6500 if(rgSCHIsActvReqd(cell, ue))
6503 /*Passing primary cell*/
6504 rgSCHSCellSelectAndActDeAct(ue->cell, ue, RGR_SCELL_ACT);
6509 /*If remaining BO is 0 then reset the count*/
6517 } /* end of rgSCHUtlFillRgInfUeInfo */
6521 /** @brief This function shall update the scheduler with the CEs and data rcvd
6525 * Function: rgSCHUtlUpdSch
6528 * - Collate the information of all the SDUs received and inform the
6529 * scheduler rgSCHDataRcvd
6530 * - Send Data indication to the higher layer with the dedicated data
6531 * (rgUIMSndDedDatInd)
6532 * - Inform scheduler with any MAC CEs if present.
6534 * @param [in] RgCellCb *cellCb
6535 * @param [in] RgUeCb *ueCb
6536 * @param [in] RgMacPdu *pdu
6537 * @param [in] RgSchErrInfo *err
6543 PUBLIC S16 rgSCHUtlUpdSch
6545 RgInfSfDatInd *subfrmInfo,
6546 RgSchCellCb *cellCb,
6552 PUBLIC S16 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err)
6553 RgInfSfDatInd *subfrmInfo;
6554 RgSchCellCb *cellCb;
6562 TRC2(rgSCHUtlUpdSch);
6565 if (RGSCH_UL_SPS_ACT_PRSENT & pdu->ceInfo.bitMask)
6567 /* SPS to be activated due to data on SPS LCG ID*/
6568 rgSCHUtlSpsActInd(cellCb, ueCb, pdu->ceInfo.spsSduSize);
6571 /* TODO : Temp Fix for crash due to UL SDU corruption*/
6572 if (RGSCH_PHR_CE_PRSNT & pdu->ceInfo.bitMask)
6575 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6576 if ((ret = rgSCHUtlUpdPhr(cellCb, ueCb, pdu->ceInfo.ces.phr, err)) != ROK)
6579 /* Note: Order of indication to Sch now is
6580 * 1st Indicate the DataInd info for each LCG's
6581 * 2nd Update the BSR reports received along with data
6582 * this is to make sure the effBsr is updated to the latest BSR
6585 cellCb->sc.apis->rgSCHUpdUeDataIndLcg(cellCb, ueCb, pdu);
6587 #ifndef MAC_5GTF_UPDATE
6588 if (RGSCH_TRUNC_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6590 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6591 /*ccpu00129922 - MOD - Deleted return value
6592 * checking since it returns void*/
6593 rgSCHUtlUpdBsrTrunc (cellCb, ueCb,
6594 (U8)(pdu->ceInfo.ces.bsr.truncBsr >> 6),
6595 (U8)(pdu->ceInfo.ces.bsr.truncBsr & 0x3F), err);
6599 if (RGSCH_SHORT_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6601 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6602 /*ccpu00129922 - MOD - Deleted return value
6603 checking since it returns void*/
6604 rgSCHUtlUpdBsrShort (cellCb, ueCb,
6605 (U8)(pdu->ceInfo.ces.bsr.shortBsr >> 6),
6606 (U8)(pdu->ceInfo.ces.bsr.shortBsr & 0x3F), err);
6610 if (RGSCH_LONG_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6612 if (RGSCH_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6615 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6616 /*ccpu00129922 - MOD - Deleted return value
6617 checking since it returns void*/
6618 rgSCHUtlUpdBsrLong (cellCb, ueCb,
6619 pdu->ceInfo.ces.bsr.longBsr.bs1,
6620 pdu->ceInfo.ces.bsr.longBsr.bs2,
6621 pdu->ceInfo.ces.bsr.longBsr.bs3,
6622 pdu->ceInfo.ces.bsr.longBsr.bs4,
6625 #ifndef MAC_5GTF_UPDATE
6632 } /* end of rgSCHUtlUpdSch */
6635 * @brief Handler for Updating Bo received in StaRsp
6639 * Function : rgSCHUtlAddUeToCcchSduLst
6641 * This function shall be invoked once it receives staRsp on CCCH
6643 * @param[in] RgSchCellCb *cell
6644 * @param[in] RgSchUeCb *ueCb
6649 PUBLIC S16 rgSCHUtlAddUeToCcchSduLst
6655 PUBLIC S16 rgSCHUtlAddUeToCcchSduLst(cell, ueCb)
6660 RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb, cell);
6661 RgSchDlHqProcCb *hqP = (RgSchDlHqProcCb *)ueDl->proc;
6662 TRC2(rgSCHUtlAddUeToCcchSduLst);
6664 /* Temp Guard: For back to back CCCH SDU BO
6665 * twice. Hence an extra guard. If already added to scheduling
6666 * queue or if scheduled and waiting for HQ FDBK, ignore */
6667 if ((ueCb->ccchSduLnk.node) ||
6668 ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
6669 ((hqP != NULLP) && (hqP->hqE->ccchSduProc))))
6671 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unexpected CCCH SDU BO",
6676 ueCb->ccchSduLnk.node = (PTR)(ueCb);
6677 cmLListAdd2Tail(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
6685 * Function : rgSCHUtlUpdtBo
6687 * This function shall be invoked once it receives staRsp on CCCH
6689 * @param[in] RgSchCellCb *cell
6690 * @param[in] RgRguCmnStaRsp *staRsp
6695 PUBLIC S16 rgSCHUtlUpdtBo
6698 RgInfCmnBoRpt *staRsp
6701 PUBLIC S16 rgSCHUtlUpdtBo(cell, staRsp)
6703 RgInfCmnBoRpt *staRsp;
6707 TRC2(rgSCHUtlUpdtBo)
6710 if ((ueCb = rgSCHDbmGetUeCb(cell, staRsp->u.rnti)) == NULLP)
6712 /* Handle Ue fetch failure */
6713 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid UEID:%d",staRsp->u.rnti);
6716 /* Update Bo in ueCb */
6717 ueCb->dlCcchInfo.bo = (U32)(staRsp->bo);
6721 rgSCHUtlAddUeToEmtcCcchSduLst(cell,ueCb);
6726 rgSCHUtlAddUeToCcchSduLst(cell, ueCb);
6730 } /* rgSCHUtlUpdtBo */
6736 * Function : rgSCHUtlHndlCcchBoUpdt
6738 * This function shall fetch the raCb with the given rnti and ask RAM to
6742 * @param[in] RgSchCellCb *cell
6743 * @param[in] RgInfCmnBoRpt *boRpt
6749 PUBLIC S16 rgSCHUtlHndlCcchBoUpdt
6752 RgInfCmnBoRpt *boRpt
6755 PUBLIC S16 rgSCHUtlHndlCcchBoUpdt(cell, boRpt)
6757 RgInfCmnBoRpt *boRpt;
6763 TRC2(rgSCHUtlHndlCcchBoUpdt);
6765 if ((raCb = rgSCHDbmGetRaCb(cell, boRpt->u.rnti)) == NULLP)
6768 /* CR timer implementation changes*/
6769 /*If no raCb, schedule ueCb, ueCb is extracted in rgSCHUtlUpdtBo*/
6770 RETVALUE(rgSCHUtlUpdtBo(cell, boRpt));
6772 /* Handle RaCb fetch failure */
6773 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6774 "Invalid RNTI:%d to fetch raCb",boRpt->u.rnti);
6781 /*Fix: If RaCb exists, then MSG4 is not completed yet*/
6782 /*Check if guard timer has expired, if not CR CE + CCCH SDU will be scheduled*/
6783 if((raCb->contResTmrLnk.node != NULLP) && \
6784 (raCb->schdLnk.node == NULLP) && (raCb->dlHqE->msg4Proc == NULLP))
6787 /*if contention resolution timer left ,Stop the Contention Resolution Guard Timer ,
6788 add in toBeSchduled list and update the Bo */
6789 if(TRUE == raCb->isEmtcRaCb)
6791 rgSCHRamEmtcUpdtBo(cell, raCb, boRpt);
6796 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
6797 raCb->contResTmrLnk.node=NULLP;
6798 rgSCHRamUpdtBo(cell, raCb, boRpt);
6803 /*Fix:Guard timer has expired */
6804 /*Update the BO in UE CB but dont add it to the scheduling list.
6805 *Should be added to the list after MSG4 completion*/
6806 if ((ueCb = rgSCHDbmGetUeCb(cell, boRpt->u.rnti)) == NULLP)
6808 /* Handle Ue fetch failure */
6809 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RNTI:%d",boRpt->u.rnti);
6812 /* Update Bo in ueCb */
6813 ueCb->dlCcchInfo.bo = (U32)(boRpt->bo);
6817 rgSCHRamUpdtBo(cell, raCb, boRpt);
6821 } /* rgSCHUtlHndlCcchBoUpdt */
6824 * @brief Validates BO received for BCCH or PCCH.
6828 * Function : rgSCHUtlGetAllwdCchTbSz
6830 * This function shall return the tbSz equal to or
6831 * the nearest greater value for a given bo.
6832 * If no such value found return -1. The nPrb value is
6837 * @param[out] U8 *nPrb
6843 PUBLIC S32 rgSCHUtlGetAllwdCchTbSz
6850 PUBLIC S32 rgSCHUtlGetAllwdCchTbSz(bo, nPrb, mcs)
6860 TRC2(rgSCHUtlGetAllwdCchTbSz);
6862 for (lt = 0, rt = 43; lt <= rt;)
6865 if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz == bo)
6867 *nPrb = rgSchUtlBcchPcchTbSzTbl[cn].rbIndex;
6868 *mcs = rgSchUtlBcchPcchTbSzTbl[cn].mcs;
6869 RETVALUE(rgSchUtlBcchPcchTbSzTbl[cn].tbSz);
6871 else if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz < bo)
6880 *nPrb = rgSchUtlBcchPcchTbSzTbl[lt].rbIndex;
6881 *mcs = rgSchUtlBcchPcchTbSzTbl[lt].mcs;
6882 RETVALUE(rgSchUtlBcchPcchTbSzTbl[lt].tbSz);
6886 * @brief Handler for BO Updt received for BCCH or PCCH.
6890 * Function : rgSCHUtlHndlBcchPcchBoUpdt
6892 * This function shall store the buffer and time to transmit in lcCb
6895 * @param[in] RgSchCellCb *cell
6896 * @param[in] RgInfCmnBoRpt *boRpt
6902 PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt
6905 RgInfCmnBoRpt *boUpdt
6908 PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt(cell, boUpdt)
6910 RgInfCmnBoRpt *boUpdt;
6913 RgSchClcDlLcCb *dlLc;
6914 RgSchClcBoRpt *boRpt;
6915 Inst inst = cell->instIdx;
6919 TRC2(rgSCHUtlHndlBcchPcchBoUpdt);
6921 dlLc = rgSCHDbmGetBcchOnBch(cell);
6924 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6925 "No Logical Channel dlLc is NULLP for RNTI:%d LCID:%d",boUpdt->u.rnti,boUpdt->lcId);
6928 if (boUpdt->lcId != dlLc->lcId)
6930 /* Added for dropping paging Message*/
6932 if ((rgSCHChkBoUpdate(cell,boUpdt))== ROK) /* Checking if received BO falls within the window of 5120 slots*/
6934 if (rgSCHUtlGetAllwdCchTbSz(boUpdt->bo*8, &nPrb, &mcs)
6937 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"[%ld]BO: does not match any "
6938 "valid TB Size RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6941 }/*end of rgSCHChkBoUpdate*/
6947 if ((dlLc = rgSCHDbmGetCmnLcCb(cell, boUpdt->lcId)) == NULLP)
6949 /* Handle lcCb fetch failure */
6950 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6951 "LCID:%d Invalid for RNTI:%d",boUpdt->lcId,boUpdt->u.rnti);
6954 if (((rgSCHUtlAllocSBuf(inst, (Data **)(&boRpt), sizeof(RgSchClcBoRpt))) ==RFAILED) ||
6957 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, "Allocation of common bo %dreport "
6958 "failed RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6962 boRpt->bo = boUpdt->bo;
6964 boRpt->timeToTx = boUpdt->u.timeToTx;
6967 if(cell->emtcEnable)
6969 boRpt->emtcDIReason = boUpdt->emtcDIReason;
6970 boRpt->pnb = boUpdt->pnb;
6973 RG_SCH_ADD_TO_CRNT_TIME(boRpt->timeToTx,
6974 boRpt->maxTimeToTx, cell->siCfg.siWinSize)
6975 if((NULLP != dlLc) && (dlLc->si))
6977 boRpt->retxCnt = cell->siCfg.retxCnt;
6983 rgSCHDbmInsCmnLcBoRpt(dlLc, boRpt);
6986 } /* rgSCHUtlHndlBcchPcchBoUpdt */
6989 * @brief API for sending bind confirm from Scheduler instance to RRM
6993 * Function: rgSCHUtlRgrBndCfm
6995 * This API is invoked to send bind confirm from Scheduler instance to RRM.
6996 * This API fills in Pst structure and SAP Ids and invokes
6997 * bind confirm API towards RRM.
6999 * @param[in] SuId suId
7000 * @param[in] U8 status
7006 PUBLIC S16 rgSCHUtlRgrBndCfm
7013 PUBLIC S16 rgSCHUtlRgrBndCfm(instId, suId, status)
7021 TRC2(rgSCHUtlRgrBndCfm)
7024 ret = RgUiRgrBndCfm(&rgSchCb[instId].rgrSap[suId].sapCfg.sapPst, rgSchCb[instId].rgrSap[suId].sapCfg.suId, status);
7027 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrBndCfm: RgUiRgrBndCfm Failed ");
7031 } /* rgSCHUtlRgrBndCfm*/
7034 * @brief API for sending bind confirm from Scheduler instance to RRM via RGM
7039 * Function: rgSCHUtlRgmBndCfm
7041 * This API is invoked to send bind confirm from Scheduler instance to RRM.
7042 * This API fills in Pst structure and SAP Ids and invokes
7044 * @param[in] SuId suId
7045 * @param[in] U8 status
7051 PUBLIC S16 rgSCHUtlRgmBndCfm
7058 PUBLIC S16 rgSCHUtlRgmBndCfm(instId, suId, status)
7066 TRC2(rgSCHUtlRgmBndCfm)
7069 ret = RgUiRgmBndCfm(&rgSchCb[instId].rgmSap[suId].sapCfg.sapPst, rgSchCb[instId].rgmSap[suId].sapCfg.suId, status);
7072 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgmBndCfm: RgUiRgrBndCfm Failed ");
7076 } /* rgSCHUtlRgmBndCfm*/
7081 * @brief API for sending configuration confirm from Scheduler to DU APP
7085 * Function: schSendCfgCfm
7087 * This API is invoked to send configuration confirm from Scheduler to DU
7090 * @param[in] Pst pst
7091 * @param[in] RgrCfgTransId transId
7092 * @param[in] U8 status
7098 PUBLIC S16 schSendCfgCfm
7102 RgrCfgTransId transId,
7106 PUBLIC S16 schSendCfgCfm(reg, pool, transId, status)
7109 RgrCfgTransId transId;
7117 cmMemset((U8 *)(&cfmPst), 0, sizeof(Pst));
7119 cfmPst.srcEnt = (Ent)ENTDUAPP;
7120 cfmPst.srcInst = (Inst) 0;
7121 cfmPst.srcProcId = SFndProcId();
7122 cfmPst.dstEnt = (Ent)ENTRG;
7123 cfmPst.dstInst = (Inst) 0;
7124 cfmPst.dstProcId = SFndProcId();
7125 cfmPst.selector = ODU_SELECTOR_LC;
7126 cfmPst.region = reg;
7129 if(RgUiRgrCfgCfm(&cfmPst,transId, status) != ROK)
7131 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"schSendCfgCfm: RgUiRgrCfgCfm Failed");
7132 printf("\nschSendCfgCfm: RgUiRgrCfgCfm Failed ");
7136 } /* schSendCfgCfm*/
7139 * @brief API for sending TTI indication from Scheduler to RRM.
7143 * Function: rgSCHUtlRgrTtiInd
7145 * This API is invoked to send TTI indication from Scheduler instance to RRM.
7146 * This API fills in Pst structure and RgrTtiIndInfo
7148 * @param[in] cell RgSchCellCb
7149 * @param[in] CmLteTimingInfo status
7155 PUBLIC S16 rgSCHUtlRgrTtiInd
7158 RgrTtiIndInfo *rgrTti
7161 PUBLIC S16 rgSCHUtlRgrTtiInd(cell, rgrTti)
7163 RgrTtiIndInfo *rgrTti;
7167 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
7169 extern Bool g_usettitmr;
7170 extern Void mtTmrHdlrPublic(void);
7173 TRC2(rgSCHUtlRgrTtiInd)
7176 rgrSap = cell->rgrSap;
7177 if (rgrSap->sapSta.sapState != LRG_BND)
7179 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
7180 "rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ",
7181 rgrSap->sapSta.sapState);
7184 RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst),
7185 cell->rgrSap->sapCfg.suId, rgrTti);
7193 } /* rgSCHUtlRgrTtiInd*/
7195 /** @brief This function is called by rgMacSchSfRecpInd. This function invokes the
7196 * scheduler with the information of the received Data and any Control Elements
7204 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
7206 * - If UE exists then update the Schduler with any MAC CEs if present.
7207 * - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3
7209 * @param [in] RgSchCellCb *cellCb
7210 * @param [in] RgSchUeCb *ueCb
7211 * @param [in] CmLteRnti rnti
7212 * @param [in] RgMacPdu *pdu
7213 * @param [in] RgSchErrInfo *err
7220 PUBLIC S16 rgSCHUtlProcMsg3
7222 RgInfSfDatInd *subfrmInfo,
7223 RgSchCellCb *cellCb,
7230 PUBLIC S16 rgSCHUtlProcMsg3 (subfrmInfo, cellCb, ueCb, rnti, pdu, err)
7231 RgInfSfDatInd *subfrmInfo;
7232 RgSchCellCb *cellCb;
7242 TRC2(rgSCHUtlProcMsg3)
7245 /* must have an raCb for this case */
7246 raCb = rgSCHDbmGetRaCb (cellCb, rnti);
7249 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, "RNTI:%d Received MSG3, unable to "
7254 /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that
7255 * effBsr of current case only will be considered in scheduling of ContResLst*/
7256 ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err);
7259 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Processing failed in the RAM "
7263 /* if ueCb is present */
7266 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err);
7272 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7273 * scheduler with the information of the received Data.
7277 * Function: rgSCHUtlSpsRelInd
7282 * @param [in] RgSchCellCb *cellCb
7283 * @param [in] RgSchUeCb *ueCb
7284 * @param [in] Bool *isExplRel
7291 PUBLIC S16 rgSCHUtlSpsRelInd
7293 RgSchCellCb *cellCb,
7298 PUBLIC S16 rgSCHUtlSpsRelInd (cellCb, ueCb, isExplRel)
7299 RgSchCellCb *cellCb;
7304 TRC2(rgSCHUtlSpsRelInd);
7305 cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel);
7307 } /* end of rgSCHUtlSpsRelInd */
7310 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7311 * scheduler with the information of the received Data.
7315 * Function: rgSCHUtlSpsActInd
7320 * @param [in] RgSchCellCb *cellCb
7321 * @param [in] RgSchUeCb *ueCb
7322 * @param [in] U16 spsSduSize
7329 PUBLIC S16 rgSCHUtlSpsActInd
7331 RgSchCellCb *cellCb,
7336 PUBLIC S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize)
7337 RgSchCellCb *cellCb;
7342 TRC2(rgSCHUtlSpsActInd);
7343 cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize);
7345 } /* end of rgSCHUtlSpsActInd */
7348 #endif /* LTEMAC_SPS */
7352 * @brief This API is invoked to send uplink group power control request to PHY.
7356 * Function : rgSCHUtlTfuGrpPwrCntrlReq
7358 * This API is invoked to send uplink group power control request to PHY.
7359 * It fills in the Pst structure, spId value and invokes group power
7360 * control request primitive at TFU.
7362 * @param[in] TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7368 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq
7372 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7375 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq(inst, sapId, grpPwrCntrlReq)
7378 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq;
7382 RgSchLowSapCb *tfuSap;
7385 TRC2(rgSCHUtlTfuGrpPwrCntrlReq);
7387 /* Get the lower SAP control block from the layer control block. */
7388 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7389 if (tfuSap->sapSta.sapState != LRG_BND)
7391 RLOG_ARG1(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7392 "rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState);
7395 cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
7396 if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK)
7398 RLOG_ARG0(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7399 "rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed");
7402 } /* rgSCHUtlTfuGrpPwrCntrlReq */
7406 * @brief This API is invoked to send Control Info to PHY.
7410 * Function : rgSCHUtlTfuCntrlReq
7412 * This API is invoked to send Control Info to PHY. It
7413 * fills in the Pst structure, spId value and invokes Cntrl
7414 * request primitive at TFU.
7416 * @param[in] TfuCntrlReqInfo *cntrlReq
7422 PUBLIC S16 rgSCHUtlTfuCntrlReq
7426 TfuCntrlReqInfo *cntrlReq
7429 PUBLIC S16 rgSCHUtlTfuCntrlReq(inst, sapId, cntrlReq)
7432 TfuCntrlReqInfo *cntrlReq;
7436 RgSchLowSapCb *tfuSap;
7438 TRC2(rgSCHUtlTfuCntrlReq)
7440 /* Get the lower SAP control block from the layer control block. */
7441 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7444 if (tfuSap->sapSta.sapState != LRG_BND)
7446 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Lower SAP not bound (%d) ",
7447 tfuSap->sapSta.sapState);
7448 RGSCH_FREE_MEM(cntrlReq);
7453 /* Using local variable for pst is unnecessary - for optimization */
7454 if((ret = RgLiTfuCntrlReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7457 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Call to RgLiTfuCntrlReq() failed");
7460 } /* rgSCHUtlTfuCntrlReq*/
7463 /* FOR ACK NACK REP */
7466 * @brief This API is invoked to tell the DL Scheduler to add the UE back into
7467 * its scheduling queues.
7471 * Function : rgSCHUtlDlActvtUe
7473 * This API is invoked from Measurement gap moduled.
7475 * @param[in] RgSchCellCb *cell
7476 * @param[in] RgSchUeCb *ueCb
7483 PUBLIC S16 rgSCHUtlDlActvtUe
7489 PUBLIC S16 rgSCHUtlDlActvtUe(cell, ue)
7494 TRC2(rgSCHUtlDlActvtUe);
7495 cell->sc.apis->rgSCHActvtDlUe(cell, ue);
7500 * @brief This API is invoked to tell the UL Scheduler to add the UE back into
7501 * its scheduling queues.
7505 * Function : rgSCHUtlUlActvtUe
7507 * This API is invoked from Measurement gap moduled.
7509 * @param[in] RgSchCellCb *cell
7510 * @param[in] RgSchUeCb *ueCb
7517 PUBLIC S16 rgSCHUtlUlActvtUe
7523 PUBLIC S16 rgSCHUtlUlActvtUe(cell, ue)
7528 TRC2(rgSCHUtlUlActvtUe);
7529 cell->sc.apis->rgSCHActvtUlUe(cell, ue);
7534 * @brief This API is invoked to send Reception Request Info to PHY.
7538 * Function : rgSCHUtlTfuRecpReq
7540 * This API is invoked to send Reception Request Info to PHY. It
7541 * fills in the Pst structure, spId value and invokes Reception
7542 * request primitive at TFU.
7544 * @param[in] TfuRecpReqInfo *recpReq
7550 PUBLIC S16 rgSCHUtlTfuRecpReq
7554 TfuRecpReqInfo *recpReq
7557 PUBLIC S16 rgSCHUtlTfuRecpReq(inst, sapId, recpReq)
7560 TfuRecpReqInfo *recpReq;
7564 RgSchLowSapCb *tfuSap;
7566 TRC2(rgSCHUtlTfuRecpReq)
7568 /* Get the lower SAP control block from the layer control block. */
7569 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7572 if (tfuSap->sapSta.sapState != LRG_BND)
7574 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Lower SAP not bound (%d) ",
7575 tfuSap->sapSta.sapState);
7576 RGSCH_FREE_MEM(recpReq);
7581 /* Using local variable for pst is unnecessary - for optimization */
7582 if((ret = RgLiTfuRecpReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7585 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Call to RgLiTfuRecpReq() failed");
7588 } /* rgSCHUtlTfuRecpReq */
7590 /** @brief This function Validates the SAP information received along with the
7591 * primitive from the lower layer.
7593 * Function: rgSCHUtlValidateTfuSap
7595 * Validates SAP information.
7596 * @param suId The SAP Id
7602 PUBLIC S16 rgSCHUtlValidateTfuSap
7608 PUBLIC S16 rgSCHUtlValidateTfuSap(inst, suId)
7613 RgSchLowSapCb *tfuSap;
7615 TRC2(rgSCHUtlValidateTfuSap)
7617 if(suId >= rgSchCb[inst].numSaps)
7619 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Incorrect SuId");
7622 tfuSap = &(rgSchCb[inst].tfuSap[suId]);
7624 /* First lets check the suId */
7625 if( suId != tfuSap->sapCfg.suId)
7627 RLOG_ARG2(L_ERROR,DBG_INSTID,inst,"Incorrect SuId. Configured (%d) Recieved (%d)",
7628 tfuSap->sapCfg.suId, suId);
7631 if (tfuSap->sapSta.sapState != LRG_BND)
7633 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"Lower SAP not enabled SuId (%d)",
7634 tfuSap->sapCfg.suId);
7638 } /* end of rgSCHUtlValidateTfuSap */
7642 * Fun: rgSCHUtlAllocEventMem
7644 * Desc: This function allocates event memory
7646 * Ret: ROK - on success
7647 * RFAILED - on failure
7655 PUBLIC S16 rgSCHUtlAllocEventMem
7662 PUBLIC S16 rgSCHUtlAllocEventMem(inst, memPtr, memSize)
7669 VOLATILE U32 startTime=0;
7671 TRC2(rgSCHUtlAllocEventMem)
7673 sMem.region = rgSchCb[inst].rgSchInit.region;
7674 sMem.pool = rgSchCb[inst].rgSchInit.pool;
7676 #if (ERRCLASS & ERRCLS_DEBUG)
7679 RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize,
7680 "rgAllocEventMem(): memSize invalid\n");
7683 #endif /* ERRCLASS & ERRCLS_DEBUG */
7685 SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
7687 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
7688 MS_BUF_ADD_ALLOC_CALLER();
7690 #ifdef TFU_ALLOC_EVENT_NO_INIT
7691 if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7693 if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7696 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed.");
7700 SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
7702 } /* end of rgSCHUtlAllocEventMem*/
7706 * Fun: rgGetEventMem
7708 * Desc: This function allocates event memory
7710 * Ret: ROK - on success
7711 * RFAILED - on failure
7719 PUBLIC S16 rgSCHUtlGetEventMem
7726 PUBLIC S16 rgSCHUtlGetEventMem(ptr, len, memCp)
7734 TRC2(rgSCHUtlGetEventMem)
7735 #ifdef TFU_ALLOC_EVENT_NO_INIT
7736 ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
7738 ret = cmGetMem(memCp, len, (Ptr *)ptr);
7741 } /* end of rgSCHUtlGetEventMem*/
7747 * @brief Handler to allocate memory for ACK/NACk feedback information
7751 * Function : rgSCHUtlAllocUeANFdbkInfo
7753 * It allocates memory for the UE related ACK NACK information.
7755 * @param[in] RgSchUeCb *ue
7759 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo
7765 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx)
7772 TRC2(rgSCHUtlAllocUeANFdbkInfo);
7774 if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
7775 (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
7776 ue->cell->ackNackFdbkArrSize) != ROK)
7781 for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
7783 rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
7786 /* Set it to the first index */
7787 ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
7789 } /* rgSCHUtlAllocUeANFdbkInfo */
7792 * @brief Handler to release memory for ACK/NACk feedback information
7796 * Function : rgSCHUtlDelUeANFdbkInfo
7798 * It releases memory for the UE related ACK NACK information.
7800 * @param[in] RgSchUeCb *ue
7804 PUBLIC Void rgSCHUtlDelUeANFdbkInfo
7810 PUBLIC Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx)
7815 TRC2(rgSCHUtlDelUeANFdbkInfo);
7817 /* ccpu00117052 - MOD - Passing double pointer
7818 for proper NULLP assignment*/
7819 rgSCHUtlFreeSBuf(ue->cell->instIdx,
7820 (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
7821 ue->cell->ackNackFdbkArrSize);
7824 } /* rgSCHUtlDelUeANFdbkInfo */
7827 * @brief Handler to initialise UE ACK/NACk feedback information
7831 * Function : rgSCHUtlInitUeANFdbkInfo
7833 * It initialises UE related ACK NACK information.
7835 * @param[in] RgSchTddANInfo *anFdInfo
7839 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo
7841 RgSchTddANInfo *anFdInfo
7844 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo)
7845 RgSchTddANInfo *anFdInfo;
7848 TRC2(rgSCHUtlInitUeANFdbkInfo);
7850 anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
7852 anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
7853 anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
7854 anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
7857 } /* rgSCHUtlInitUeANFdbkInfo */
7860 * @brief Handler to get UE related ACK NACK feedback information
7864 * Function : rgSCHUtlGetUeANFdbkInfo
7866 * It gets the UE related ACK NACK information based on
7867 * SFN and slot number.
7869 * @param[in] RgSchUeCb *ueCb
7870 * @param[in] CmLteTimingInfo *time
7871 * @return RgSchTddANInfo*
7874 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo
7877 CmLteTimingInfo *timeInfo,
7881 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx)
7883 CmLteTimingInfo *timeInfo;
7889 TRC2(rgSCHUtlGetUeANFdbkInfo);
7891 for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
7893 if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
7894 (timeInfo->slot == ueCb->cellInfo[servCellIdx]->anInfo[idx].slot))
7896 RETVALUE(&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
7901 } /* rgSCHUtlGetUeANFdbkInfo */
7904 * @brief To get downlink slot index
7908 * Function: rgSCHUtlGetDlSfIdx
7909 * Purpose: Gets downlink slot index based on SFN and slot no
7911 * @param[in] CmLteTimingInfo *timeInfo
7912 * @param[in] RgSchCellCb *cell
7917 PUBLIC U8 rgSCHUtlGetDlSfIdx
7920 CmLteTimingInfo *timeInfo
7923 PUBLIC U8 rgSCHUtlGetDlSfIdx(cell, timeInfo)
7925 CmLteTimingInfo *timeInfo;
7929 TRC2(rgSCHUtlGetDlSfIdx);
7931 idx = RGSCH_NUM_SUB_FRAMES - \
7932 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7933 idx = ((idx * timeInfo->sfn) + \
7934 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->slot]) - 1;
7935 idx = idx % cell->numDlSubfrms;
7941 * @brief To get the next downlink slot
7945 * Function: rgSCHUtlGetNxtDlSfInfo
7946 * Purpose: Gets next downlink slot based on current DL slot
7948 * @param[in] CmLteTimingInfo curDlTime
7949 * @param[in] RgSchCellCb *cell
7950 * @param[in] RgSchDlSf *dlSf
7951 * @param[in] RgSchDlSf **nxtDlsf
7952 * @param[in] CmLteTimingInfo *nxtDlTime
7957 PUBLIC Void rgSCHUtlGetNxtDlSfInfo
7959 CmLteTimingInfo curDlTime,
7962 RgSchDlSf **nxtDlsf,
7963 CmLteTimingInfo *nxtDlTime
7966 PUBLIC Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime)
7967 CmLteTimingInfo curDlTime;
7970 RgSchDlSf **nxtDlsf;
7971 CmLteTimingInfo *nxtDlTime;
7974 U16 idx = curDlTime.slot;
7976 TRC2(rgSCHUtlGetNxtDlSfInfo);
7982 idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
7984 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
7985 != RG_SCH_TDD_DL_slot);
7986 RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
7987 *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
7988 if(dlSf->dlFdbkInfo.slot != (*nxtDlsf)->dlFdbkInfo.slot)
7997 * @brief To get the previous downlink slot
8001 * Function: rgSCHUtlGetPrevDlSfInfo
8002 * Purpose: Gets previous downlink slot based on current DL slot
8004 * @param[in] RgSchCellCb *cell
8005 * @param[in] CmLteTimingInfo curDlTime
8006 * @param[in] CmLteTimingInfo *prevDlTime
8007 * @param[in] U8 *numSubfrm
8012 PUBLIC Void rgSCHUtlGetPrevDlSfInfo
8015 CmLteTimingInfo curDlTime,
8016 CmLteTimingInfo *prevDlTime,
8020 PUBLIC Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm)
8022 CmLteTimingInfo curDlTime;
8023 CmLteTimingInfo *prevDlTime;
8027 S16 idx = curDlTime.slot;
8029 TRC2(rgSCHUtlGetPrevDlSfInfo);
8036 idx = RGSCH_NUM_SUB_FRAMES-1;
8039 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
8040 != RG_SCH_TDD_DL_slot);
8042 RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
8047 /* Added Holes Management functions for Adaptive Re transmission */
8048 /******* </AllocHolesMemMgmnt>: START *****/
8049 /***********************************************************
8051 * Func : rgSCHUtlUlSfInit
8053 * Desc : UL slot init.
8061 **********************************************************/
8063 PUBLIC S16 rgSCHUtlUlSfInit
8071 PUBLIC S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf)
8079 TRC2(rgSCHUtlUlSfInit);
8087 if(cell->ulDlCfgIdx == 0)
8089 /* Store the Uplink slot number corresponding to the idx */
8090 sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6];
8093 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
8094 sizeof(RgSchUlAllocDb));
8099 ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
8102 /* ccpu00117052 - MOD - Passing double pointer
8103 for proper NULLP assignment*/
8104 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8105 sizeof(RgSchUlAllocDb));
8108 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
8109 sizeof(RgSchUlHoleDb));
8112 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8113 /* ccpu00117052 - MOD - Passing double pointer
8114 for proper NULLP assignment*/
8115 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8116 sizeof(RgSchUlAllocDb));
8119 /* Initialize the hole with CFI 1 Pusch Bw Info */
8120 ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (U8)(maxUePerSf + 2), \
8121 0, cell->dynCfiCb.bwInfo[1].numSb);
8125 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8126 /* ccpu00117052 - MOD - Passing double pointer
8127 for proper NULLP assignment*/
8128 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8129 sizeof(RgSchUlAllocDb));
8130 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8131 sizeof(RgSchUlHoleDb));
8134 cmLListInit(&sf->reTxLst);
8136 /* Fix ccpu00120610*/
8137 sf->allocCountRef = &sf->allocDb->count;
8139 /* initialize UL available subbands for current sub-frame */
8140 sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
8142 sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
8143 sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
8144 for(index = 0; index < MAX_5GTF_BEAMS; index++)
8146 sf->sfBeamInfo[index].totVrbgAllocated = 0;
8147 sf->sfBeamInfo[index].totVrbgRequired = 0;
8148 sf->sfBeamInfo[index].vrbgStart = 0;
8156 /***********************************************************
8158 * Func : rgSCHUtlUlSfDeinit
8160 * Desc : Deinitialises a slot
8168 **********************************************************/
8170 PUBLIC Void rgSCHUtlUlSfDeinit
8176 PUBLIC Void rgSCHUtlUlSfDeinit(cell, sf)
8181 TRC2(rgSCHUtlUlSfDeinit);
8184 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8185 /* ccpu00117052 - MOD - Passing double pointer
8186 for proper NULLP assignment*/
8187 /* ccpu00117052 - MOD - Passing double pointer
8188 for proper NULLP assignment*/
8189 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8190 sizeof(RgSchUlAllocDb));
8194 rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
8195 /* ccpu00117052 - MOD - Passing double pointer
8196 for proper NULLP assignment*/
8197 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8198 sizeof(RgSchUlHoleDb));
8203 /***********************************************************
8205 * Func : rgSCHUtlUlAllocDbInit
8207 * Desc : Initialise allocation DB
8209 * Ret : S16 (ROK/RFAILED)
8215 **********************************************************/
8217 PRIVATE S16 rgSCHUtlUlAllocDbInit
8220 RgSchUlAllocDb *allocDb,
8224 PRIVATE S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs)
8226 RgSchUlAllocDb *allocDb;
8230 S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
8231 TRC2(rgSCHUtlUlAllocDbInit);
8237 allocDb->first = NULLP;
8241 /***********************************************************
8243 * Func : rgSCHUtlUlAllocDbDeinit
8245 * Desc : Deinitialises allocation DB
8246 * sent to UE, for a UE with accumulation disabled
8254 **********************************************************/
8256 PRIVATE Void rgSCHUtlUlAllocDbDeinit
8259 RgSchUlAllocDb *allocDb
8262 PRIVATE Void rgSCHUtlUlAllocDbDeinit(cell, allocDb)
8264 RgSchUlAllocDb *allocDb;
8267 TRC2(rgSCHUtlUlAllocDbDeinit);
8268 rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
8270 allocDb->first = NULLP;
8274 /***********************************************************
8276 * Func : rgSCHUtlUlHoleDbInit
8278 * Desc : Initialise hole DB
8280 * Ret : S16 (ROK/RFAILED)
8286 **********************************************************/
8288 PRIVATE S16 rgSCHUtlUlHoleDbInit
8291 RgSchUlHoleDb *holeDb,
8297 PRIVATE S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num)
8299 RgSchUlHoleDb *holeDb;
8306 RgSchUlHole *hole = NULLP;
8307 TRC2(rgSCHUtlUlHoleDbInit);
8309 ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
8315 holeDb->first = hole;
8316 hole->start = start;
8318 hole->prv = hole->nxt = NULLP;
8322 /***********************************************************
8324 * Func : rgSCHUtlUlHoleDbDeinit
8326 * Desc : Deinitialises hole DB
8334 **********************************************************/
8336 PRIVATE Void rgSCHUtlUlHoleDbDeinit
8339 RgSchUlHoleDb *holeDb
8342 PRIVATE Void rgSCHUtlUlHoleDbDeinit(cell, holeDb)
8344 RgSchUlHoleDb *holeDb;
8347 TRC2(rgSCHUtlUlHoleDbDeinit);
8348 rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
8350 holeDb->first = NULLP;
8355 /***********************************************************
8357 * Func : rgSCHUtlUlAllocGetHole
8359 * Desc : Get allocation from hole
8361 * Ret : RgSchUlAlloc *
8367 **********************************************************/
8369 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole
8376 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole)
8382 TRC2(rgSCHUtlUlAllocGetHole);
8383 if (numSb < hole->num)
8385 RETVALUE(rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
8389 RETVALUE(rgSCHUtlUlAllocGetCompHole(sf, hole));
8394 /***********************************************************
8396 * Func : rgSCHUtlUlAllocGetCompHole
8398 * Desc : Get an allocation corresponding to an entire hole
8400 * Ret : RgSchUlAlloc *
8406 **********************************************************/
8408 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole
8414 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole)
8419 RgSchUlAlloc *alloc;
8420 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8421 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8422 * updated, causing another check for prv */
8423 RgSchUlAlloc *prv = hole->prvAlloc;
8424 RgSchUlAlloc *nxt = hole->nxtAlloc;
8425 TRC2(rgSCHUtlUlAllocGetCompHole);
8429 if (hole->start == prv->nxtHole->start)
8431 prv->nxtHole = NULLP;
8433 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8437 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8440 RGSCH_NULL_CHECK( 0, alloc);
8441 alloc->prvHole = NULLP;
8442 alloc->nxtHole = NULLP;
8444 alloc->sbStart = hole->start;
8445 alloc->numSb = hole->num;
8449 nxt->prvHole = NULLP;
8452 rgSCHUtlUlHoleRls(sf->holeDb, hole);
8454 /* UL_ALLOC_CHANGES*/
8455 alloc->allocDbRef = (void*)sf->allocDb;
8456 alloc->holeDbRef = (void*)sf->holeDb;
8460 /***********************************************************
8462 * Func : rgSCHUtlUlAllocGetPartHole
8464 * Desc : Get an allocation corresponding to a part of a hole.
8465 * The initial 'numSb' part of the hole shall be taken
8466 * away for this alloc.
8468 * Ret : RgSchUlAlloc *
8474 **********************************************************/
8476 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole
8483 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)
8489 RgSchUlAlloc *alloc;
8490 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8491 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8492 * updated, causing another check for prv */
8493 RgSchUlAlloc *prv = hole->prvAlloc;
8494 TRC2(rgSCHUtlUlAllocGetPartHole);
8498 if (hole->start == prv->nxtHole->start)
8500 prv->nxtHole = NULLP;
8502 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8506 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8509 RGSCH_NULL_CHECK( 0, alloc);
8510 alloc->prvHole = NULLP;
8511 alloc->nxtHole = hole;
8512 hole->prvAlloc = alloc;
8514 alloc->sbStart = hole->start;
8515 alloc->numSb = numSb;
8516 hole->start += numSb;
8519 rgSCHUtlUlHoleDecr(sf->holeDb, hole);
8521 /* UL_ALLOC_CHANGES*/
8522 alloc->allocDbRef = (void*)sf->allocDb;
8523 alloc->holeDbRef = (void*)sf->holeDb;
8528 /***********************************************************
8530 * Func : rgSCHUtlUlAllocFirst
8532 * Desc : Get first alloc in slot
8534 * Ret : RgSchUlAlloc *
8540 **********************************************************/
8542 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst
8547 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf)
8551 TRC2(rgSCHUtlUlAllocFirst);
8552 RETVALUE(sf->allocDb->first);
8555 /***********************************************************
8557 * Func : rgSCHUtlUlAllocNxt
8559 * Desc : Get next alloc
8561 * Ret : RgSchUlAlloc *
8567 **********************************************************/
8569 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt
8575 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc)
8577 RgSchUlAlloc *alloc;
8580 TRC2(rgSCHUtlUlAllocNxt);
8582 RETVALUE(alloc->nxt);
8585 /***********************************************************
8587 * Func : rgSCHUtlUlAllocGetAdjNxt
8589 * Desc : Get alloc which is immediately after the passed one.
8590 * 1. Gets alloc from mem.
8591 * 2. Inserts alloc into list (between prv and
8592 * prv->nxt, prv is not NULLP).
8593 * 3. Increments alloc count.
8594 * Note 1: Holes are not dealt with here.
8595 * Note 2: Assumes prv to be NULL.
8597 * Ret : RgSchUlAlloc *
8603 **********************************************************/
8605 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt
8611 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv)
8616 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8617 RgSchUlAlloc *nxt = prv->nxt;
8618 TRC2(rgSCHUtlUlAllocGetAdjNxt);
8620 #if (ERRCLASS & ERRCLS_DEBUG)
8621 if ( alloc == NULLP )
8639 /***********************************************************
8641 * Func : rgSCHUtlUlAllocGetFirst
8643 * Desc : Get alloc which is to be the first one in the alloc list
8644 * 1. Gets alloc from mem.
8645 * 2. Inserts alloc as first element into list.
8646 * 3. Increments alloc count.
8647 * Note 1: Holes are not dealt with here.
8648 * Note 2: prv to necessarily NULLP.
8650 * Ret : RgSchUlAlloc *
8656 **********************************************************/
8658 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst
8663 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db)
8667 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8668 RgSchUlAlloc *nxt = db->first;
8669 TRC2(rgSCHUtlUlAllocGetFirst);
8671 #if (ERRCLASS & ERRCLS_DEBUG)
8672 if ( alloc == NULLP )
8691 /* UL_ALLOC_ENHANCEMENT */
8692 /***********************************************************
8694 * Func : rgSCHUtlUlHoleAddAllocation
8696 * Desc : On freeing an alloc, add to hole
8704 **********************************************************/
8706 PUBLIC Void rgSCHUtlUlHoleAddAllocation
8711 PUBLIC Void rgSCHUtlUlHoleAddAllocation(alloc)
8712 RgSchUlAlloc *alloc;
8715 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8716 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8717 * The excessive branching is meant to utilise the knowledge of whether prv
8718 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8719 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8720 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8721 RgSchUlHoleDb *db = alloc->holeDbRef;
8722 RgSchUlHole *prv = alloc->prvHole;
8723 RgSchUlHole *nxt = alloc->nxtHole;
8724 TRC2(rgSCHUtlUlHoleAddAllocation);
8730 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8733 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8739 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8742 rgSCHUtlUlHoleNew(db, alloc);
8748 /***********************************************************
8750 * Func : rgSCHUtlUlAllocRelease
8752 * Desc : Releases an uplink allocation, only take alloc ptr
8760 **********************************************************/
8762 PUBLIC Void rgSCHUtlUlAllocRelease
8767 PUBLIC Void rgSCHUtlUlAllocRelease(alloc)
8768 RgSchUlAlloc *alloc;
8771 RgSchUlAllocDb *allocDb = alloc->allocDbRef;
8772 RgSchUlAlloc *prv = alloc->prv;
8773 RgSchUlAlloc *nxt = alloc->nxt;
8774 TRC2(rgSCHUtlUlAllocRelease);
8777 alloc->raCb = NULLP;
8778 alloc->isAdaptive = FALSE;
8783 if (nxt) /* general case: this allocation lies btw two */
8790 allocDb->first = nxt;
8797 rgSCHUtlUlHoleAddAllocation(alloc);
8798 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8804 /***********************************************************
8806 * Func : rgSCHUtlUlAllocRls
8808 * Desc : Releases an uplink allocation
8816 **********************************************************/
8818 PUBLIC Void rgSCHUtlUlAllocRls
8824 PUBLIC Void rgSCHUtlUlAllocRls(sf, alloc)
8826 RgSchUlAlloc *alloc;
8829 RgSchUlAllocDb *allocDb = sf->allocDb;
8830 RgSchUlAlloc *prv = alloc->prv;
8831 RgSchUlAlloc *nxt = alloc->nxt;
8832 TRC2(rgSCHUtlUlAllocRls);
8835 alloc->raCb = NULLP;
8836 alloc->isAdaptive = FALSE;
8843 if (nxt) /* general case: this allocation lies btw two */
8850 allocDb->first = nxt;
8857 rgSCHUtlUlHoleAddAlloc(sf, alloc);
8858 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8863 printf("\nError: allocDb->count is ZERO ====\n");
8866 //printf("\nallocDb->count:%u\n",allocDb->count);
8871 /***********************************************************
8873 * Func : rgSCHUtlUlHoleFirst
8875 * Desc : Get first (largest) hole
8877 * Ret : RgSchUlHole *
8883 **********************************************************/
8885 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst
8890 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst(sf)
8894 TRC2(rgSCHUtlUlHoleFirst);
8895 RETVALUE(sf->holeDb->first);
8898 /***********************************************************
8900 * Func : rgSCHUtlUlHoleNxt
8902 * Desc : Get next largest hole
8904 * Ret : RgSchUlHole *
8910 **********************************************************/
8912 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt
8918 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole)
8923 TRC2(rgSCHUtlUlHoleNxt);
8925 RETVALUE(hole->nxt);
8928 /***********************************************************
8930 * Func : rgSCHUtlUlHoleAddAlloc
8932 * Desc : On freeing an alloc, add to hole
8940 **********************************************************/
8942 PUBLIC Void rgSCHUtlUlHoleAddAlloc
8948 PUBLIC Void rgSCHUtlUlHoleAddAlloc(sf, alloc)
8950 RgSchUlAlloc *alloc;
8953 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8954 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8955 * The excessive branching is meant to utilise the knowledge of whether prv
8956 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8957 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8958 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8959 RgSchUlHoleDb *db = sf->holeDb;
8960 RgSchUlHole *prv = alloc->prvHole;
8961 RgSchUlHole *nxt = alloc->nxtHole;
8962 TRC2(rgSCHUtlUlHoleAddAlloc);
8968 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8971 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8977 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8980 rgSCHUtlUlHoleNew(db, alloc);
8983 /* increment the number of subbands getting freed to total available list */
8984 sf->availSubbands += alloc->numSb;
8989 /***********************************************************
8991 * Func : rgSCHUtlUlHoleJoin
8993 * Desc : Join two holes (due to alloc being deleted)
9001 **********************************************************/
9003 PUBLIC Void rgSCHUtlUlHoleJoin
9011 PUBLIC Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc)
9015 RgSchUlAlloc *alloc;
9018 TRC2(rgSCHUtlUlHoleJoin);
9019 prv->num += alloc->numSb + nxt->num;
9020 rgSCHUtlUlHoleRls(db, nxt);
9021 rgSCHUtlUlHoleIncr(db, prv);
9022 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9027 /***********************************************************
9029 * Func : rgSCHUtlUlHoleExtndRight
9031 * Desc : Extend hole due to alloc coming 'after' the hole
9040 **********************************************************/
9042 PUBLIC Void rgSCHUtlUlHoleExtndRight
9049 PUBLIC Void rgSCHUtlUlHoleExtndRight(db, prv, alloc)
9052 RgSchUlAlloc *alloc;
9055 TRC2(rgSCHUtlUlHoleExtndRight);
9056 prv->num += alloc->numSb;
9057 rgSCHUtlUlHoleIncr(db, prv);
9058 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9062 /***********************************************************
9064 * Func : rgSCHUtlUlHoleExtndLeft
9066 * Desc : Extend hole due to alloc coming 'before' the hole
9075 **********************************************************/
9077 PUBLIC Void rgSCHUtlUlHoleExtndLeft
9084 PUBLIC Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc)
9087 RgSchUlAlloc *alloc;
9090 TRC2(rgSCHUtlUlHoleExtndLeft);
9091 nxt->num += alloc->numSb;
9092 nxt->start = alloc->sbStart;
9093 rgSCHUtlUlHoleIncr(db, nxt);
9094 rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
9098 /***********************************************************
9100 * Func : rgSCHUtlUlHoleNew
9102 * Desc : Create new hole due to alloc being deleted
9110 **********************************************************/
9112 PUBLIC Void rgSCHUtlUlHoleNew
9118 PUBLIC Void rgSCHUtlUlHoleNew(db, alloc)
9120 RgSchUlAlloc *alloc;
9123 RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
9124 #if (ERRCLASS & ERRCLS_DEBUG)
9125 if ( hole == NULLP )
9130 TRC2(rgSCHUtlUlHoleNew);
9131 hole->start = alloc->sbStart;
9132 hole->num = alloc->numSb;
9134 rgSCHUtlUlHoleIns(db, hole);
9135 rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
9139 /***********************************************************
9141 * Func : rgSCHUtlUlHoleUpdAllocLnks
9143 * Desc : Update alloc links in hole
9151 **********************************************************/
9153 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks
9156 RgSchUlAlloc *prvAlloc,
9157 RgSchUlAlloc *nxtAlloc
9160 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc)
9162 RgSchUlAlloc *prvAlloc;
9163 RgSchUlAlloc *nxtAlloc;
9166 TRC2(rgSCHUtlUlHoleUpdAllocLnks);
9169 prvAlloc->nxtHole = hole;
9173 nxtAlloc->prvHole = hole;
9175 hole->prvAlloc = prvAlloc;
9176 hole->nxtAlloc = nxtAlloc;
9181 /***********************************************************
9183 * Func : rgSCHUtlUlHoleIns
9185 * Desc : Insert (newly created) hole in sorted list of holes.
9186 * Searches linearly, beginning with the largest hole.
9194 **********************************************************/
9196 PUBLIC Void rgSCHUtlUlHoleIns
9202 PUBLIC Void rgSCHUtlUlHoleIns(db, hole)
9208 TRC2(rgSCHUtlUlHoleIns);
9210 if ((cur = db->first) != NULLP)
9213 if (cur->num < hole->num)
9223 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9225 if (nxt->num < hole->num)
9227 /* Insert hole: cur <-> hole <-> nxt */
9243 /* This is the first hole */
9245 hole->prv = NULLP; /* may not be needed */
9251 /***********************************************************
9253 * Func : rgSCHUtlUlHoleIncr
9255 * Desc : hole->num has increeased, reposition in sorted
9264 **********************************************************/
9266 PUBLIC Void rgSCHUtlUlHoleIncr
9272 PUBLIC Void rgSCHUtlUlHoleIncr(db, hole)
9278 TRC2(rgSCHUtlUlHoleIncr);
9280 if ((cur = hole->prv) != NULLP)
9284 if (cur->num > hole->num)
9289 /* Remove hole from current position */
9290 cur->nxt = hole->nxt;
9293 hole->nxt->prv = cur;
9296 for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
9298 if (prv->num > hole->num)
9300 /* Insert hole: prv <-> hole <-> cur */
9319 /***********************************************************
9321 * Func : rgSCHUtlUlHoleDecr
9323 * Desc : hole->num has decreeased, reposition in sorted
9332 **********************************************************/
9334 PUBLIC Void rgSCHUtlUlHoleDecr
9340 PUBLIC Void rgSCHUtlUlHoleDecr(db, hole)
9346 TRC2(rgSCHUtlUlHoleDecr);
9348 if ((cur = hole->nxt) != NULLP)
9352 if (cur->num < hole->num)
9357 /* Remove hole from current position */
9358 cur->prv = hole->prv;
9361 hole->prv->nxt = cur;
9363 else /* no prv, so cur to replace hole as first in list */
9368 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9370 if (nxt->num < hole->num)
9372 /* Insert hole: cur <-> hole <-> nxt */
9390 /***********************************************************
9392 * Func : rgSCHUtlUlHoleRls
9394 * Desc : Releases hole.
9395 * 1. Decrements hole count.
9396 * 2. Deletes hole from list.
9397 * 3. Frees hole (hole memory release).
9405 **********************************************************/
9407 PUBLIC Void rgSCHUtlUlHoleRls
9413 PUBLIC Void rgSCHUtlUlHoleRls(db, hole)
9418 RgSchUlHole *prv = hole->prv;
9419 RgSchUlHole *nxt = hole->nxt;
9420 TRC2(rgSCHUtlUlHoleRls);
9440 rgSCHUtlUlHoleMemRls(&db->mem, hole);
9445 /***********************************************************
9447 * Func : rgSCHUtlUlAllocMemInit
9449 * Desc : Initialises alloc free pool
9451 * Ret : S16 (ROK/RFAILED)
9457 **********************************************************/
9459 PUBLIC S16 rgSCHUtlUlAllocMemInit
9462 RgSchUlAllocMem *mem,
9466 PUBLIC S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs)
9468 RgSchUlAllocMem *mem;
9473 RgSchUlAlloc *allocs;
9474 TRC2(rgSCHUtlUlAllocMemInit);
9476 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
9477 maxAllocs * sizeof(*allocs));
9482 mem->allocs = allocs;
9483 mem->maxAllocs = maxAllocs;
9484 if (mem->maxAllocs == 1)
9486 allocs[0].prv = NULLP;
9487 allocs[0].nxt = NULLP;
9492 allocs[0].prv = NULLP;
9493 allocs[0].nxt = &allocs[1];
9494 for (i = 1; i < mem->maxAllocs - 1; ++i)
9496 allocs[i].prv = &allocs[i-1];
9497 allocs[i].nxt = &allocs[i+1];
9499 allocs[i].prv = &allocs[i-1];
9500 allocs[i].nxt = NULLP;
9502 mem->firstFree = &allocs[0];
9506 /***********************************************************
9508 * Func : rgSCHUtlUlAllocMemDeinit
9510 * Desc : Deinitialises alloc free pool
9518 **********************************************************/
9520 PUBLIC Void rgSCHUtlUlAllocMemDeinit
9523 RgSchUlAllocMem *mem
9526 PUBLIC Void rgSCHUtlUlAllocMemDeinit(cell, mem)
9528 RgSchUlAllocMem *mem;
9531 TRC2(rgSCHUtlUlAllocMemDeinit);
9532 /* ccpu00117052 - MOD - Passing double pointer
9533 for proper NULLP assignment*/
9534 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
9535 mem->maxAllocs * sizeof(*mem->allocs));
9537 mem->firstFree = NULLP;
9541 /***********************************************************
9543 * Func : rgSCHUtlUlHoleMemInit
9545 * Desc : Initialises hole free pool. Assumes maxHoles
9548 * Ret : S16 (ROK/RFAILED)
9554 **********************************************************/
9556 PUBLIC S16 rgSCHUtlUlHoleMemInit
9559 RgSchUlHoleMem *mem,
9561 RgSchUlHole **holeRef
9564 PUBLIC S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef)
9566 RgSchUlHoleMem *mem;
9568 RgSchUlHole **holeRef;
9573 TRC2(rgSCHUtlUlHoleMemInit);
9575 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
9576 maxHoles * sizeof(*holes));
9583 mem->maxHoles = maxHoles;
9585 /* first hole is taken up */
9586 holes[0].prv = NULLP; /* not needed */
9587 holes[0].nxt = NULLP; /* not needed */
9588 *holeRef = &holes[0];
9590 if (mem->maxHoles == 2)
9592 holes[1].prv = NULLP; /* may not be needed */
9593 holes[1].nxt = NULLP; /* may not be needed */
9598 holes[1].prv = NULLP;
9599 holes[0].nxt = &holes[1];
9600 for (i = 1; i < mem->maxHoles - 1; ++i)
9602 holes[i].prv = &holes[i-1];
9603 holes[i].nxt = &holes[i+1];
9605 holes[i].prv = &holes[i-1];
9606 holes[i].nxt = NULLP;
9608 mem->firstFree = &holes[1];
9613 /***********************************************************
9615 * Func : rgSCHUtlUlHoleMemDeinit
9617 * Desc : Deinitialises hole free pool
9625 **********************************************************/
9627 PUBLIC Void rgSCHUtlUlHoleMemDeinit
9633 PUBLIC Void rgSCHUtlUlHoleMemDeinit(cell, mem)
9635 RgSchUlHoleMem *mem;
9638 TRC2(rgSCHUtlUlHoleMemDeinit);
9639 /* ccpu00117052 - MOD - Passing double pointer
9640 for proper NULLP assignment*/
9641 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
9642 mem->maxHoles * sizeof(*mem->holes));
9644 mem->firstFree = NULLP;
9648 /***********************************************************
9650 * Func : rgSCHUtlUlAllocMemGet
9652 * Desc : Gets an 'alloc' from the free pool
9654 * Ret : RgSchUlAlloc *
9660 **********************************************************/
9662 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet
9664 RgSchUlAllocMem *mem
9667 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem)
9668 RgSchUlAllocMem *mem;
9671 RgSchUlAlloc *alloc;
9672 TRC2(rgSCHUtlUlAllocMemGet);
9674 #if (ERRCLASS & ERRCLS_DEBUG)
9675 if (mem->firstFree == NULLP)
9681 alloc = mem->firstFree;
9682 mem->firstFree = alloc->nxt;
9683 alloc->nxt = NULLP; /* probably not needed */
9684 /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
9689 /***********************************************************
9691 * Func : rgSCHUtlUlAllocMemRls
9693 * Desc : Returns an 'alloc' to the free pool
9701 **********************************************************/
9703 PUBLIC Void rgSCHUtlUlAllocMemRls
9705 RgSchUlAllocMem *mem,
9709 PUBLIC Void rgSCHUtlUlAllocMemRls(mem, alloc)
9710 RgSchUlAllocMem *mem;
9711 RgSchUlAlloc *alloc;
9714 TRC2(rgSCHUtlUlAllocMemRls);
9717 alloc->nxt = mem->firstFree;
9718 if (mem->firstFree != NULLP)
9720 mem->firstFree->prv = alloc;
9722 mem->firstFree = alloc;
9726 /***********************************************************
9728 * Func : rgSCHUtlUlHoleMemGet
9730 * Desc : Gets a 'hole' from the free pool
9732 * Ret : RgSchUlHole *
9738 **********************************************************/
9740 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet
9745 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet(mem)
9746 RgSchUlHoleMem *mem;
9750 TRC2(rgSCHUtlUlHoleMemGet);
9752 #if (ERRCLASS & ERRCLS_DEBUG)
9753 if (mem->firstFree == NULLP)
9759 hole = mem->firstFree;
9760 mem->firstFree = hole->nxt;
9761 mem->firstFree->prv = NULLP; /* may not be needed, under error class */
9762 hole->nxt = NULLP; /* probably not needed */
9763 /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
9768 /***********************************************************
9770 * Func : rgSCHUtlUlHoleMemRls
9772 * Desc : Returns a 'hole' to the free pool
9780 **********************************************************/
9782 PUBLIC Void rgSCHUtlUlHoleMemRls
9784 RgSchUlHoleMem *mem,
9788 PUBLIC Void rgSCHUtlUlHoleMemRls(mem, hole)
9789 RgSchUlHoleMem *mem;
9793 TRC2(rgSCHUtlUlHoleMemRls);
9796 hole->nxt = mem->firstFree;
9797 if (mem->firstFree != NULLP)
9799 mem->firstFree->prv = hole;
9801 mem->firstFree = hole;
9806 * @brief Get an alloc from the specified position in the BW.
9810 * Function : rgSCHUtlUlGetSpfcAlloc
9812 * - Return an alloc from the specified position in the BW.
9813 * Note: This function assumes there is always a hole
9814 * Existing which completely has the specified
9815 * allocation. The reason for such an assumption is
9816 * the function's usage as of now guarantees that there
9817 * will always be such hole. And also for efficiency.
9819 * @param[in] RgSchUlSf *sf
9820 * @param[in] U8 startSb
9821 * @param[in] U8 numSb
9822 * @return RgSchUlAlloc*
9825 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc
9832 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb)
9838 RgSchUlHole *hole, *nxtHole;
9839 RgSchUlAlloc *alloc = NULLP;
9840 TRC2(rgSCHUtlUlGetSpfcAlloc);
9842 if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
9848 nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
9849 if ((startSb >= hole->start) &&
9850 (startSb+numSb <= hole->start+hole->num))
9852 if (startSb != hole->start)
9854 /* Create a new hole to accomodate Subbands between
9855 * hole start and req alloc start */
9856 RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
9858 #if (ERRCLASS & ERRCLS_DEBUG)
9859 if ( newHole == NULLP )
9864 newHole->start = hole->start;
9865 newHole->num = startSb - hole->start;
9866 hole->start = startSb;
9867 /* [ccpu00122847]-MOD- Correctly updating the hole->num */
9868 hole->num -= newHole->num;
9869 ++(sf->holeDb->count);
9870 rgSCHUtlUlHoleIns(sf->holeDb, newHole);
9871 newHole->prvAlloc = hole->prvAlloc;
9872 if (newHole->prvAlloc)
9874 newHole->prvAlloc->nxtHole = newHole;
9876 if (numSb == hole->num)
9878 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9882 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9884 alloc->prvHole = newHole;
9885 newHole->nxtAlloc = alloc;
9887 else /* Hole start and req alloc start are same */
9889 if (numSb == hole->num)
9891 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9895 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9900 } while ((hole = nxtHole) != NULLP);
9905 * @brief Validates the qci values
9909 * Function :rgSCHUtlValidateQci
9911 * @param[in] RgSchCellCb *cellCb
9912 * @param[in] U8 numQci
9913 * @param[out] U8 *qci
9919 PRIVATE S16 rgSCHUtlValidateQci
9921 RgSchCellCb *cellCb,
9926 PRIVATE S16 rgSCHUtlValidateQci(cellCb, numQci, qci)
9927 RgSchCellCb *cellCb;
9935 TRC3(rgSCHUtlValidateQci)
9937 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
9939 qciVal = qci[qciIdx];
9940 if(qciVal == 0 || qciVal > 9)
9944 if(qciVal != cellCb->qciArray[qciVal].qci)
9951 }/* rgSCHUtlValidateQci */
9953 * @brief Validates the measurement request parameters.
9957 * Function :rgSCHUtlValidateMeasReq
9959 * @param[in] RgSchCellCb *cellCb
9960 * @param[in] LrgSchMeasReqInfo *schL2MeasInfo
9961 * @param[out] RgSchErrInfo *err
9962 * @return RgSchUlAlloc*
9965 PUBLIC S16 rgSCHUtlValidateMeasReq
9967 RgSchCellCb *cellCb,
9968 LrgSchMeasReqInfo *schL2MeasInfo,
9972 PUBLIC S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err)
9973 RgSchCellCb *cellCb;
9974 LrgSchMeasReqInfo *schL2MeasInfo;
9981 TRC3(rgSCHUtlValidateMeasReq)
9983 measType = schL2MeasInfo->measType;
9985 if((measType == 0) ||
9988 err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
9989 err->errCause = RGSCHERR_SCH_L2MEAS;
9992 if((schL2MeasInfo->timePrd !=0) &&
9993 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
9994 ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
9995 (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
9997 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9998 err->errCause = RGSCHERR_SCH_L2MEAS;
10001 if((schL2MeasInfo->timePrd !=0) &&
10002 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
10003 (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ))
10005 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10006 err->errCause = RGSCHERR_SCH_L2MEAS;
10009 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
10010 ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
10011 (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
10012 ((schL2MeasInfo->timePrd !=0)&&
10013 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
10014 (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
10016 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10017 err->errCause = RGSCHERR_SCH_L2MEAS;
10020 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
10021 ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
10022 (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
10023 ((schL2MeasInfo->timePrd !=0) &&
10024 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
10025 (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
10027 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10028 err->errCause = RGSCHERR_SCH_L2MEAS;
10031 if((schL2MeasInfo->timePrd !=0) &&
10032 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
10034 RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \
10035 (schL2MeasInfo->avgPrbQciDl.numQci));
10036 ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
10037 schL2MeasInfo->avgPrbQciDl.qci);
10040 err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
10041 err->errCause = RGSCHERR_SCH_L2MEAS;
10046 }/* rgSCHUtlValidateMeasReq */
10047 #endif /* LTE_L2_MEAS */
10048 /******* </AllocHolesMemMgmnt>: END *****/
10051 * @brief API for sending SI configuration confirm from Scheduler to RRM
10055 * Function: rgSCHUtlRgrSiCfgCfm
10057 * This API is invoked to send SI configuration confirm from Scheduler
10059 * This API fills in Pst structure and SAP Ids and invokes
10060 * config confirm API towards RRM.
10062 * @param[in] RgrCfgTransId transId
10063 * @param[in] U8 status
10069 PUBLIC S16 rgSCHUtlRgrSiCfgCfm
10073 RgrCfgTransId transId,
10077 PUBLIC S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status)
10080 RgrCfgTransId transId;
10084 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10086 TRC2(rgSCHUtlRgrSiCfgCfm)
10088 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10089 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10092 if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10093 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10094 transId, status) != ROK)
10096 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10097 "RgUiRgrSiCfgCfm Failed ");
10102 } /* rgSCHUtlRgrSiCfgCfm */
10106 * @brief API for sending Warning SI configuration confirm from
10112 * This API is invoked to send Warning SI configuration confirm
10113 * from Scheduler to RRM.
10114 * This API fills in Pst structure and SAP Ids and invokes
10115 * config confirm API towards RRM.
10117 * @param[in] RgrCfgTransId transId
10118 * @param[in] U8 status
10124 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm
10129 RgrCfgTransId transId,
10133 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status)
10137 RgrCfgTransId transId;
10141 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10143 TRC2(rgSCHUtlRgrWarningSiCfgCfm)
10145 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10146 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10149 if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10150 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10151 transId, siId, status) != ROK)
10153 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10154 "RgUiRgrSiCfgCfm Failed ");
10159 } /* rgSCHUtlRgrWarningSiCfgCfm */
10161 /***********************************************************
10163 * Func : rgSCHUtlPutSiInfo
10165 * Desc : Utility Function to deallocate SI information
10173 **********************************************************/
10175 PUBLIC Void rgSCHUtlPutSiInfo
10180 PUBLIC Void rgSCHUtlPutSiInfo(cell)
10185 U32 sizeOfSiInfo = 0;
10186 TRC2(rgSCHUtlPutSiInfo)
10187 /*Free the buffers in crntSiInfo*/
10188 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
10189 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
10191 sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
10193 for(idx=0; idx < sizeOfSiInfo; idx++)
10195 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
10198 /*Free the buffers in newSiInfo */
10199 RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
10200 RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
10202 sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
10204 for(idx=0; idx < sizeOfSiInfo; idx++)
10206 RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
10211 #endif /*RGR_SI_SCH */
10215 /***********************************************************
10217 * Func : rgSCHUtlGetDrxSchdUesInDl
10219 * Desc : Utility Function to fill the get the list of
10220 * scheduled UEs. On these UE's, drx-inactivity
10221 * timer will be started/restarted.
10230 **********************************************************/
10232 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl
10234 RgSchCellCb *cellCb,
10236 RgSchDlHqProcCb *dlHq,
10237 RgInfUeAlloc *allocInfo,
10238 CmLListCp *dlDrxInactvTmrLst,
10239 CmLListCp *dlInActvLst,
10240 CmLListCp *ulInActvLst
10243 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
10244 RgSchCellCb *cellCb;
10246 RgSchDlHqProcCb *dlHq;
10247 RgInfUeAlloc *allocInfo;
10248 CmLListCp *dlDrxInactvTmrLst;
10249 CmLListCp *dlInActvLst;
10250 CmLListCp *ulInActvLst;
10253 Bool isNewTx = FALSE;
10255 RgSchDrxDlHqProcCb *drxHq;
10256 RgSchDRXCellCb *drxCell = cellCb->drxCb;
10257 RgSchDrxUeCb *drxUe;
10259 Inst inst = cellCb->instIdx;
10261 U8 cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
10265 for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
10267 if(allocInfo->tbInfo[idx].isReTx == FALSE)
10270 /* Removing break here, since in 2 TB case if 2nd TB is proceeding with
10271 retx then drxretx timer should be stopped.*/
10275 /*Stop the DRX retransmission timer as UE scheduled for retx. Here
10276 * we stop the timer and inactivate the UE for both UL and DL.
10277 * This may result in loss of one slot for UL but this trade
10278 * off is taken to avoid the overhead of maintaining a list of UEs
10279 * to be inactivated in the next slot.*/
10280 drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
10281 drxUe = RG_SCH_DRX_GET_UE(ueCb);
10282 if(drxHq->reTxIndx != DRX_INVALID)
10284 /* This condition should never occur */
10285 if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
10287 RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]"
10288 "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
10289 drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId));
10292 drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10293 drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10295 dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10296 ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10298 for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
10300 dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
10301 ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
10304 drxUe->drxDlInactvMask |= dlInactvMask;
10305 drxUe->drxUlInactvMask |= ulInactvMask;
10307 /* if no other condition is keeping ue active,
10308 * inactivate the Ue
10310 if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
10312 /* BUG 2 : HARQ_RTT, changed for consistency */
10313 ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
10315 /* Add to DL inactive list */
10316 cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
10317 ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
10320 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
10322 /*BUG 2: HARQ_RTT changed for consistency */
10323 ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
10325 cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
10326 ueCb->ulDrxInactvLnk.node = (PTR)ueCb;
10329 /* Deleting entry from HARQ RTT queue for the same HARQ proc,
10330 * if exist. This is the special case which can happen iF UL
10331 * scheduling is done later. */
10332 if(drxHq->rttIndx != DRX_INVALID)
10334 cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
10335 &(drxHq->harqRTTEnt));
10337 drxHq->rttIndx = DRX_INVALID;
10340 cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
10341 &(drxHq->harqRetxEnt));
10342 drxHq->reTxIndx = DRX_INVALID;
10347 if(isNewTx == TRUE)
10349 if(ueCb->drxCb->raRcvd == TRUE)
10351 ueCb->drxCb->raRcvd = FALSE;
10353 /* mark the ra bit */
10354 ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10355 ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10357 }/*if(ra->rcvd) == TRUE */
10359 if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
10361 cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
10362 ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
10364 }/*if(isNewTx == TRUE) */
10367 }/* rgSCHUtlGetSchdUes*/
10369 /* ccpu00117452 - MOD - Changed macro name from
10370 RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
10371 #ifdef RGR_CQI_REPT
10373 * @brief This function fills StaInd struct
10377 * Function: rgSCHUtlFillSndStaInd
10378 * Purpose: Fills StaInd struct and sends the
10381 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10382 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10383 * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled
10384 * @param[in] U8 numCqiRept NUmber of reports to be filled
10389 PUBLIC S16 rgSCHUtlFillSndStaInd
10393 RgrStaIndInfo *staInfo,
10397 PUBLIC S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept)
10400 RgrStaIndInfo *staInfo;
10406 /* Fill StaInd for sending collated Latest N CQI rpeorts */
10407 /* Find index in the array from where Latest N
10408 reports needs to be fetched. Use this value to index in the array
10409 and copy the reports into staInfo */
10411 /* Fill the Cell Id of PCC of the UE */
10412 staInfo->cellId = ue->cell->cellId;
10413 staInfo->crnti = ue->ueId;
10415 idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
10417 cmMemcpy ((U8*)&(staInfo->ueCqiInfo.cqiRept),
10418 (U8*)&(ue->schCqiInfo.cqiRept[idxStart]),
10419 numCqiRept * sizeof(RgrUeCqiRept));
10421 staInfo->ueCqiInfo.numCqiRept = numCqiRept;
10423 ue->schCqiInfo.cqiCount = 0;
10425 /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
10426 if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
10428 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10429 "CQI reports for RNTI:%d",ue->ueId);
10435 }/* End of rgSCHUtlFillSndStaInd */
10440 * @brief API for sending STA indication from Scheduler to RRM.
10444 * Function: rgSCHUtlRgrStaInd
10446 * This API is invoked to send STA indication from Scheduler instance to RRM.
10447 * This API fills in Pst structure and RgrStaIndInfo
10448 * and calls the Sta primitive API towards RRM.
10450 * @param[in] cell RgSchCellCb
10451 * @param[in] RgrStsIndInfo *rgrSta
10457 PUBLIC S16 rgSCHUtlRgrStaInd
10460 RgrStaIndInfo *rgrSta
10463 PUBLIC S16 rgSCHUtlRgrStaInd(cell, rgrSta)
10465 RgrStaIndInfo *rgrSta;
10469 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10471 TRC2(rgSCHUtlRgrStaInd)
10474 rgrSap = cell->rgrSap;
10475 if (rgrSap->sapSta.sapState != LRG_BND)
10477 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10478 "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
10479 rgrSap->sapSta.sapState);
10482 RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
10483 cell->rgrSap->sapCfg.suId, rgrSta);
10485 } /* rgSCHUtlRgrStaInd*/
10486 #endif /* End of RGR_CQI_REPT */
10488 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
10490 * @brief Indicates MAC to release any rnti context it has.
10493 * Function : rgSCHUtlIndRntiRls2Mac
10494 * This function indicates MAC for this rnti release.
10495 * In case of ueId change it will indicate MAC
10496 * about the new rnti to be updated.
10497 * It will post a release RNTI indication to MAC.
10501 * @param[in] RgSchCellCb *cell
10502 * @param[in] CmLteRnti rnti
10503 * @param[in] Bool ueIdChng
10504 * @param[in] CmLteRnti newRnti
10509 PUBLIC Void rgSCHUtlIndRntiRls2Mac
10517 PUBLIC Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti)
10525 Inst inst = cell->instIdx;
10526 RgInfRlsRnti rntiInfo;
10528 TRC2(rgSCHUtlIndRntiRls2Mac)
10530 /* Copy the info to rntiInfo */
10531 rntiInfo.cellId = cell->cellId;
10532 rntiInfo.rnti = rnti;
10533 /* Fix : syed ueId change as part of reestablishment.
10534 * Now SCH to trigger this. CRG ueRecfg for ueId change
10536 rntiInfo.ueIdChng = ueIdChng;
10537 rntiInfo.newRnti = newRnti;
10539 rntiInfo.isUeSCellDel = FALSE;
10541 /* Invoke MAC to release the rnti */
10542 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
10543 RgSchMacRlsRnti(&pst, &rntiInfo);
10547 /* LTE_ADV_FLAG_REMOVED_START */
10549 * @brief API for sending LOAD INF indication from Scheduler to RRM.
10552 * Function: rgSCHUtlRgrLoadInfInd
10554 * This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
10555 * This API fills in Pst structure and RgrLoadInfIndInfo
10556 * and calls the Sta primitive API towards RRM.
10558 * @param[in] cell RgSchCellCb
10559 * @param[in] RgrLoadInfIndInfo *rgrLoadInf
10565 PUBLIC S16 rgSCHUtlRgrLoadInfInd
10568 RgrLoadInfIndInfo *rgrLoadInf
10571 PUBLIC S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf)
10573 RgrLoadInfIndInfo *rgrLoadInf;
10577 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10579 TRC2(rgSCHUtlRgrLoadInfInd)
10582 rgrSap = cell->rgrSap;
10583 if (rgrSap->sapSta.sapState != LRG_BND)
10585 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10586 "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
10587 rgrSap->sapSta.sapState);
10590 RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
10591 cell->rgrSap->sapCfg.suId, rgrLoadInf);
10593 } /* rgSCHUtlRgrLoadInfInd*/
10594 /* LTE_ADV_FLAG_REMOVED_END */
10596 /* MS_FIX : syed SCH to act as MASTER in maintaining
10597 * rnti related context. Trigger to rnti del/Chng at SCH
10598 * will result in a Indication to MAC to release its
10599 * RNTI context. MAC inturn indicates the context cleared
10600 * indication to SCH, upon which SCH would set this
10602 * @brief API for sending STA indication from Scheduler to RRM.
10606 * Function: rgSCHUtlRlsRnti
10608 * This API is invoked to indicate MAC to release rnti
10610 * @param[in] RgSchCellCb *cellCb
10611 * @param[in] RgSchRntiLnk *rntiLnk,
10612 * @param[in] Bool ueIdChngd,
10613 * @param[in] CmLteRnti newRnti
10618 PUBLIC Void rgSCHUtlRlsRnti
10621 RgSchRntiLnk *rntiLnk,
10626 PUBLIC Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti)
10628 RgSchRntiLnk *rntiLnk;
10634 TRC2(rgSCHUtlRlsRnti)
10637 if(cell->emtcEnable)
10639 rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
10644 /*Add to Guard Pool*/
10645 cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
10646 rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
10648 /* Fix: syed Explicitly Inidcate MAC to release RNTI */
10649 rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
10656 * @brief This function fills StaInd struct
10660 * Function: rgSCHUtlFillSndUeStaInd
10661 * Purpose: Fills StaInd struct and sends the
10664 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10665 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10666 * @param[in] U8 numCqiRept NUmber of reports to be filled
10671 PUBLIC S16 rgSCHUtlFillSndUeStaInd
10675 RgrUeStaIndInfo *ueStaInfo
10678 PUBLIC S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo)
10681 RgrUeStaIndInfo *ueStaInfo;
10685 ueStaInfo->cellId = cell->cellId;
10686 ueStaInfo->crnti = ue->ueId;
10688 /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
10689 if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
10691 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10692 "UE Sta reports CRNTI:%d",ue->ueId);
10698 }/* End of rgSCHUtlFillSndStaInd */
10703 * @brief API for sending STA indication from Scheduler to RRM.
10707 * Function: rgSCHUtlRgrStaInd
10709 * This API is invoked to send STA indication from Scheduler instance to RRM.
10710 * This API fills in Pst structure and RgrStaIndInfo
10711 * and calls the Sta primitive API towards RRM.
10713 * @param[in] cell RgSchCellCb
10714 * @param[in] RgrStsIndInfo *rgrSta
10720 PUBLIC S16 rgSCHUtlRgrUeStaInd
10723 RgrUeStaIndInfo *rgrUeSta
10726 PUBLIC S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta)
10728 RgrUeStaIndInfo *rgrUeSta;
10732 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10734 TRC2(rgSCHUtlRgrStaInd)
10737 rgrSap = cell->rgrSap;
10738 if (rgrSap->sapSta.sapState != LRG_BND)
10740 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10741 "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
10742 rgrSap->sapSta.sapState);
10745 RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
10746 cell->rgrSap->sapCfg.suId, rgrUeSta);
10748 } /* rgSCHUtlRgrStaInd*/
10752 * @brief function to report DL and UL PRB usage to RRM.
10755 * Function: rgSCHUtlUpdAvgPrbUsage
10756 * This function sends the PRB usage report to
10757 * RRM with the interval configured by RRM.
10759 * @param[in] cell *RgSchCellCb
10765 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage
10770 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage(cell)
10774 CmLteTimingInfo frm;
10775 RgmPrbRprtInd *prbRprtInd;
10778 #ifdef DBG_MAC_RRM_PRB_PRINT
10779 static U32 count = 0;
10780 const U32 reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
10785 TRC2(rgSCHUtlUpdAvgPrbUsage);
10787 frm = cell->crntTime;
10788 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
10794 if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
10796 /* Get the total number of DL and UL slots within the reporting period*/
10797 numDlSf = (cell->prbUsage.rprtPeriod *
10798 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10799 / RGSCH_NUM_SUB_FRAMES;
10800 numUlSf = (cell->prbUsage.rprtPeriod *
10801 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10802 / RGSCH_NUM_SUB_FRAMES;
10806 /* Get the total number of DL and UL slots < 10 ms interval */
10807 numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10808 numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10811 numDlSf = cell->prbUsage.rprtPeriod;
10812 numUlSf = cell->prbUsage.rprtPeriod;
10815 if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
10816 cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd,
10817 sizeof(RgmPrbRprtInd)) != ROK)
10822 cmMemset((U8 *) &prbRprtInd->stQciPrbRpts[0],
10824 (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
10826 prbRprtInd->bCellId = cell->cellId;
10830 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL;
10831 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10833 prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage =
10834 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
10835 (numDlSf * cell->bwCfg.dlTotalBw));
10836 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10837 cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
10843 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL;
10844 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10846 prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage =
10847 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
10848 (numUlSf * cell->ulAvailBw));
10849 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10850 cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
10854 #ifdef DBG_MAC_RRM_PRB_PRINT
10855 if((count % reprotForEvery20Sec) == 0 )
10857 printf("\n====================================================================");
10858 printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n");
10859 printf("======================================================================\n");
10860 printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n",
10861 prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
10862 prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
10863 prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
10864 prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
10865 prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
10866 prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
10867 prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
10868 prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
10871 RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst),
10872 cell->rgmSap->sapCfg.suId, prbRprtInd);
10880 * @brief This function resends the Ta in case of
10881 * max retx failure or DTX for the Ta transmitted
10885 * Function: rgSCHUtlReTxTa
10888 * @param[in] RgSchCellCb *cell
10889 * @param[in] RgSchUeCb *ue
10894 PUBLIC Void rgSCHUtlReTxTa
10896 RgSchCellCb *cellCb,
10900 PUBLIC Void rgSCHUtlReTxTa(cellCb, ueCb)
10901 RgSchCellCb *cellCb;
10905 TRC2(rgSCHUtlReTxTa)
10907 /* If TA Timer is running. Stop it */
10908 if (ueCb->taTmr.tmrEvnt != TMR_NONE)
10910 rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
10912 /*[ccpu00121813]-ADD-If maxretx is reached then
10913 * use outstanding TA val for scheduling again */
10914 if(ueCb->dl.taCb.outStndngTa == TRUE)
10916 ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
10917 ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
10918 ueCb->dl.taCb.outStndngTa = FALSE;
10921 /* Fix : syed TA state updation missing */
10922 ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
10923 rgSCHUtlDlTARpt(cellCb, ueCb);
10928 /* Added function for dropping Paging Message*/
10930 * @brief Handler for BO Updt received for BCCH or PCCH.
10934 * Function : rgSCHChkBoUpdate
10936 * This function shall check for BO received falls within the scheduling window or not
10939 * @param[in] RgSchCellCb *cell
10945 PRIVATE S16 rgSCHChkBoUpdate
10948 RgInfCmnBoRpt *boUpdt
10951 PRIVATE S16 rgSCHChkBoUpdate (cell, boUpdt)
10953 RgInfCmnBoRpt *boUpdt;
10957 U32 crntTimeInSubFrms = 0;
10958 U32 boUpdTimeInSubFrms = 0;
10960 TRC2(rgSCHChkBoUpdate);
10962 crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.slot +
10963 RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI
10964 so incrementing with +1 more */
10965 boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.slot;
10968 distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
10969 boUpdTimeInSubFrms - crntTimeInSubFrms : \
10970 (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
10972 if (distance > RGSCH_PCCHBCCH_WIN)
10978 }/*rgSCHChkBoUpdate*/
10983 * @brief Utility function to calculate the UL reTxIdx in TDD cfg0
10987 * Function : rgSchUtlCfg0ReTxIdx
10989 * Update the reTxIdx according to the rules mentioned
10990 * in 3GPP TS 36.213 section 8 for TDD Cfg0
10992 * @param[in] RgSchCellCb *cell
10993 * @param[in] CmLteTimingInfo phichTime
10994 * @param[in] U8 hqFdbkIdx
10998 PUBLIC U8 rgSchUtlCfg0ReTxIdx
11001 CmLteTimingInfo phichTime,
11005 PUBLIC U8 rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx)
11007 CmLteTimingInfo phichTime;
11011 U8 reTxIdx = RGSCH_INVALID_INFO;
11013 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
11015 U8 ulSF; /* UL SF in the TDD frame */
11017 TRC2(rgSchUtlCfg0ReTxIdx);
11019 ulSf = &cellUl->ulSfArr[hqFdbkIdx];
11020 ulSF = ulSf->ulSfIdx;
11022 /* Check for the UL SF 4 or 9 */
11023 if(ulSF == 9 || ulSF == 4)
11027 if(phichTime.slot == 0 || phichTime.slot == 5)
11031 /* Retx will happen according to the Pusch k table */
11032 reTxIdx = cellUl->schdIdx;
11036 /* Retx will happen at n+7 */
11037 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11038 /* Fetch the corresponding UL slot Idx in UL sf array */
11039 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11042 else if(phichTime.slot == 1 || phichTime.slot == 6)
11044 /* Retx will happen at n+7 */
11045 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11046 /* Fetch the corresponding UL slot Idx in UL sf array */
11047 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11054 * @brief Utility function to calculate total num of PRBs required to
11055 * satisfy DL BO for TM1/TM2/TM6/TM7
11059 * Function : rgSchUtlDlCalc1CwPrb
11061 * Calculate PRBs required for UE to satisfy BO in DL
11063 * Note : Total calculated PRBs will be assigned to *prbReqrd
11066 * @param[in] RgSchCellCb *cell
11067 * @param[in] RgSchUeCb *ue
11068 * @param[in] U32 bo
11069 * @param[out] U32 *prbReqrd
11073 PUBLIC Void rgSchUtlDlCalc1CwPrb
11081 PUBLIC Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd)
11088 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11089 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11093 U8 cfi = dlCell->currCfi;
11095 TRC2(rgSchUtlDlCalc1CwPrb);
11097 iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11098 eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
11100 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11101 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11102 noRes = ((U64)((bo << 3) << 10)) / (eff);
11103 /* Get the number of RBs needed for this transmission */
11104 /* Number of RBs = No of REs / No of REs per RB */
11105 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11108 } /* rgSchUtlDlCalc1CwPrb*/
11111 * @brief Utility function to calculate total num of PRBs required to
11112 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11117 * Function : rgSchUtlDlCalc2CwPrb
11119 * Calculate PRBs required for UE to satisfy BO in DL
11121 * Note : Total calculated PRBs will be assigned to *prbReqrd
11124 * @param[in] RgSchCellCb *cell
11125 * @param[in] RgSchUeCb *ue
11126 * @param[in] U32 bo
11127 * @param[out] U32 *prbReqrd
11131 PUBLIC Void rgSchUtlDlCalc2CwPrb
11139 PUBLIC Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd)
11146 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11147 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11152 U8 cfi = dlCell->currCfi;
11154 TRC2(rgSchUtlDlCalc2CwPrb);
11156 if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
11157 (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
11159 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11160 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
11162 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11163 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11164 noRes = ((U64)((bo << 3) << 10)) / (eff1);
11165 /* Get the number of RBs needed for this transmission */
11166 /* Number of RBs = No of REs / No of REs per RB */
11167 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11171 noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
11172 noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
11173 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
11174 iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
11175 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
11176 eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
11178 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11179 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11180 noRes = ((U64)((bo << 3) << 10)) / (eff1 + eff2);
11181 /* Get the number of RBs needed for this transmission */
11182 /* Number of RBs = No of REs / No of REs per RB */
11183 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11186 } /* rgSchUtlDlCalc2CwPrb */
11189 * @brief Utility function to calculate total num of PRBs required to
11190 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11194 * Function : rgSchUtlCalcTotalPrbReq
11196 * This function calls TM specific routine to calculate PRB
11199 * @param[in] RgSchCellCb *cell
11200 * @param[in] RgSchUeCb *ue
11201 * @param[in] U32 bo
11202 * @param[out] U32 *prbReqrd
11206 PUBLIC Void rgSchUtlCalcTotalPrbReq
11214 PUBLIC Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd)
11221 TRC2(rgSchUtlCalcTotalPrbReq);
11223 /* Call TM specific Prb calculation routine */
11224 (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
11227 } /* rgSchUtlCalcTotalPrbReq */
11230 /***********************************************************
11232 * Func : rgSCHUtlFetchPcqiBitSz
11235 * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
11244 **********************************************************/
11246 PRIVATE U8 rgSCHUtlFetchPcqiBitSz
11253 PRIVATE U8 rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt)
11262 RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
11264 TRC3(rgSCHUtlFetchPcqiBitSz);
11265 confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
11266 if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) &&
11267 (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
11273 ri = cqiCb->perRiVal;
11275 switch(confRepMode)
11277 case RGR_PRD_CQI_MOD10:
11283 case RGR_PRD_CQI_MOD11:
11296 else if(numTxAnt == 4)
11309 /* This is number of antenna case 1.
11310 * This is not applicable for Mode 1-1.
11311 * So setting it to invalid value */
11317 case RGR_PRD_CQI_MOD20:
11325 pcqiSz = 4 + cqiCb->label;
11330 case RGR_PRD_CQI_MOD21:
11345 else if(numTxAnt == 4)
11358 /* This might be number of antenna case 1.
11359 * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
11360 * So setting invalid value.*/
11368 pcqiSz = 4 + cqiCb->label;
11372 pcqiSz = 7 + cqiCb->label;
11388 * @brief Utility function to returns the number of subbands based on the
11393 * Function : rgSchUtlGetNumSbs
11395 * Calculate the number of PRBs
11396 * Update the subbandRequired based on the nPrbs and subband size
11398 * @param[in] RgSchCellCb *cell
11399 * @param[in] RgSchUeCb *ue
11400 * @param[in] U32 *numSbs
11404 PUBLIC U8 rgSchUtlGetNumSbs
11411 PUBLIC U8 rgSchUtlGetNumSbs (cell, ue, numSbs)
11418 //Currently hardcoding MAX prb for each UE
11419 nPrb = ue->ue5gtfCb.maxPrb;
11420 (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
11425 * @brief Utility function to insert the UE node into UE Lst based on the
11426 * number of subbands allocated for the UE for the current TTI.
11430 * Function : rgSchUtlSortInsUeLst
11432 * If subbandRequired < Min, then insert at head
11433 * Else If subbandRequired > Max, then insert at tail
11434 * Else, traverse the list and place the node at the appropriate place
11436 * @param[in] RgSchCellCb *cell
11437 * @param[in] RgSchUeCb *ue
11441 PUBLIC U8 rgSchUtlSortInsUeLst
11449 PUBLIC U8 rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired)
11457 CmLList *firstUeInLst;
11458 CmLList *lastUeInLst;
11460 RgSchCmnUlUe *ueUl;
11462 //firstUeInLst = cmLListFirst(ueLst);
11463 CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
11464 if(NULLP == firstUeInLst)
11466 /* first node to be added to the list */
11467 cmLListAdd2Tail(ueLst, node);
11471 /* Sb Required for the UE is less than the first node in the list */
11472 tempUe = (RgSchUeCb *)(firstUeInLst->node);
11473 ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
11475 if(vrbgRequired <= ueUl->vrbgRequired)
11477 cmLListInsCrnt(ueLst, (node));
11481 /* Sb Required for this UE is higher than the UEs in the list */
11482 lastUeInLst = cmLListLast(ueLst);
11483 tempUe = (RgSchUeCb *)(lastUeInLst->node);
11484 if(vrbgRequired >= ueUl->vrbgRequired)
11486 cmLListAdd2Tail(ueLst, (node));
11490 /* This UE needs to be in the middle. Search and insert the UE */
11491 ueInLst = cmLListFirst(ueLst);
11494 tempUe = (RgSchUeCb *)(ueInLst->node);
11496 if(vrbgRequired <= ueUl->vrbgRequired)
11498 cmLListInsCrnt(ueLst, (node));
11502 ueInLst = cmLListNext(ueLst);
11504 } while(NULLP != ueInLst && ueInLst != firstUeInLst);
11513 * @brief Function to Send LCG GBR register to MAC
11517 * Function: rgSCHUtlBuildNSendLcgReg
11519 * Handler for sending LCG GBR registration
11524 * Processing Steps:
11526 * @param[in] RgSchCellCb *cell
11527 * @param[in] CmLteRnti crnti
11528 * @param[in] U8 lcgId
11529 * @param[in] Bool isGbr
11534 PUBLIC S16 rgSCHUtlBuildNSendLcgReg
11542 PUBLIC S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr)
11550 RgInfLcgRegReq lcgRegReq;
11552 TRC3(rgSCHUtlBuildNSendLcgReg);
11554 cmMemset((U8*)&pst, (U8)0, sizeof(Pst));
11555 lcgRegReq.isGbr = isGbr;
11556 lcgRegReq.cellId = cell->cellId;
11557 lcgRegReq.crnti = crnti;
11558 lcgRegReq.lcgId = lcgId;
11559 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
11560 /* code Coverage portion of the test case */
11561 RgSchMacLcgReg(&pst, &lcgRegReq);
11570 * @brief Function to map RGR pucch type to TFU type
11574 * Function: rgSchUtlGetFdbkMode
11580 * Processing Steps:
11582 * @param[in] RgrSchFrmt1b3TypEnum
11583 * @return TfuAckNackMode
11587 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode
11589 RgrSchFrmt1b3TypEnum fdbkType
11592 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType)
11593 RgrSchFrmt1b3TypEnum fdbkType;
11597 TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
11599 TRC2(rgSchUtlGetFdbkMode);
11603 case RG_SCH_UCI_FORMAT_NON_CA:
11604 case RG_SCH_UCI_FORMAT1A_1B:
11606 mode = TFU_UCI_FORMAT_1A_1B;
11609 case RG_SCH_UCI_FORMAT1B_CS:
11611 mode = TFU_UCI_FORMAT_1B_CS;
11614 case RG_SCH_UCI_FORMAT3:
11616 mode = TFU_UCI_FORMAT_3;
11622 #endif /* TFU_TDD */
11623 #endif /* LTE_ADV */
11624 #endif /*TFU_UPGRADE */
11628 * @brief Send Ue SCell delete to SMAC.
11632 * Function : rgSCHUtlSndUeSCellDel2Mac
11633 * This function populates the struct RgInfRlsRnti and
11634 * get the pst for SMac and mark field isUeSCellDel to TRUE which
11635 * indicates that it is a Ue SCell delete.
11639 * @param[in] RgSchCellCb *cell
11640 * @param[in] CmLteRnti rnti
11645 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac
11651 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti)
11657 Inst inst = cell->instIdx;
11658 RgInfRlsRnti rntiInfo;
11660 TRC2(rgSCHUtlSndUeSCellDel2Mac)
11662 RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti));
11663 /* Copy the info to rntiInfo */
11664 rntiInfo.cellId = cell->cellId;
11665 rntiInfo.rnti = rnti;
11666 /* Fix : syed ueId change as part of reestablishment.
11667 * Now SCH to trigger this. CRG ueRecfg for ueId change
11669 rntiInfo.ueIdChng = FALSE;
11670 rntiInfo.newRnti = rnti;
11671 rntiInfo.isUeSCellDel = TRUE;
11672 /* Invoke MAC to release the rnti */
11673 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
11674 RgSchMacRlsRnti(&pst, &rntiInfo);
11679 * @brief Returns max TB supported by a given txMode
11683 * Function : rgSCHUtlGetMaxTbSupp
11684 * Max TB supported for TM Modes (1,2,5,6 and 7) is 1
11688 * @param[in] RgrTxMode txMode
11689 * @return U8 maxTbCount;
11693 PUBLIC U8 rgSCHUtlGetMaxTbSupp
11698 PUBLIC U8 rgSCHUtlGetMaxTbSupp(txMode)
11704 TRC2(rgSCHUtlGetMaxTbSupp);
11728 RETVALUE(maxTbCount);
11732 * @brief Send Ue SCell delete to SMAC.
11736 * Function : rgSCHTomUtlGetTrigSet
11737 * This function gets the triggerset based on cqiReq
11739 * @param[in] RgSchCellCb *cell
11740 * @param[in] RgSchUeCb ueCb
11741 * @param[in] U8 cqiReq,
11742 * @param[out] U8 *triggerSet
11748 PUBLIC Void rgSCHTomUtlGetTrigSet
11756 PRIVATE S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet)
11763 RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
11766 case RG_SCH_APCQI_SERVING_CC:
11768 /* APeriodic CQI request for Current Carrier.*/
11769 U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
11770 *triggerSet = 1 << (7 - sCellIdx);
11773 case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
11775 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
11778 case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
11780 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
11793 * @brief This function updates the value of UE specific DCI sizes
11797 * Function: rgSCHUtlUpdUeDciSize
11798 * Purpose: This function calculates and updates DCI Sizes in bits.
11800 * Invoked by: Scheduler
11802 * @param[in] RgSchCellCb *cell
11803 * @param[in] RgSchUeCb *ueCb
11804 * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI
11809 PUBLIC Void rgSCHUtlUpdUeDciSize
11816 PUBLIC Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit)
11822 U8 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11823 U8 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11824 if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
11826 dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
11827 dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
11829 if (isCsi2Bit == TRUE)
11831 dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
11835 dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
11838 /* Common CSI is always 1 bit DCI 0 */
11839 dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
11841 /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
11842 if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11844 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11846 if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11848 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11851 /* Remove the Ambiguous Sizes as mentioned in table Table 5.3.3.1.2-1 Spec 36.212-a80 Sec 5.3.3.1.3 */
11852 dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
11853 dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
11855 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize;
11856 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
11858 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize;
11859 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
11861 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11863 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11864 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11865 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11866 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11867 if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
11869 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
11872 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11873 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11874 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11875 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11876 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
11877 } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
11879 /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
11880 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11881 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11882 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11883 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11885 /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource
11886 * on a secondary cell without an uplink configuration associated with the secondary cell */
11887 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11888 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
11889 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11891 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11892 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11893 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11894 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11895 if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
11897 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
11900 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11901 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11902 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11903 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11904 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
11905 } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
11907 rgSCHEmtcUtlUpdUeDciSize(cell, ueCb);
11912 * @brief This function initialises the DCI Size table
11916 * Function: rgSCHUtlCalcDciSizes
11917 * Purpose: This function calculates and initialises DCI Sizes in bits.
11919 * Invoked by: Scheduler
11921 * @param[in] RgSchCellCb *cell
11926 PUBLIC Void rgSCHUtlCalcDciSizes
11931 PUBLIC Void rgSCHUtlCalcDciSizes(cell)
11937 U32 bits = 0, idx = 0;
11939 switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
11941 case TFU_DCI_FORMAT_0:
11943 /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
11945 /*-- Calculate resource block assignment bits need to be set
11946 Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
11947 bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
11948 while ((bits & 0x8000) == 0)
11955 dciSize = 1 /* DCI 0 bit indicator */ + \
11956 1 /* Frequency hoping enable bit field */ + \
11957 (U8)bits /* For frequency Hopping */ + \
11964 2 /* UL Index Config 0 or DAI Config 1-6 */
11968 cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
11970 /* If hoping flag is enabled */
11971 if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
11973 cell->dciSize.dci0HopSize = 1;
11977 cell->dciSize.dci0HopSize = 2;
11980 /* Update common non-CRNTI scrambled DCI 0/1A flag */
11981 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
11983 case TFU_DCI_FORMAT_1A:
11985 /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
11988 /* Calculate resource block assignment bits need to be set
11989 Which is ln(N(N+1)/2) */
11990 bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
11991 while ((bits & 0x8000) == 0)
11998 dciSize += 1 /* Format 1A */ + \
11999 1 /* Local or Distributed */ + \
12000 (U8)bits /* Resource block Assignment */ + \
12003 4 /* HARQ Proc Id */ +
12005 3 /* HARQ Proc Id */ +
12015 cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
12017 /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI,
12018 * and the number of information bits in format 1A is less than that of format 0,
12019 * zeros shall be appended to format 1A until the payload size equals that of format 0. */
12020 /* Compare the size with DCI 1A and DCI 0 and consider the greater one */
12021 if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
12023 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
12025 /* If the number of information bits in format 1A belongs to one of the sizes in
12026 * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
12027 dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
12028 cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
12030 case TFU_DCI_FORMAT_1:
12032 /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
12034 if (cell->bwCfg.dlTotalBw > 10)
12036 dciSize = 1; /* Resource Allocation header bit */
12039 /* Resouce allocation bits Type 0 and Type 1 */
12040 bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
12041 if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
12046 dciSize += (U8)bits /* Resource Allocation bits */ + \
12054 2 /* Redunancy Version */ + \
12063 cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
12065 cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
12068 /* If the UE is not configured to decode PDCCH with CRC
12069 * scrambled by the C-RNTI and the number of information bits in format 1
12070 * is equal to that for format 0/1A, one bit of value zero shall be appended
12072 if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
12074 cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
12077 /* If the number of information bits in format 1 belongs to one of the sizes in
12078 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until
12079 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1
12080 * and is not equal to that of format 0/1A mapped onto the same search space. */
12081 cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
12082 } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
12084 case TFU_DCI_FORMAT_2:
12086 /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
12088 if (cell->bwCfg.dlTotalBw > 10)
12090 dciSize = 1; /* Resource Allocation bit */
12093 dciSize += (U8)bits /* Resource Allocation bits */ + \
12101 1 /* CW Swap Flag */ + \
12102 5 /* MCS for TB1 */+ \
12103 1 /* NDI for TB1 */+ \
12104 2 /* RV for TB1 */ + \
12105 5 /* MCS for TB2 */+ \
12106 1 /* NDI for TB2 */+ \
12107 2 /* RV for TB2 */;
12108 if (cell->numTxAntPorts == 2)
12112 else if (cell->numTxAntPorts == 4)
12116 cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
12117 cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
12119 case TFU_DCI_FORMAT_2A:
12121 /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
12123 if (cell->bwCfg.dlTotalBw > 10)
12125 dciSize = 1; /* Resource Allocation bit */
12128 dciSize += (U8)bits /* Resource Allocation bits */ + \
12136 1 /* CW Swap Flag */ + \
12137 5 /* MCS for TB1 */+ \
12138 1 /* NDI for TB1 */+ \
12139 2 /* RV for TB1 */ + \
12140 5 /* MCS for TB2 */+ \
12141 1 /* NDI for TB2 */+ \
12142 2 /* RV for TB2 */;
12143 if (cell->numTxAntPorts == 4)
12147 cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
12148 cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
12149 rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
12151 case TFU_DCI_FORMAT_3:
12153 /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
12154 cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
12155 if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
12157 cell->dciSize.size[TFU_DCI_FORMAT_3]++;
12160 case TFU_DCI_FORMAT_3A:
12162 /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
12163 cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
12166 case TFU_DCI_FORMAT_6_0A:
12168 rgSCHEmtcGetDciFrmt60ASize(cell);
12170 case TFU_DCI_FORMAT_6_1A:
12172 rgSCHEmtcGetDciFrmt61ASize(cell);
12177 /* DCI format not supported */
12184 * @brief Handler for the CPU OvrLd related state adjustment.
12188 * Function : rgSCHUtlCpuOvrLdAdjItbsCap
12190 * Processing Steps:
12191 * - Record dl/ulTpts
12192 * - Adjust maxItbs to acheive target throughputs
12194 * @param[in] RgSchCellCb *cell
12198 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap
12203 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap(cell)
12209 TRC3(rgSCHUtlCpuOvrLdAdjItbsCap)
12211 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP |
12212 RGR_CPU_OVRLD_DL_TPT_DOWN))
12214 /* Regulate DL Tpt for CPU overload */
12215 if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
12217 tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
12218 /* Upto 0.5% drift in measured vs target tpt is ignored */
12219 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12221 cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
12226 tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
12227 /* Upto 0.5% drift in measured vs target tpt is ignored */
12228 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12230 cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
12233 #ifdef CPU_OL_DBG_PRINTS
12234 printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt,
12235 cell->thresholds.maxDlItbs);
12239 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP |
12240 RGR_CPU_OVRLD_UL_TPT_DOWN))
12242 /* Regualte DL Tpt for CPU overload */
12243 if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
12245 tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
12246 /* Upto 1% drift in measured vs target tpt is ignored */
12247 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12249 cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
12254 tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
12255 /* Upto 1% drift in measured vs target tpt is ignored */
12256 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12258 cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
12261 #ifdef CPU_OL_DBG_PRINTS
12262 printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt,
12263 cell->thresholds.maxUlItbs);
12270 * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
12274 * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12276 * Processing Steps:
12277 * - Validate the config params.
12278 * - Update numUEperTTi CPU OL related information.
12279 * - If successful, return ROK else RFAILED.
12281 * @param[in] RgSchCellCb *cell
12282 * @param[in] U8 cnrtCpuOvrLdIns
12286 PRIVATE Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12292 PRIVATE S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns)
12294 U8 crntCpuOvrLdIns;
12297 RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl);
12298 RgSchCmnCell *cellSch;
12299 U8 maxUeNewDlTxPerTti;
12300 U8 maxUeNewUlTxPerTti;
12302 #ifdef CPU_OL_DBG_PRINTS
12308 cellSch = RG_SCH_CMN_GET_CELL(cell);
12310 maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti;
12311 maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
12313 /* Calculate Maximum Decremen */
12314 maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12315 maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12317 /* Check for DL CPU Commands */
12318 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI )
12320 /* Decrement till 90% of maxUeNewDlTxPerTti */
12321 if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
12323 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12324 cpuInstr->dlNxtIndxDecNumUeTti++;
12325 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] > 1 )
12327 cpuInstr->maxUeNewTxPerTti[tmpslot]--;
12331 #ifdef CPU_OL_DBG_PRINTS
12332 printf("CPU_OL_TTI__ERROR\n");
12334 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12337 #ifdef CPU_OL_DBG_PRINTS
12338 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12340 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12341 cpuInstr->dlNxtIndxDecNumUeTti);
12343 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
12345 if ( cpuInstr->dlNxtIndxDecNumUeTti > 0)
12347 cpuInstr->dlNxtIndxDecNumUeTti--;
12348 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12349 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] < maxUeNewDlTxPerTti )
12351 cpuInstr->maxUeNewTxPerTti[tmpslot]++;
12355 #ifdef CPU_OL_DBG_PRINTS
12356 printf("CPU_OL_TTI__ERROR\n");
12358 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12361 #ifdef CPU_OL_DBG_PRINTS
12362 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12364 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12365 cpuInstr->dlNxtIndxDecNumUeTti);
12367 /* Check for UL CPU commands */
12368 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
12370 /* Decrement till 90% of maxUeNewDlTxPerTti */
12371 if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
12373 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12374 cpuInstr->ulNxtIndxDecNumUeTti++;
12375 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] > 1 )
12377 cpuInstr->maxUeNewRxPerTti[tmpslot]--;
12381 #ifdef CPU_OL_DBG_PRINTS
12382 printf("CPU_OL_TTI__ERROR\n");
12384 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12387 #ifdef CPU_OL_DBG_PRINTS
12388 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12390 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12391 cpuInstr->dlNxtIndxDecNumUeTti);
12393 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
12395 if ( cpuInstr->ulNxtIndxDecNumUeTti > 0)
12397 cpuInstr->ulNxtIndxDecNumUeTti--;
12398 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12399 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] < maxUeNewUlTxPerTti )
12401 cpuInstr->maxUeNewRxPerTti[tmpslot]++;
12405 #ifdef CPU_OL_DBG_PRINTS
12406 printf("CPU_OL_TTI__ERROR\n");
12408 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12411 #ifdef CPU_OL_DBG_PRINTS
12412 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12414 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12415 cpuInstr->dlNxtIndxDecNumUeTti);
12417 #ifdef CPU_OL_DBG_PRINTS
12418 /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
12419 printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
12420 printf("DL Sf numUePerTti:");
12421 for ( idx = 0; idx < 10 ; idx ++ )
12423 printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]);
12425 printf("\nUL Sf numUePerTti:");
12426 for ( idx = 0; idx < 10 ; idx ++ )
12428 printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]);
12434 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
12437 * @brief Handler for the CPU OvrLd related cell Recfg.
12441 * Function : rgSCHUtlResetCpuOvrLdState
12443 * Processing Steps:
12444 * - Validate the config params.
12445 * - Update CPU OL related state information.
12446 * - If successful, return ROK else RFAILED.
12448 * @param[in] RgSchCellCb *cell
12449 * @param[in] U8 cnrtCpuOvrLdIns
12455 PUBLIC S16 rgSCHUtlResetCpuOvrLdState
12461 PUBLIC S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns)
12463 U8 crntCpuOvrLdIns;
12468 RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
12471 TRC3(rgSCHUtlResetCpuOvrLdState)
12473 #ifdef CPU_OL_DBG_PRINTS
12474 printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
12476 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd");
12478 if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
12480 /* The CPU OL instruction received with RESET (0), hence reset it */
12481 #ifdef CPU_OL_DBG_PRINTS
12482 printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
12484 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD");
12485 cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
12486 /* Reset the max UL and DL itbs to 26 */
12487 cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
12488 cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
12489 /* Reset the num UE per TTI intructions */
12490 cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
12491 cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
12492 for ( idx = 0; idx < 10; idx++ )
12494 cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] =
12495 schCmnCell->dl.maxUeNewTxPerTti;
12496 cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] =
12497 schCmnCell->ul.maxUeNewTxPerTti;
12502 /* Check and Update numUEPer TTI based CPU overload instruction before
12503 * going for TP based CPU OL
12504 * TTI based intrcuctions shall be > 0xF */
12505 if ( crntCpuOvrLdIns > 0xF )
12507 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
12508 /* If need to have both TP and numUePerTti instrcution together in
12509 * one command then dont return from here */
12513 crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
12514 (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
12515 if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) &&
12516 (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
12518 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12521 crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
12522 (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
12523 if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) &&
12524 (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
12526 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12529 if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
12531 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12535 cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
12539 if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
12541 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
12542 (cell->measurements.ulTpt * 3 )/100;
12546 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
12547 (cell->measurements.ulTpt * 2 )/100;
12549 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to "
12550 "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
12551 #ifdef CPU_OL_DBG_PRINTS
12552 printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
12553 cell->measurements.ulTpt);
12559 if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
12561 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
12562 (cell->measurements.dlTpt * 1 )/100;
12566 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
12567 (cell->measurements.dlTpt * 1 )/100;
12569 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to "
12570 "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
12572 #ifdef CPU_OL_DBG_PRINTS
12573 printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
12574 cell->measurements.dlTpt);
12577 rgSCHUtlCpuOvrLdAdjItbsCap(cell);
12581 PUBLIC S16 rgSCHUtlAddToResLst
12584 RgSchIotRes *iotRes
12587 cmLListAdd2Tail(cp, &iotRes->resLnk);
12588 iotRes->resLnk.node = (PTR)iotRes;
12591 PUBLIC S16 rgSCHUtlDelFrmResLst
12594 RgSchIotRes *iotRes
12597 CmLListCp *cp = NULLP;
12598 RgSchEmtcUeInfo *emtcUe = NULLP;
12599 emtcUe = RG_GET_EMTC_UE_CB(ue);
12600 if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
12602 cp = &emtcUe->ulResLst;
12603 }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
12605 cp = &emtcUe->dlResLst;
12608 RLOG0(L_INFO, "*****restype mismatch");
12614 RLOG0(L_INFO,"****error count*****\n");
12618 cmLListDelFrm(cp, &iotRes->resLnk);
12619 iotRes->resLnk.node = NULLP;
12623 /**********************************************************************
12626 **********************************************************************/