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 "envopt.h" /* environment options */
41 #include "envdep.h" /* environment dependent */
42 #include "envind.h" /* environment independent */
43 #include "gen.h" /* general layer */
44 #include "ssi.h" /* system service interface */
45 #include "cm_hash.h" /* common hash list */
46 #include "cm_llist.h" /* common linked list library */
47 #include "cm_err.h" /* common error */
48 #include "cm_lte.h" /* common LTE */
53 #include "rg_sch_err.h"
54 #include "rg_sch_inf.h"
56 #include "rg_sch_cmn.h"
58 #include "rl_interface.h"
59 #include "rl_common.h"
61 /* header/extern include files (.x) */
62 #include "gen.x" /* general layer typedefs */
63 #include "ssi.x" /* system services typedefs */
64 #include "cm5.x" /* common timers */
65 #include "cm_hash.x" /* common hash list */
66 #include "cm_lib.x" /* common library */
67 #include "cm_llist.x" /* common linked list */
68 #include "cm_mblk.x" /* memory management */
69 #include "cm_tkns.x" /* common tokens */
70 #include "cm_lte.x" /* common tokens */
71 #include "tfu.x" /* TFU types */
72 #include "lrg.x" /* layer management typedefs for MAC */
73 #include "rgr.x" /* layer management typedefs for MAC */
75 #include "rg_sch_inf.x" /* typedefs for Scheduler */
76 #include "rg_sch.x" /* typedefs for Scheduler */
77 #include "rg_sch_cmn.x" /* typedefs for Scheduler */
79 #include "rg_sch_emtc_ext.x"
84 U32 rgNumPrachRecvd =0; /* Num of Rach Req received including dedicated preambles */
85 U32 rgNumRarSched =0; /* Num of RARs sent */
86 U32 rgNumBI =0; /* Num of BackOff Ind sent */
87 U32 rgNumMsg3CrcPassed =0; /* Num of CRC success for Msg3 */
88 U32 rgNumMsg3CrcFailed =0; /* Num of CRC fail for Msg 3 */
89 U32 rgNumMsg3FailMaxRetx =0; /* Num of Msg3 fail after Max Retx attempts */
90 U32 rgNumMsg4Ack =0; /* Num of Acks for Msg4 Tx */
92 /* Num of Nacks for Msg4 Tx */
93 U32 rgNumMsg4FailMaxRetx =0; /* Num of Msg4 Tx failed after Max Retx attempts */
94 U32 rgNumSrRecvd =0; /* Num of Sched Req received */
95 U32 rgNumSrGrant =0; /* Num of Sched Req Grants sent */
96 U32 rgNumMsg3CrntiCE =0; /* Num of Msg 3 CRNTI CE received */
97 U32 rgNumDedPream =0; /* Num of Dedicated Preambles recvd */
98 U32 rgNumMsg3CCCHSdu =0; /* Num of Msg 3 CCCH Sdus recvd */
99 U32 rgNumCCCHSduCrntiNotFound =0; /*UE Ctx not found for CCCH SDU Msg 3 */
100 U32 rgNumCrntiCeCrntiNotFound =0; /*UE Ctx not found for CRNTI CE Msg 3 */
101 U32 rgNumMsg4WithCCCHSdu =0; /* Num of Msg4 with CCCH Sdu */
102 U32 rgNumMsg4WoCCCHSdu =0; /* Num of Msg4 without CCCH Sdu */
103 U32 rgNumMsg4Dtx =0; /* Num of DTX received for Msg 4 */
104 U32 rgNumMsg3AckSent =0; /* Num of PHICH Ack sent for Msg 3 */
105 U32 rgNumMsg3NackSent =0; /* Num of PHICH Nack sent for Msg 3 */
106 U32 rgNumMsg4PdcchWithCrnti =0; /* Num of PDCCH for CRNTI based contention resolution */
107 U32 rgNumRarFailDuetoRntiExhaustion =0; /* Num of RACH Failures due to RNTI pool exhaution */
108 U32 rgNumTAModified =0; /* Num of times TA received is different from prev value */
109 U32 rgNumTASent =0; /* Num of TA Command sent */
110 U32 rgNumMsg4ToBeTx =0; /* Num of times MSG4 that should be sent */
111 U32 rgNumMsg4Txed =0; /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */
112 U32 rgNumMsg3DtxRcvd =0; /* CRC Fail with SINR < 0 */
114 U32 rgNumDedPreamUECtxtFound =0; /* Num of Dedicated Preambles recvd */
116 PRIVATE U8 rgSchDciAmbigSizeTbl[61] = {0,0,0,0,0,0,0,0,0,0,0,
117 0,1,0,1,0,1,0,0,0,1,
118 0,0,0,1,0,1,0,0,0,0,
119 0,1,0,0,0,0,0,0,0,1,
120 0,0,0,1,0,0,0,0,0,0,
121 0,0,0,0,0,1,0,0,0,0};
125 EXTERN U32 rgSchCmnBetaCqiOffstTbl[16];
126 EXTERN U32 rgSchCmnBetaRiOffstTbl[16];
127 EXTERN RgSchdApis rgSchCmnApis;
128 EXTERN PUBLIC S16 RgUiRgmSendPrbRprtInd ARGS((
131 RgmPrbRprtInd *prbRprtInd
134 EXTERN PUBLIC S16 RgUiRgmSendTmModeChangeInd ARGS((
137 RgmTransModeInd *txModeChngInd
140 EXTERN PUBLIC S16 rgSCHEmtcUtlGetSfAlloc ARGS((
143 EXTERN PUBLIC S16 rgSCHEmtcUtlPutSfAlloc ARGS((
146 EXTERN PUBLIC Void rgSCHEmtcUtlUpdUeDciSize ARGS((
150 EXTERN PUBLIC Void rgSCHEmtcGetDciFrmt61ASize ARGS((
153 EXTERN PUBLIC Void rgSCHEmtcGetDciFrmt60ASize ARGS((
156 EXTERN PUBLIC S16 rgSCHEmtcUtlFillPdschDciInfo ARGS((
157 TfuPdschDciInfo *pdsch,
160 EXTERN PUBLIC Void rgSCHEmtcUtlRlsRnti ARGS((
162 RgSchRntiLnk *rntiLnk,
165 EXTERN PUBLIC S16 rgSCHEmtcPdcchAlloc ARGS((
169 EXTERN PUBLIC Void rgSCHEmtcPdcchFree ARGS((
174 /* Functions specific to TM1/TM2/TM6/TM7 for PRB calculation*/
175 PUBLIC Void rgSchUtlDlCalc1CwPrb ARGS(( RgSchCellCb *cell,
180 /* Functions specific to TM3/TM4 for PRB calculation*/
181 PUBLIC Void rgSchUtlDlCalc2CwPrb ARGS(( RgSchCellCb *cell,
187 PUBLIC RgSchCellCb* rgSchUtlGetCellCb ARGS(( Inst inst,
192 typedef Void (*RgSchUtlDlCalcPrbFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
193 U32 bo, U32 *prbRequrd));
195 /* Functions specific to each transmission mode for PRB calculation*/
196 RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[7] = {rgSchUtlDlCalc1CwPrb,
197 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
198 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb};
201 /* Functions specific to each transmission mode for PRB calculation*/
202 RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[9] = {rgSchUtlDlCalc1CwPrb,
203 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
204 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb, NULLP, NULLP};
209 /* The below table will be used to map the UL SF number in a TDD Cfg 0
210 frame to the ul Sf array maintained in cellCb */
211 PRIVATE U8 rgSchTddCfg0UlSfTbl[] = {2, 3, 4, 7, 8, 9};
214 PRIVATE S16 rgSCHUtlUlAllocDbInit ARGS((
219 PRIVATE Void rgSCHUtlUlAllocDbDeinit ARGS((
223 PRIVATE S16 rgSCHUtlUlHoleDbInit ARGS((
230 PRIVATE Void rgSCHUtlUlHoleDbDeinit ARGS((
235 PRIVATE S16 rgSCHChkBoUpdate ARGS((
237 RgInfCmnBoRpt *boUpdt
240 PRIVATE U8 rgSCHUtlFetchPcqiBitSz ARGS((
246 /* sorted in ascending order of tbSz */
247 CONSTANT struct rgSchUtlBcchPcchTbSz
249 U8 rbIndex; /* RB index {2,3} */
250 U16 tbSz; /* one of the Transport block size in bits of
252 /* Corrected allocation for common channels */
254 } rgSchUtlBcchPcchTbSzTbl[44] = {
255 { 2, 32, 0 }, { 2, 56, 1 }, { 2, 72, 2 }, { 3, 88, 1 },
256 { 2, 104, 3 }, { 2, 120, 4 }, { 2, 144, 5 }, { 2, 176, 6 },
257 { 3, 208, 4 }, { 2, 224, 7 }, { 2, 256, 8 }, { 2, 296, 9 },
258 { 2, 328, 10 }, { 2, 376, 11 }, { 3, 392, 8 }, { 2, 440, 12 },
259 { 3, 456, 9 }, { 2, 488, 13 }, { 3, 504, 10 }, { 2, 552, 14 },
260 { 3, 584, 11 }, { 2, 600, 15 }, { 2, 632, 16 }, { 3, 680, 12 },
261 { 2, 696, 17 }, { 3, 744, 13 }, { 2, 776, 18 }, { 2, 840, 19 },
262 { 2, 904, 20 }, { 3, 968, 16 }, { 2, 1000, 21 }, { 2, 1064, 22 },
263 { 2, 1128, 23 }, { 3, 1160, 18 }, { 2, 1192, 24 }, { 2, 1256, 25 },
264 { 3, 1288, 19 }, { 3, 1384, 20 }, { 2, 1480, 26 }, { 3, 1608, 22 },
265 { 3, 1736, 23 }, { 3, 1800, 24 }, { 3, 1864, 25 }, { 3, 2216, 26 }
272 /* forward references */
274 PRIVATE Void rgSCHUtlUpdPrachOcc ARGS((
276 RgrTddPrachInfo *cellCfg));
279 #define RGSCH_NUM_PCFICH_REG 4
280 #define RGSCH_NUM_REG_PER_CCE 9
281 #define RGSCH_NUM_REG_PER_PHICH_GRP 3
284 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _iPhich) {\
285 (_phich)->hqFeedBack = _hqFeedBack; \
286 (_phich)->rbStart = _rbStart; \
287 (_phich)->nDmrs = _nDmrs; \
288 (_phich)->iPhich = _iPhich; \
289 (_phich)->lnk.next = NULLP; \
290 (_phich)->lnk.prev = NULLP; \
291 (_phich)->lnk.node = (PTR)(_phich); \
294 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _isForMsg3) {\
295 (_phich)->hqFeedBack = _hqFeedBack; \
296 (_phich)->rbStart = _rbStart; \
297 (_phich)->nDmrs = _nDmrs; \
298 (_phich)->isForMsg3 = _isForMsg3; \
299 (_phich)->lnk.next = NULLP; \
300 (_phich)->lnk.prev = NULLP; \
301 (_phich)->lnk.node = (PTR)(_phich); \
305 #define RGSCH_PHICH_ALLOC(_inst,_dataPtr, _size, _ret) {\
306 _ret = rgSCHUtlAllocSBuf(_inst, (Data **)&_dataPtr, _size); \
309 /* ccpu00117052 - MOD - Passing double pointer
310 for proper NULLP assignment*/
311 #define RGSCH_PHICH_FREE(_inst, _dataPtr, _size) {\
312 rgSCHUtlFreeSBuf(_inst, (Data **)(&(_dataPtr)), _size); \
316 #define RGSCH_GETBIT(a, b) ((((U8*)a)[(b)>>3] >> ((7-((b)&7)))) & 1)
322 * Desc: This function finds of the Power of x raised to n
324 * Ret: value of x raised to n
332 PUBLIC F64 rgSCHUtlPower
338 PUBLIC F64 rgSCHUtlPower(x, n)
349 RETVALUE( x * rgSCHUtlPower( x, n-1 ) );
353 RETVALUE( (1/x) * rgSCHUtlPower( x, n+1 ) );
355 } /* end of rgSCHUtlPower*/
361 * Desc: This function parses bits x to y of an array and
362 * returns the integer value out of it.
364 * Ret: integer value of z bits
372 PUBLIC U32 rgSCHUtlParse
380 PUBLIC U32 rgSCHUtlParse(buff, startPos, endPos, buffSize)
387 U8 pointToChar,pointToEnd, loop;
388 U8 size = endPos - startPos;
391 pointToEnd = (startPos)%8;
392 for ( loop=0; loop<size; loop++)
394 pointToChar = (((startPos)+loop)/8);
395 if (RGSCH_GETBIT(buff+pointToChar,pointToEnd%8)==1)
397 result=result+(rgSCHUtlPower(2,(size-loop-1)));
401 RETVALUE((U32)result);
402 } /* end of rgSCHUtlParse*/
406 * Fun: rgSCHUtlFindDist
408 * Desc: This function calculates the iterations need to cover
409 * before the valid Index can be used for next possible Reception
411 * Ret: integer value of z bits
419 PUBLIC U8 rgSCHUtlFindDist
425 PUBLIC U8 rgSCHUtlFindDist(crntTime, tempIdx)
431 /* ccpu00137113- Distance is not estimated properly if the periodicity is
432 * equal to RG_SCH_PCQI_SRS_SR_TRINS_SIZE.
434 while(crntTime<=tempIdx)
436 crntTime += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
440 } /* end of rgSCHUtlFindDist*/
445 * @brief This function checks availability of a PDCCH
449 * Function: rgSCHUtlPdcchAvail
450 * Purpose: This function checks if a particular PDCCH is in use.
451 * map field of PDCCH is used to track the CCEs arleady
452 * allocated. Each bit of map represents one CCE and the
453 * LSBit of first byte represents CCE 0.
455 * 1. Locate the set of bits that represent the PDCCH for
456 * the provided location.
457 * 2. If the value of the bits is non-zero one or many CCEs
458 * for the PDCCH are in use and hence the PDCCH is not available.
459 * 3. If pdcch is available, assign it to [out]pdcch.
460 * 4. Set all of the bits to one. There is no check performed
461 * to see if the PDCCH is available.
463 * Invoked by: scheduler
465 * @param[in] RgSchCellCb* cell
466 * @param[in] RgSchPdcchInfo* pdcchInfo
468 * @param[in] U8 aggrLvl
469 * @param[out] RgSchPdcch** pdcch
471 * -# TRUE if available
476 PUBLIC Bool rgSCHUtlPdcchAvail
479 RgSchPdcchInfo *pdcchInfo,
480 CmLteAggrLvl aggrLvl,
484 PUBLIC Bool rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, pdcch)
486 RgSchPdcchInfo *pdcchInfo;
487 CmLteAggrLvl aggrLvl;
495 Inst inst = cell->instIdx;
499 TRC2(rgSCHUtlPdcchAvail);
503 byte = &pdcchInfo->map[0];
504 initMask = (0xffff >> (16 - aggrLvl));
506 /* if N(symbol, xPDCCH) =2, then xPDCCH will be candidates in
507 * search space of index {0,1,2,3} and {8,9,..14}
509 if ((cell->cell5gtfCb.cfi == 2) && (aggrLvl == CM_LTE_AGGR_LVL2))
511 offsetStepMask = 0xc;
515 offsetStepMask = 0xc0;
518 /* Loop till the number of bytes available in the CCE map */
519 while (offset < ((pdcchInfo->nCce+ 7) >> 3))
521 byte = &pdcchInfo->map[offset];
522 /* Checking for available CCE */
523 if ((*byte & currMask) == 0)
527 /* if the number of CCEs required are not available, move to next offset */
528 if (currMask & offsetStepMask)
535 /* Move to the next available CCE index in the current byte(cce map) */
536 currMask = currMask << aggrLvl;
540 if ((offset >= ((pdcchInfo->nCce + 7) >> 3)) ||
541 ((aggrLvl == CM_LTE_AGGR_LVL16) && (offset > 0)))
546 byte = &pdcchInfo->map[offset];
548 if (cell->pdcchLst.first != NULLP)
550 *pdcch = (RgSchPdcch *)(cell->pdcchLst.first->node);
551 cmLListDelFrm(&cell->pdcchLst, cell->pdcchLst.first);
555 ret = rgSCHUtlAllocSBuf(inst, (Data **)pdcch, sizeof(RgSchPdcch));
565 /* ALL CCEs will be used in case of level 16 */
566 if (aggrLvl == CM_LTE_AGGR_LVL16)
568 *(byte+1) |= currMask;
570 (*pdcch)->aggrLvl = aggrLvl;
571 cmLListAdd2Tail(&pdcchInfo->pdcchs, &((*pdcch)->lnk));
572 (*pdcch)->lnk.node = (PTR)*pdcch;
573 (*pdcch)->nCce = aggrLvl;
574 (*pdcch)->ue = NULLP;
582 * @brief This function releases a PDCCH
586 * Function: rgSCHUtlPdcchPut
587 * Purpose: This function releases a PDCCH.
589 * 1. Locate the set of bits that represent the PDCCH for
590 * the provided location.
591 * 2. Set all of the bits to zero.
592 * 3. Release the memory of PDCCH to the cell free Q
594 * Invoked by: scheduler
596 * @param[in] RgSchPdcchInfo* pdcchInfo
598 * @param[in] U8 aggrLvl
603 PUBLIC Void rgSCHUtlPdcchPut
606 RgSchPdcchInfo *pdcchInfo,
610 PUBLIC Void rgSCHUtlPdcchPut(cell, pdcchInfo, pdcch)
612 RgSchPdcchInfo *pdcchInfo;
620 TRC2(rgSCHUtlPdcchPut);
622 switch(pdcch->aggrLvl)
624 case CM_LTE_AGGR_LVL2:
625 offset = (pdcch->nCce >> 1) & 3;
626 mask = 0x3 << (offset * 2); /*ccpu00128826 - Offset Correction */
628 case CM_LTE_AGGR_LVL4:
629 offset = (pdcch->nCce >> 2) & 1;
630 mask = 0xf << (offset * 4);/*ccpu00128826 - Offset Correction */
632 case CM_LTE_AGGR_LVL8:
635 case CM_LTE_AGGR_LVL16:
641 /* Placing common computation of byte from all the cases above here
643 byte = &pdcchInfo->map[pdcch->nCce >> 3];
645 cmLListDelFrm(&pdcchInfo->pdcchs, &pdcch->lnk);
646 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
647 pdcch->lnk.node = (PTR)pdcch;
656 * @brief This function initializes PDCCH information for frame
660 * Function: rgSCHUtlPdcchInit
661 * Purpose: This function initializes PDCCH information for
662 * a subframe. It removes the list of PDCCHs allocated
663 * in the prior use of this subframe structure.
665 * Invoked by: rgSCHUtlSubFrmPut
667 * @param[in] RgSchCellCb* cell
668 * @param[in] RgSubFrm* subFrm
673 PUBLIC Void rgSCHUtlPdcchInit
680 PUBLIC Void rgSCHUtlPdcchInit(cell, subFrm, nCce)
686 RgSchPdcchInfo *pdcchInfo;
688 Inst inst = cell->instIdx;
692 TRC2(rgSCHUtlPdcchInit);
694 pdcchInfo = &subFrm->pdcchInfo;
695 while(pdcchInfo->pdcchs.first != NULLP)
697 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
698 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
699 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
702 cmLListInit(&pdcchInfo->pdcchs);
705 subFrm->relPdcch = NULLP;
708 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
710 /* The bitMap array size is the number of ceiling(CCEs/8) */
711 /* If nCce received is not the same as the one stored in
712 * pdcchInfo, free the pdcchInfo map */
714 if(pdcchInfo->nCce != nCce)
718 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), cceMapSz);
720 pdcchInfo->nCce = nCce;
721 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
722 rgSCHUtlAllocSBuf(inst, (Data **)&pdcchInfo->map,
724 if (pdcchInfo->map == NULLP)
726 /* Generate log error here */
731 cmMemset(subFrm->pdcchInfo.map, 0, cceMapSz);
732 /* If nCce is not exactly same as the bitMap size(no of bits allocated
733 * to represent the Cce's, then mark the extra bits as unavailable
734 extra bits = (((pdcchInfo->nCce + 7) >> 3)*8) - pdcchInfo->nCce
735 The last byte of bit map = subFrm->pdcchInfo.map[((pdcchInfo->nCce + 7) >> 3) - 1]
736 NOTE : extra bits are most significant of the last byte eg. */
737 extraBits = (cceMapSz)*8 - pdcchInfo->nCce;
738 subFrm->pdcchInfo.map[cceMapSz - 1] |=
739 ((1 << extraBits) - 1) << (8 - extraBits);
743 /* LTE_ADV_FLAG_REMOVED_START */
745 * @brief This function frees Pool
748 * Function: rgSchSFRTotalPoolFree
750 * Invoked by: rgSchSFRTotalPoolInit
752 * @param[in] RgSchCellCb* cell
753 * @param[in] RgSubFrm* subFrm
758 PUBLIC Void rgSchSFRTotalPoolFree
760 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo,
764 PUBLIC Void rgSchSFRTotalPoolFree(sfrTotalPoolInfo, cell)
765 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo;
771 TRC2(rgSchSFRTotalPoolFree);
773 /*Deinitialise if these cc pools and ce pools are already existent*/
774 l = &sfrTotalPoolInfo->ccPool;
778 /*REMOVING Cell Centred POOLS IF ANY*/
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));
789 /*REMOVING Cell Edged POOLS IF ANY*/
790 l = &sfrTotalPoolInfo->cePool;
794 n = cmLListDelFrm(l, n);
796 /* Deallocate buffer */
797 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
799 /* Deallocate buffer */
800 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
807 * @brief This function resets temporary variables in Pool
810 * Function: rgSchSFRResetPoolVariables
812 * Invoked by: rgSCHSFRUtlTotalPoolInit
814 * @param[in] RgSchCellCb* cell
815 * @param[in] RgSubFrm* subFrm
820 PUBLIC S16 rgSchSFRTotalPoolInit
826 PRIVATE Void rgSchSFRTotalPoolInit(cell, sf)
831 /* Initialise the variables */
832 RgSchSFRPoolInfo *sfrCCPool;
833 RgSchSFRPoolInfo *sfrCEPool;
836 CmLList *temp = NULLP;
839 TRC2(rgSchSFRTotalPoolInit);
841 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
842 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = 0;
843 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = 0;
844 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = 0;
845 sf->sfrTotalPoolInfo.CC1 = FALSE;
846 sf->sfrTotalPoolInfo.CC2 = FALSE;
847 /*Initialise the CE Pools*/
848 cmLListInit (&(sf->sfrTotalPoolInfo.cePool));
850 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
853 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
854 "CE Pool memory allocation FAILED for cell");
855 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
859 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
862 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
863 "CE Pool memory allocation FAILED for cell ");
864 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
868 l = &sf->sfrTotalPoolInfo.cePool;
869 cmLListAdd2Tail(l, temp);
871 /*Initialise Bandwidth and startRB and endRB for each pool*/
874 /* Initialise the CE Pools */
875 sfrCEPool = (RgSchSFRPoolInfo*)n->node;
877 sfrCEPool->poolstartRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb;
878 sfrCEPool->poolendRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb;
879 sfrCEPool->bw = sfrCEPool->poolendRB - sfrCEPool->poolstartRB + 1;
880 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = sfrCEPool->bw;
882 sfrCEPool->bwAlloced = 0;
883 sfrCEPool->type2Start = sfrCEPool->poolstartRB;
884 sfrCEPool->type2End = RGSCH_CEIL(sfrCEPool->poolstartRB, cell->rbgSize);
885 sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1;
886 sfrCEPool->pwrHiCCRange.startRb = 0;
887 sfrCEPool->pwrHiCCRange.endRb = 0;
889 /*Initialise CC Pool*/
890 cmLListInit (&(sf->sfrTotalPoolInfo.ccPool));
892 /*Add memory and Update CCPool*/
893 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
896 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
897 "CC Pool memory allocation FAILED for cell ");
898 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
902 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
905 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
906 "CC Pool memory allocation FAILED for cell ");
907 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
911 l = &sf->sfrTotalPoolInfo.ccPool;
912 cmLListAdd2Tail(l, temp);
914 /*Initialise Bandwidth and startRB and endRB for each pool*/
915 if(sfrCEPool->poolstartRB)
918 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
920 sfrCCPool->poolstartRB = 0;
921 sfrCCPool->poolendRB = sfrCEPool->poolstartRB - 1;
922 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
923 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = sfrCCPool->bw;
924 sfrCCPool->bwAlloced = 0;
925 sfrCCPool->type2Start = 0;
926 sfrCCPool->type2End = 0;
927 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
928 sf->sfrTotalPoolInfo.CC1 = TRUE;
929 sfrCCPool->pwrHiCCRange.startRb = 0;
930 sfrCCPool->pwrHiCCRange.endRb = 0;
935 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
937 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
938 sfrCCPool->poolendRB = sf->bw - 1;
939 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
940 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
941 sfrCCPool->CCPool2Exists = TRUE;
942 sfrCCPool->bwAlloced = 0;
943 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
944 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
945 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
946 sf->sfrTotalPoolInfo.CC2 = TRUE;
947 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
948 sfrCCPool->pwrHiCCRange.startRb = 0;
949 sfrCCPool->pwrHiCCRange.endRb = 0;
952 if((sfrCEPool->poolendRB != sf->bw - 1) && (!sfrCCPool->poolstartRB))
954 /*Add memory and Update CCPool*/
955 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
958 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
959 "CC Pool memory allocation FAILED for cell ");
960 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
964 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
967 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
968 "CC Pool memory allocation FAILED for cell ");
969 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
973 cmLListAdd2Tail(l, temp);
976 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
978 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
979 sfrCCPool->poolendRB = sf->bw - 1;
980 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
981 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
982 sfrCCPool->CCPool2Exists = TRUE;
983 sfrCCPool->bwAlloced = 0;
984 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
985 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
986 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
987 sf->sfrTotalPoolInfo.CC2 = TRUE;
988 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
989 sfrCCPool->pwrHiCCRange.startRb = 0;
990 sfrCCPool->pwrHiCCRange.endRb = 0;
993 sf->sfrTotalPoolInfo.CCRetx = FALSE;
994 sf->sfrTotalPoolInfo.CERetx = FALSE;
996 sf->sfrTotalPoolInfo.ccBwFull = FALSE;
997 sf->sfrTotalPoolInfo.ceBwFull = FALSE;
998 sf->sfrTotalPoolInfo.isUeCellEdge = FALSE;
1002 * @brief This function resets temporary variables in RNTP Prepration
1005 * Function: rgSchDSFRRntpInfoInit
1007 * Invoked by: rgSCHSFRUtlTotalPoolInit
1009 * @param[in] TknStrOSXL* rntpPtr
1010 * @param[in] RgSubFrm* subFrm
1015 PUBLIC S16 rgSchDSFRRntpInfoInit
1017 TknStrOSXL *rntpPtr,
1022 PRIVATE Void rgSchDSFRRntpInfoInit(rntpPtr, cell, bw)
1023 TknStrOSXL *rntpPtr;
1028 Inst inst = cell->instIdx;
1031 TRC2(rgSchDSFRRntpInfoInit);
1033 rntpPtr->pres = PRSNT_NODEF;
1035 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1039 /* Allocate memory for "scheduled UE" Info */
1040 if((rgSCHUtlAllocSBuf(inst, (Data**)&(rntpPtr->val),
1041 (len * sizeof(U8)))) != ROK)
1043 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
1051 * @brief This function release RNTP pattern from subFrame and Cell
1054 * Function: rgSchDSFRRntpInfoFree
1056 * Invoked by: rgSCHSFRUtlTotalPoolInit
1058 * @param[in] TknStrOSXL* rntpPtr
1059 * @param[in] RgSubFrm* subFrm
1064 PUBLIC S16 rgSchDSFRRntpInfoFree
1066 TknStrOSXL *rntpPtr,
1071 PRIVATE Void rgSchDSFRRntpInfoFree(rntpPtr, cell, bw)
1072 TknStrOSXL *rntpPtr;
1077 Inst inst = cell->instIdx;
1080 TRC2(rgSchDSFRRntpInfoFree);
1082 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1084 if(rntpPtr->pres == PRSNT_NODEF)
1086 rgSCHUtlFreeSBuf(inst, (Data **)(&(rntpPtr->val)),(len * sizeof(U8)));
1087 rntpPtr->pres = NOTPRSNT;
1095 * @brief This function resets temporary variables in Pool
1098 * Function: rgSchSFRResetPoolVariables
1099 * Purpose: Initialise the dynamic variables in each pool.
1100 * Reset bwAlloced, bwAssigned, type2End, type0End, type2Start
1101 * Invoked by: rgSCHSFRUtlTotalPoolReset
1103 * @param[in] RgSchCellCb* cell
1104 * @param[in] RgSchSFRPoolInfo *pool
1109 PRIVATE Void rgSchSFRResetPoolVariables
1112 RgSchSFRPoolInfo *pool
1115 PRIVATE Void rgSchSFRResetPoolVariables(cell, pool)
1117 RgSchSFRPoolInfo *pool;
1121 TRC2(rgSchSFRResetPoolVariables);
1122 pool->bwAlloced = 0;
1124 /*type0end will be the last RBG in pool with all available RBs*/
1125 pool->type0End = (((pool->poolendRB + 1)/cell->rbgSize) - 1);
1127 /*type2end will be the first RBG in pool with all available RBs*/
1128 pool->type2End = RGSCH_CEIL(pool->poolstartRB, cell->rbgSize);
1129 pool->type2Start = pool->poolstartRB;
1130 pool->bw = pool->poolendRB - pool->poolstartRB + 1;
1135 * @brief This function resets SFR Pool information for frame
1139 * Function: rgSCHSFRUtlTotalPooReset
1140 * Purpose: Update the dynamic variables in each pool as they will be modified in each subframe.
1141 * Dont modify the static variables like startRB, endRB, BW
1142 * Invoked by: rgSCHUtlSubFrmPut
1144 * @param[in] RgSchCellCb* cell
1145 * @param[in] RgSchDlSf* subFrm
1150 PRIVATE Void rgSCHSFRUtlTotalPoolReset
1156 PRIVATE Void rgSCHSFRUtlTotalPoolReset(cell, subFrm)
1161 RgSchSFRTotalPoolInfo *totalPoolInfo = &subFrm->sfrTotalPoolInfo;
1162 CmLListCp *ccPool = &totalPoolInfo->ccPool;
1163 CmLListCp *cePool = &totalPoolInfo->cePool;
1164 CmLList *node = NULLP;
1165 RgSchSFRPoolInfo *tempPool = NULLP;
1167 TRC2(rgSCHSFRUtlTotalPoolReset);
1169 totalPoolInfo->ccBwFull = FALSE;
1170 totalPoolInfo->ceBwFull = FALSE;
1171 totalPoolInfo->isUeCellEdge = FALSE;
1172 totalPoolInfo->CCPool1BwAvlbl = 0;
1173 totalPoolInfo->CCPool2BwAvlbl = 0;
1174 totalPoolInfo->CEPoolBwAvlbl = 0;
1175 totalPoolInfo->CCRetx = FALSE;
1176 totalPoolInfo->CERetx = FALSE;
1178 node = ccPool->first;
1181 tempPool = (RgSchSFRPoolInfo *)(node->node);
1183 rgSchSFRResetPoolVariables(cell, tempPool);
1184 if(tempPool->poolstartRB == 0)
1185 totalPoolInfo->CCPool1BwAvlbl = tempPool->bw;
1187 totalPoolInfo->CCPool2BwAvlbl = tempPool->bw;
1190 node = cePool->first;
1193 tempPool = (RgSchSFRPoolInfo *)(node->node);
1195 rgSchSFRResetPoolVariables(cell, tempPool);
1196 totalPoolInfo->CEPoolBwAvlbl = tempPool->bw;
1201 /* LTE_ADV_FLAG_REMOVED_END */
1203 * @brief This function appends PHICH information for frame
1207 * Function: rgSCHUtlAddPhich
1208 * Purpose: This function appends PHICH information for
1213 * @param[in] RgSchCellCb* cell
1214 * @param[in] RgSubFrm* subFrm
1215 * @param[in] U8 hqFeedBack
1216 * @param[in] U8 nDmrs
1217 * @param[in] U8 rbStart
1224 PUBLIC S16 rgSCHUtlAddPhich
1227 CmLteTimingInfo frm,
1234 PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, iPhich)
1236 CmLteTimingInfo frm;
1244 PUBLIC S16 rgSCHUtlAddPhich
1247 CmLteTimingInfo frm,
1254 PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, isForMsg3)
1256 CmLteTimingInfo frm;
1267 Inst inst = cell->instIdx;
1268 TRC2(rgSCHUtlAddPhich);
1270 dlSf = rgSCHUtlSubFrmGet(cell, frm);
1271 RGSCH_PHICH_ALLOC(inst, phich,sizeof(RgSchPhich), ret);
1275 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, " rgSCHUtlAddPhich(): "
1276 "Allocation of RgSchPhich failed");
1280 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, iPhich);
1282 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, isForMsg3); /*SR_RACH_STATS */
1284 cmLListAdd2Tail(&dlSf->phichInfo.phichs, &phich->lnk);
1286 } /* rgSCHUtlAddPhich */
1289 * @brief This function resets PHICH information for frame
1293 * Function: rgSCHUtlPhichReset
1294 * Purpose: This function initializes PHICH information for
1295 * a subframe. It removes the list of PHICHs allocated
1296 * in the prior use of this subframe structure.
1298 * Invoked by: rgSCHUtlSubFrmPut
1300 * @param[in] RgSchCellCb* cell
1301 * @param[in] RgSubFrm* subFrm
1306 PRIVATE Void rgSCHUtlPhichReset
1312 PRIVATE Void rgSCHUtlPhichReset(cell, subFrm)
1317 RgSchPhichInfo *phichInfo;
1322 TRC2(rgSCHUtlPhichReset);
1324 phichInfo = &subFrm->phichInfo;
1325 while(phichInfo->phichs.first != NULLP)
1327 phich = (RgSchPhich *)phichInfo->phichs.first->node;
1328 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
1329 RGSCH_PHICH_FREE(cell->instIdx, phich, sizeof(RgSchPhich));
1331 cmLListInit(&phichInfo->phichs);
1333 } /* rgSCHUtlPhichReset */
1337 * @brief This function returns subframe data structure for a cell
1341 * Function: rgSCHUtlSubFrmGet
1342 * Purpose: This function resets the subframe data structure
1343 * when the subframe is released
1345 * Invoked by: scheduler
1347 * @param[in] RgSubFrm subFrm
1352 PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet
1358 PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet(cell, frm)
1360 CmLteTimingInfo frm;
1366 TRC2(rgSCHUtlSubFrmGet);
1369 dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
1370 //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1371 sf = cell->subFrms[dlIdx];
1373 /* Changing the idexing
1374 so that proper subframe is selected */
1375 dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.subframe % RGSCH_NUM_SUB_FRAMES));
1376 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1377 sf = cell->subFrms[dlIdx];
1387 * @brief This function returns subframe data structure for a cell
1391 * Function: rgSCHUtlSubFrmPut
1392 * Purpose: This function resets the subframe data structure
1393 * when the subframe is released
1395 * Invoked by: scheduler
1397 * @param[in] RgSubFrm subFrm
1402 PUBLIC Void rgSCHUtlSubFrmPut
1408 PUBLIC Void rgSCHUtlSubFrmPut(cell, sf)
1416 TRC2(rgSCHUtlSubFrmPut);
1419 /* Release all the held PDCCH information */
1420 rgSCHUtlPdcchInit(cell, sf, sf->nCce);
1422 /* Release all the held PDCCH information */
1423 rgSCHUtlPdcchInit(cell, sf, cell->nCce);
1425 rgSCHUtlPhichReset(cell, sf);
1427 /* Reset the bw allocated. */
1430 /* Setting allocated bandwidth to SPS bandwidth for non-SPS RB allocator */
1431 sf->bwAlloced = ((cell->spsCellCfg.maxSpsDlBw +
1432 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
1433 if (sf->bwAlloced > sf->bw)
1435 sf->bwAlloced = sf->bw;
1437 sf->spsAllocdBw = 0;
1438 sf->type2Start = sf->bwAlloced;
1439 cmMemset((U8*) &sf->dlSfAllocInfo, 0, sizeof(RgSchDlSfAllocInfo));
1442 /* Fix for ccpu00123918*/
1444 /* LTE_ADV_FLAG_REMOVED_START */
1445 /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
1446 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
1448 cmMemset((U8*) sf->rntpInfo.val, 0, len);
1450 /* LTE_ADV_FLAG_REMOVED_END */
1453 /*[ccpu00138609]-ADD-Reset the CCCH UE counter */
1456 /* Non DLFS scheduling using Type0 RA requires the following
1457 * parameter's tracking */
1458 /* Type 2 localized allocations start from 0th RBG and onwards */
1459 /* Type 0 allocations start from last RBG and backwards*/
1463 sf->type2End = RGSCH_CEIL(sf->bwAlloced,cell->rbgSize);
1465 sf->type0End = cell->noOfRbgs - 1;
1466 /* If last RBG is of incomplete size then special handling */
1467 (sf->bw % cell->rbgSize == 0)? (sf->lstRbgDfct = 0) :
1468 (sf->lstRbgDfct = cell->rbgSize - (sf->bw % cell->rbgSize));
1469 /* This resets the allocation for BCCH and PDCCH */
1471 /* TODO we need to move this reset for emtc functions */
1472 if(!(cell->emtcEnable))
1481 sf->bcch.pdcch = NULLP;
1482 sf->pcch.pdcch = NULLP;
1484 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
1486 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
1488 for (i = 0; i < noRaRsps; i++)
1490 sf->raRsp[i].pdcch = NULLP;
1491 cmLListInit(&(sf->raRsp[i].raRspLst));
1493 /* LTE_ADV_FLAG_REMOVED_START */
1494 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
1496 rgSCHSFRUtlTotalPoolReset(cell, sf);
1498 /* LTE_ADV_FLAG_REMOVED_END */
1500 cmLListInit(&sf->n1PucchResLst);
1504 sf->isCceFailure = FALSE;
1505 sf->dlUlBothCmplt = 0;
1511 * @brief This function computes log N (32 bit Unsigned) to the base 2
1515 * Function: rgSCHUtlLog32bitNbase2
1516 * Purpose: This function computes log N (32 bit Unsigned) to the base 2.
1517 * For n= 0,1 ret = 0.
1519 * Invoked by: Scheduler
1526 PUBLIC U8 rgSCHUtlLog32bitNbase2
1531 PUBLIC U8 rgSCHUtlLog32bitNbase2(n)
1535 U32 b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
1536 U32 s[] = {1, 2, 4, 8, 16};
1540 TRC2(rgSCHUtlLog32bitNbase2)
1542 for (i=4; i >= 0; i--)
1556 * @brief This function is a wrapper to call scheduler specific API.
1560 * Function: rgSCHUtlDlRelPdcchFbk
1561 * Purpose: Calls scheduler's handler for SPS release PDCCH feedback
1566 * @param[in] RgSchCellCb *cell
1567 * @param[in] RgSchUeCb *ue
1568 * @param[in] U8 isAck
1573 PUBLIC Void rgSCHUtlDlRelPdcchFbk
1580 PUBLIC Void rgSCHUtlDlRelPdcchFbk(cell, ue, isAck)
1586 TRC2(rgSCHUtlDlRelPdcchFbk);
1587 cell->sc.apis->rgSCHDlRelPdcchFbk(cell, ue, isAck);
1594 * @brief This function is a wrapper to call scheduler specific API.
1598 * Function: rgSCHUtlDlProcAck
1599 * Purpose: Calls scheduler's handler to process Ack
1604 * @param[in] RgSchCellCb *cell
1605 * @param[in] RgSchDlHqProcCb *hqP
1610 PUBLIC Void rgSCHUtlDlProcAck
1613 RgSchDlHqProcCb *hqP
1616 PUBLIC Void rgSCHUtlDlProcAck(cell, hqP)
1618 RgSchDlHqProcCb *hqP;
1621 TRC2(rgSCHUtlDlProcAck);
1622 cell->sc.apis->rgSCHDlProcAck(cell, hqP);
1627 * @brief CRNTI CE Handler
1631 * Function : rgSCHUtlHdlCrntiCE
1633 * - Call scheduler common API
1636 * @param[in] RgSchCellCb *cell
1637 * @param[in] RgSchUeCb *ue
1638 * @param[out] RgSchErrInfo *err
1642 PUBLIC Void rgSCHUtlHdlCrntiCE
1648 PUBLIC Void rgSCHUtlHdlCrntiCE(cell, ue)
1653 TRC2(rgSCHUtlHdlCrntiCE);
1655 cell->sc.apis->rgSCHHdlCrntiCE(cell, ue);
1657 } /* rgSCHUtlHdlCrntiCE */
1658 #endif /* LTEMAC_SPS */
1660 /***********************************************************
1662 * Func : rgSCHUtlCalcTotalRegs
1664 * Desc : Calculate total REGs, given a bandwidth, CFI
1665 * and number of antennas.
1667 * Ret : Total REGs (U16)
1669 * Notes: Could optimise if bw values are limited
1670 * (taken from RRC spec) by indexing values from
1672 * Input values are not validated. CFI is assumed
1677 **********************************************************/
1679 PRIVATE U16 rgSCHUtlCalcTotalRegs
1687 PRIVATE U16 rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp)
1695 TRC2(rgSCHUtlCalcTotalRegs);
1697 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1703 /* Refer 36.211 section 6.10.1.2
1704 * For symbols 2 and 4, the REGs per RB will be based on cyclic prefix
1705 * and number of antenna ports.
1706 * For symbol 1, there are 2 REGs per RB always. Similarly symbol 3
1710 /*CR changes [ccpu00124416] - MOD*/
1713 regs = bw * RGSCH_NUM_REGS_4TH_SYM_EXT_CP;
1717 regs = bw * RGSCH_NUM_REGS_4TH_SYM_NOR_CP;
1720 regs += bw * RGSCH_NUM_REGS_3RD_SYM;
1722 /*CR changes [ccpu00124416] - MOD using number of antenna ports*/
1723 regs += (numAntna == RGSCH_NUM_ANT_PORT_FOUR) ? \
1724 (bw * RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT) : \
1725 (bw * RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT);
1726 default: /* case 1 */
1727 regs += bw * RGSCH_NUM_REGS_1ST_SYM;
1732 /***********************************************************
1734 * Func : rgSCHUtlCalcPhichRegs
1736 * Desc : Calculates number of PHICH REGs
1738 * Ret : Number of PHICH REGs (U8)
1740 * Notes: ng6 is Ng multiplied by 6
1744 **********************************************************/
1746 PRIVATE U16 rgSCHUtlCalcPhichRegs
1752 PRIVATE U16 rgSCHUtlCalcPhichRegs(bw, ng6)
1757 TRC2(rgSCHUtlCalcPhichRegs);
1758 /* ccpu00115330: Corrected the calculation for number of PHICH groups*/
1759 RETVALUE(RGSCH_CEIL((bw * ng6) ,(8 * 6)) * RGSCH_NUM_REG_PER_PHICH_GRP);
1764 * @brief Calculates total CCEs (N_cce)
1768 * Function: rgSCHUtlCalcNCce
1769 * Purpose: This function calculates and returns total CCEs for a
1770 * cell, given the following: bandwidth, Ng configuration
1771 * (multiplied by six), cfi (actual number of control
1772 * symbols), m factor for PHICH and number of antennas.
1774 * Invoked by: Scheduler
1779 * @param[in] U8 mPhich
1780 * @param[in] U8 numAntna
1781 * @param[in] Bool isEcp
1782 * @return N_cce (U8)
1786 PUBLIC U8 rgSCHUtlCalcNCce
1796 PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, mPhich, numAntna, isEcp)
1809 TRC2(rgSCHUtlCalcNCce);
1811 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1815 case RGR_NG_ONESIXTH:
1830 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1831 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1832 cceRegs = totalRegs - mPhich*phichRegs - RGSCH_NUM_PCFICH_REG;
1834 RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1839 * @brief Calculates total CCEs (N_cce)
1843 * Function: rgSCHUtlCalcNCce
1844 * Purpose: This function calculates and returns total CCEs for a
1845 * cell, given the following: bandwidth, Ng configuration
1846 * (multiplied by six), cfi (actual number of control
1847 * symbols) and number of antennas.
1849 * Invoked by: Scheduler
1854 * @param[in] U8 numAntna
1855 * @return N_cce (U8)
1859 PUBLIC U8 rgSCHUtlCalcNCce
1868 PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, numAntna, isEcp)
1880 TRC2(rgSCHUtlCalcNCce);
1882 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1886 case RGR_NG_ONESIXTH:
1901 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1902 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1903 cceRegs = totalRegs - phichRegs - RGSCH_NUM_PCFICH_REG;
1905 RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1910 * @brief Returns PHICH info associated with an uplink
1911 * HARQ process allocation
1915 * Function: rgSCHUtlGetPhichInfo
1916 * Purpose: This function returns PHICH info associated with
1917 * an uplink HARQ process allocation. PHICH info
1918 * comprises RB start and N_dmrs.
1920 * @param[in] RgSchUlHqProcCb *hqProc
1921 * @param[out] U8 *rbStartRef
1922 * @param[out] U8 *nDmrsRef
1927 PUBLIC S16 rgSCHUtlGetPhichInfo
1929 RgSchUlHqProcCb *hqProc,
1935 PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef, iPhich)
1936 RgSchUlHqProcCb *hqProc;
1943 PUBLIC S16 rgSCHUtlGetPhichInfo
1945 RgSchUlHqProcCb *hqProc,
1950 PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef)
1951 RgSchUlHqProcCb *hqProc;
1960 TRC2(rgSCHUtlGetPhichInfo);
1962 if ((hqProc != NULLP) && (hqProc->alloc != NULLP))
1964 *rbStartRef = hqProc->alloc->grnt.rbStart;
1965 *nDmrsRef = hqProc->alloc->grnt.nDmrs;
1967 *iPhich = hqProc->iPhich;
1975 * @brief Returns uplink grant information required to permit
1976 * PHY to receive data
1980 * Function: rgSCHUtlAllocRcptInfo
1981 * Purpose: Given an uplink allocation, this function returns
1982 * uplink grant information which is needed by PHY to
1983 * decode data sent from UE. This information includes:
1988 * @param[in] RgSchUlAlloc *alloc
1989 * @param[out] U8 *rbStartRef
1990 * @param[out] U8 *numRbRef
1991 * @param[out] U8 *rvRef
1992 * @param[out] U16 *size
1993 * @param[out] TfuModScheme *modType
1994 * @param[out] Bool *isRtx
1995 * @param[out] U8 *nDmrs
1996 * @param[out] Bool *ndi
1997 * @param[out] U8 *hqPId
2001 PUBLIC S16 rgSCHUtlAllocRcptInfo
2003 RgSchUlAlloc *alloc,
2010 TfuModScheme *modType,
2017 PUBLIC S16 rgSCHUtlAllocRcptInfo(alloc, rnti, iMcsRef, rbStartRef, numRbRef,
2018 rvRef, size, modType, isRtx, nDmrs, ndi,
2020 RgSchUlAlloc *alloc;
2027 TfuModScheme *modType;
2034 /* Modulation order for 16qam UEs would be
2035 * min(4,modulation order in grant). Please refer to 36.213-8.6.1*/
2036 CmLteUeCategory ueCtgy;
2038 TRC2(rgSCHUtlAllocRcptInfo);
2039 #if (ERRCLASS & ERRCLS_DEBUG)
2040 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2046 if ( !alloc->forMsg3 )
2048 if ( ((alloc->ue) == NULLP) || (RG_SCH_CMN_GET_UE(alloc->ue, alloc->ue->cell) == NULLP))
2050 RLOG_ARG2(L_ERROR,DBG_CELLID,alloc->ue->cell->cellId,
2051 "Failed: ue->sch is null RNTI:%d,isRetx=%d",
2052 alloc->rnti, alloc->grnt.isRtx);
2055 ueCtgy = (RG_SCH_CMN_GET_UE_CTGY(alloc->ue));
2058 *iMcsRef = alloc->grnt.iMcs;
2059 *rbStartRef = alloc->grnt.rbStart;
2060 *numRbRef = alloc->grnt.numRb;
2061 *rvRef = rgRvTable[alloc->hqProc->rvIdx];
2062 *rnti = alloc->rnti;
2063 *size = alloc->grnt.datSz;
2064 *modType = (alloc->forMsg3)? alloc->grnt.modOdr:
2065 ((ueCtgy == CM_LTE_UE_CAT_5)?
2067 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)));
2068 *isRtx = alloc->grnt.isRtx;
2069 *nDmrs = alloc->grnt.nDmrs;
2070 *ndi = alloc->hqProc->ndi;
2071 *hqPId = alloc->hqProc->procId;
2077 * @brief Returns uplink grant information required to permit
2078 * PHY to receive data
2082 * Function: rgSCHUtlAllocRcptInfo
2083 * Purpose: Given an uplink allocation, this function returns
2084 * uplink grant information which is needed by PHY to
2085 * decode data sent from UE. This information includes:
2090 * @param[in] RgSchUlAlloc *alloc
2091 * @param[out] U8 *rbStartRef
2092 * @param[out] U8 *numRbRef
2093 * @param[out] U8 *rvRef
2094 * @param[out] U16 *size
2095 * @param[out] TfuModScheme *modType
2099 PUBLIC S16 rgSCHUtlAllocRcptInfo
2102 RgSchUlAlloc *alloc,
2103 CmLteTimingInfo *timeInfo,
2104 TfuUeUlSchRecpInfo *recpReq
2107 PUBLIC S16 rgSCHUtlAllocRcptInfo(cell, alloc, timeInfo, recpReq)
2109 RgSchUlAlloc *alloc;
2110 CmLteTimingInfo *timeInfo;
2111 TfuUeUlSchRecpInfo *recpReq;
2114 TRC2(rgSCHUtlAllocRcptInfo);
2115 #if (ERRCLASS & ERRCLS_DEBUG)
2116 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2121 recpReq->size = alloc->grnt.datSz;
2122 recpReq->rbStart = alloc->grnt.rbStart;
2123 recpReq->numRb = alloc->grnt.numRb;
2124 /* Modulation order min(4,mod in grant) for 16 qam UEs.
2125 * Please refer to 36.213-8.6.1*/
2126 #ifdef FOUR_TX_ANTENNA
2127 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2128 (/*(alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2129 alloc->grnt.modOdr: *//* Chandra:TmpFx-TM500 Cat5 with Only16QAM */
2130 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2132 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2133 ((alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2135 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2137 recpReq->nDmrs = alloc->grnt.nDmrs;
2138 recpReq->hoppingEnbld = FALSE;
2139 recpReq->hoppingBits = 0;
2140 recpReq->isRtx = alloc->grnt.isRtx;
2141 recpReq->ndi = alloc->hqProc->ndi;
2142 recpReq->rv = rgRvTable[alloc->hqProc->rvIdx];
2144 recpReq->harqProcId = alloc->hqProc->procId;
2146 recpReq->harqProcId = rgSCHCmnGetUlHqProcIdx(timeInfo, cell);
2148 /* Transmission mode is SISO till Uplink MIMO is implemented. */
2149 recpReq->txMode = 0;
2150 /* This value needs to filled in in the case of frequency hopping. */
2151 recpReq->crntTxNb = 0;
2153 recpReq->mcs = alloc->grnt.iMcs;
2155 recpReq->rbgStart = alloc->grnt.vrbgStart;
2156 recpReq->numRbg = alloc->grnt.numVrbg;
2157 recpReq->xPUSCHRange = alloc->grnt.xPUSCHRange;
2158 //TODO_SID Need to check
2159 recpReq->nAntPortLayer = 0;
2160 recpReq->SCID = alloc->grnt.SCID;
2161 recpReq->PMI = alloc->grnt.PMI;
2162 recpReq->uciWoTBFlag = alloc->grnt.uciOnxPUSCH;
2165 recpReq->beamIndex = alloc->ue->ue5gtfCb.BeamId;
2170 if (!alloc->forMsg3)
2172 if (alloc->grnt.isRtx)
2174 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulRetxOccns++;
2178 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulTxOccns++;
2179 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulSumiTbs += \
2180 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2181 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulNumiTbs ++;
2182 cell->tenbStats->sch.ulSumiTbs += \
2183 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2184 cell->tenbStats->sch.ulNumiTbs ++;
2186 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulPrbUsg += alloc->grnt.numRb;
2187 cell->tenbStats->sch.ulPrbUsage[0] += alloc->grnt.numRb;
2190 /* ccpu00117050 - DEL - nSrs setting at rgSCHUtlAllocRcptInfo */
2197 * @brief This function initialises the PRACH subframe occasions
2201 * Function: rgSCHUtlUpdPrachOcc
2202 * Purpose: This function updates the PRACH subframes based on
2203 * RGR configuration.
2205 * Invoked by: Scheduler
2207 * @param[in] RgSchCellCb *cell
2208 * @param[in] RgrTddPrachInfo *cellCfg
2213 PRIVATE Void rgSCHUtlUpdPrachOcc
2216 RgrTddPrachInfo *cellCfg
2219 PRIVATE Void rgSCHUtlUpdPrachOcc(cell, cellCfg)
2221 RgrTddPrachInfo *cellCfg;
2230 TRC2(rgSCHUtlUpdPrachOcc)
2232 /* In the 1st half frame */
2233 if(cellCfg->halfFrm == 0)
2238 /* In the 2nd half frame */
2244 for(idx = startIdx; idx < endIdx; idx++)
2246 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
2247 == RG_SCH_TDD_UL_SUBFRAME)
2249 if(cellCfg->ulStartSfIdx == count)
2251 size = cell->rachCfg.raOccasion.size;
2252 cell->rachCfg.raOccasion.subFrameNum[size] = idx;
2253 cell->rachCfg.raOccasion.size++;
2263 * @brief This function initialises the PRACH occasions
2267 * Function: rgSCHUtlPrachCfgInit
2268 * Purpose: This function initialises the PRACH occasions based on
2269 * RGR configuration.
2271 * Invoked by: Scheduler
2273 * @param[in] RgSchCellCb *cell
2274 * @param[in] RgrCellCfg *cellCfg
2279 PUBLIC Void rgSCHUtlPrachCfgInit
2285 PUBLIC Void rgSCHUtlPrachCfgInit(cell, cellCfg)
2287 RgrCellCfg *cellCfg;
2294 TRC2(rgSCHUtlPrachCfgInit)
2295 if(cellCfg->prachRscInfo.numRsc <= 0)
2297 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid"
2298 "PRACH resources Configuration ");
2302 /* Update SFN occasions */
2303 cell->rachCfg.raOccasion.sfnEnum =
2304 cellCfg->prachRscInfo.prachInfo[0].sfn;
2306 cell->rachCfg.raOccasion.size = 0;
2308 /* Update subframe occasions */
2309 for(idx = 0; idx < cellCfg->prachRscInfo.numRsc; idx++)
2311 if(cellCfg->prachRscInfo.prachInfo[idx].freqIdx == 0)
2313 if(cellCfg->prachRscInfo.prachInfo[idx].halfFrm == 0)
2321 if(cellCfg->prachRscInfo.prachInfo[idx].ulStartSfIdx ==
2324 subfrmIdx = cell->rachCfg.raOccasion.size;
2325 cell->rachCfg.raOccasion.subFrameNum[subfrmIdx] = splFrm;
2326 cell->rachCfg.raOccasion.size++;
2330 rgSCHUtlUpdPrachOcc(cell,
2331 &cellCfg->prachRscInfo.prachInfo[idx]);
2339 * @brief This function performs RGR cell initialization
2343 * Function: rgSCHUtlRgrCellCfg
2344 * Purpose: This function initialises the cell with RGR configuration
2345 * and subframe related initialization.
2347 * Invoked by: Scheduler
2349 * @param[in] RgSchCellCb *cell
2350 * @param[in] RgrCellCfg *cellCfg
2351 * @param[in] RgSchErrInfo *errInfo
2356 PUBLIC S16 rgSCHUtlRgrCellCfg
2359 RgrCellCfg *cellCfg,
2360 RgSchErrInfo *errInfo
2363 PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2365 RgrCellCfg *cellCfg;
2366 RgSchErrInfo *errInfo;
2373 CmLteTimingInfo frm;
2374 U8 ulDlCfgIdx = cellCfg->ulDlCfgIdx;
2378 U16 bw; /*!< Number of RBs in the cell */
2380 TRC2(rgSCHUtlRgrCellCfg);
2382 cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo));
2384 /* ccpu00132657-MOD- Determining DLSF array size independent of DELTAS */
2385 maxDlSubframes = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
2386 maxSubframes = 2 * maxDlSubframes;
2387 cell->numDlSubfrms = maxSubframes;
2388 /* ACC-TDD <ccpu00130639> */
2389 cell->tddHqSfnCycle = -1;
2390 cell->ulDlCfgIdx = ulDlCfgIdx;
2392 /* PRACH Occasions Initialization */
2393 rgSCHUtlPrachCfgInit(cell, cellCfg);
2395 /* ccpu00132658- Moved out of below for loop since the updating rbgSize and
2396 * bw are independent of sfNum*/
2397 /* determine the RBG size and no of RBGs for the configured
2399 if (cell->bwCfg.dlTotalBw > 63)
2403 else if (cell->bwCfg.dlTotalBw > 26)
2407 else if (cell->bwCfg.dlTotalBw > 10)
2415 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2417 bw = cell->bwCfg.dlTotalBw;
2419 rgSCHUtlAllocSBuf(cell->instIdx,
2420 (Data **)&cell->subFrms, sizeof(RgSchDlSf *) * maxSubframes);
2421 if (cell->subFrms == NULLP)
2426 /* Create memory for each frame. */
2427 for(i = 0; i < maxSubframes; i++)
2429 while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
2430 RG_SCH_TDD_UL_SUBFRAME)
2432 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2435 rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf, sizeof(RgSchDlSf));
2440 cmMemset((U8 *)sf, 0, sizeof(*sf));
2443 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2451 /* Mark SPS bandwidth to be occupied */
2452 sf->bwAlloced = ((cellCfg->spsCfg.maxSpsDlBw +
2453 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
2454 sf->spsAllocdBw = 0;
2455 sf->type2End = sf->bwAlloced/cell->rbgSize;
2458 /* Fix for ccpu00123918*/
2460 #endif /* LTEMAC_SPS */
2461 /* Initialize the ackNakRepQ here */
2462 #ifdef RG_MAC_MEASGAP
2463 cmLListInit (&(sf->ackNakRepQ));
2465 cell->subFrms[i] = sf;
2466 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2468 if (i != maxSubframes)
2472 /* ccpu00117052 - MOD - Passing double pointer
2473 for proper NULLP assignment*/
2474 rgSCHUtlFreeSBuf(cell->instIdx,
2475 (Data **)(&(cell->subFrms[i-1])), sizeof(RgSchDlSf));
2477 rgSCHLaaDeInitDlSfCb(cell, sf);
2480 /* ccpu00117052 - MOD - Passing double pointer
2481 for proper NULLP assignment*/
2482 rgSCHUtlFreeSBuf(cell->instIdx,
2483 (Data **)(&(cell->subFrms)), sizeof(RgSchDlSf *) * maxSubframes);
2488 if (cell->sc.apis == NULLP)
2490 cell->sc.apis = &rgSchCmnApis;
2492 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2496 /* ccpu00132286- Removed deletion of sf nodes as the deletion will be
2497 * happening during CellDelete. Added return handling to provide negative
2502 /* Release the subframes and thereby perform the initialization */
2503 for (i = 0; i < maxSubframes; i++)
2505 if((i > 0) && (i%maxDlSubframes == 0))
2510 frm.subframe = cell->subFrms[i]->sfNum;
2511 rgSCHUtlDlRlsSubFrm(cell, frm);
2520 * @brief This function performs scheduler related cell creation
2524 * Function: rgSCHUtlRgrCellCfg
2525 * Purpose: This function creates the subframes needed for the
2526 * cell. It then peforms init of the scheduler by calling
2527 * scheduler specific cell init function.
2529 * Invoked by: Scheduler
2531 * @param[in] RgSchCellCb *cell
2532 * @param[in] RgrCellCfg *cellCfg
2533 * @param[in] RgSchErrInfo *errInfo
2538 PUBLIC S16 rgSCHUtlRgrCellCfg
2541 RgrCellCfg *cellCfg,
2542 RgSchErrInfo *errInfo
2545 PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2547 RgrCellCfg *cellCfg;
2548 RgSchErrInfo *errInfo;
2553 CmLteTimingInfo frm;
2555 Inst inst = cell->instIdx;
2556 /* LTE_ADV_FLAG_REMOVED_START */
2558 len = (U16)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /*KW fix for LTE_ADV */
2559 /* LTE_ADV_FLAG_REMOVED_END */
2560 TRC2(rgSCHUtlRgrCellCfg);
2562 cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo));
2564 /* determine the RBG size and no of RBGs for the configured
2566 if (cell->bwCfg.dlTotalBw > 63)
2570 else if (cell->bwCfg.dlTotalBw > 26)
2574 else if (cell->bwCfg.dlTotalBw > 10)
2582 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2583 /* Create memory for each frame. */
2584 /* Changing loop limit from
2585 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_SUBFRAMES */
2586 for(i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++)
2588 rgSCHUtlAllocSBuf(inst, (Data **)&sf, sizeof(RgSchDlSf));
2593 cmMemset((U8 *)sf, 0, sizeof(*sf));
2596 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2601 /* Doing MOD operation before assigning value of i */
2602 sf->sfNum = i % RGSCH_NUM_SUB_FRAMES;
2603 sf->bw = cell->bwCfg.dlTotalBw;
2604 /* Initialize the ackNakRepQ here */
2605 #ifdef RG_MAC_MEASGAP
2606 cmLListInit (&(sf->ackNakRepQ));
2608 cell->subFrms[i] = sf;
2609 /* LTE_ADV_FLAG_REMOVED_START */
2610 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2612 /*initialize the RNTP Buffer*/
2613 if(rgSchDSFRRntpInfoInit(&sf->rntpInfo, cell, sf->bw))
2619 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
2621 /*initialise the pools of CC and CE*/
2622 if(rgSchSFRTotalPoolInit(cell, sf))
2627 /* LTE_ADV_FLAG_REMOVED_END */
2630 /* LTE_ADV_FLAG_REMOVED_START */
2631 /* Allocate memory for "scheduled UE" Info */
2632 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2634 if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val),
2635 (len * sizeof(U8)))) != ROK)
2637 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
2640 cell->rntpAggrInfo.pres = PRSNT_NODEF;
2641 cell->rntpAggrInfo.len = len;
2643 /* LTE_ADV_FLAG_REMOVED_END */
2645 /* Changing loop limit from
2646 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_SUBFRAMES */
2647 if (i != RGSCH_NUM_DL_SUBFRAMES)
2651 /* ccpu00117052 - MOD - Passing double pointer
2652 for proper NULLP assignment*/
2653 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i-1])),
2656 rgSCHLaaDeInitDlSfCb(cell, sf);
2662 if (cell->sc.apis == NULLP)
2664 cell->sc.apis = &rgSchCmnApis;
2667 /* Release the subframes and thereby perform the initialization */
2668 for (i = 0; i < RGSCH_NUM_DL_SUBFRAMES; i++)
2670 if (i >= RGSCH_NUM_SUB_FRAMES)
2672 /* [ccpu00123828]-MOD-The below statement sfn += 1incorrectly modified
2673 * the value of sfn for i>=10 thru 19. Correct way is to assign
2677 frm.subframe = i % RGSCH_NUM_SUB_FRAMES;
2678 rgSCHUtlDlRlsSubFrm(cell, frm);
2681 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2684 errInfo->errCause = RGSCHERR_SCH_CFG;
2688 if(cell->emtcEnable)
2690 /* TODO: Repetition framework in RGR and APP */
2691 if (rgSCHUtlEmtcResMngmtInit(
2693 RGSCH_IOT_PDSCH_POOLSZ, RGSCH_IOT_PDSCH_DELTA, cellCfg->bwCfg.dlTotalBw,
2694 RGSCH_IOT_PUSCH_POOLSZ, RGSCH_IOT_PUSCH_DELTA, RGSCH_IOT_PUSCH_MAXFREQSZ,
2695 RGSCH_IOT_PUCCH_POOLSZ, RGSCH_IOT_PUCCH_DELTA, RGSCH_IOT_PUCCH_MAXFREQSZ) != ROK)
2697 errInfo->errCause = RGSCHERR_SCH_CFG;
2709 * @brief This function performs the cell reconfiguration at RGR interface
2713 * Function: rgSCHUtlRgrCellRecfg
2714 * Purpose: This function updates the reconfigurable parameters
2715 * on the cell control block for the scheduler.
2717 * Invoked by: Scheduler
2719 * @param[in] RgSchCellCb *cell
2720 * @param[in] RgrCellCfg *cellCfg
2721 * @param[in] RgSchErrInfo *errInfo
2726 PUBLIC S16 rgSCHUtlRgrCellRecfg
2729 RgrCellRecfg *recfg,
2733 PUBLIC S16 rgSCHUtlRgrCellRecfg(cell, recfg, err)
2735 RgrCellRecfg *recfg;
2739 TRC2(rgSCHUtlRgrCellRecfg);
2740 RETVALUE(cell->sc.apis->rgSCHRgrCellRecfg(cell, recfg, err));
2746 * @brief This function returns the Y value of UE for a sub frame
2750 * Function: rgSCHUtlFreeCell
2751 * Purpose: This function updates the value of Y stored in the
2752 * UE control block. It uses the previously computed
2753 * value for computing for this subframe.
2755 * Invoked by: Scheduler
2757 * @param[in] RgSchCellCb *cell
2762 PUBLIC S16 rgSCHUtlFreeCell
2767 PUBLIC S16 rgSCHUtlFreeCell(cell)
2774 RgSchPdcchInfo *pdcchInfo;
2775 RgSchPhichInfo *phichInfo;
2777 Inst inst = cell->instIdx;
2780 RgSchRaReqInfo *raReqInfo;
2783 TRC2(rgSCHUtlFreeCell);
2786 maxSubframes = cell->numDlSubfrms;
2788 maxSubframes = RGSCH_NUM_DL_SUBFRAMES;
2792 /* Invoke the index for scheduler, cell deletion */
2793 cell->sc.apis->rgSCHFreeCell(cell);
2795 /* Release the subframes allocated */
2796 for (i = 0; i < maxSubframes; i++)
2799 rgSCHLaaDeInitDlSfCb(cell, cell->subFrms[i]);
2801 pdcchInfo = &cell->subFrms[i]->pdcchInfo;
2802 /* ccpu00117052 - MOD - Passing double pointer
2803 for proper NULLP assignment*/
2804 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)),
2805 (pdcchInfo->nCce + 7) >> 3);
2806 while (pdcchInfo->pdcchs.first != NULLP)
2808 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
2809 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
2810 /* ccpu00117052 - MOD - Passing double pointer
2811 for proper NULLP assignment*/
2812 rgSCHUtlFreeSBuf(inst, (Data **)&pdcch, sizeof(RgSchPdcch));
2815 phichInfo = &cell->subFrms[i]->phichInfo;
2816 while(phichInfo->phichs.first != NULLP)
2818 phich = (RgSchPhich *)phichInfo->phichs.first->node;
2819 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
2820 RGSCH_PHICH_FREE(inst, phich, sizeof(RgSchPhich));
2823 /* LTE_ADV_FLAG_REMOVED_START */
2824 /*releasing SFR pool entries*/
2825 rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell);
2827 /*releasing dsfr rntp pattern info*/
2828 rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell,
2829 cell->bwCfg.dlTotalBw);
2830 /* LTE_ADV_FLAG_REMOVED_END */
2832 /* ccpu00117052 - MOD - Passing double pointer
2833 for proper NULLP assignment*/
2834 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i])), sizeof(RgSchDlSf));
2837 /* Release the subframe pointers */
2838 /* ccpu00117052 - MOD - Passing double pointer
2839 for proper NULLP assignment*/
2840 rgSCHUtlFreeSBuf(inst,
2841 (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxSubframes);
2843 for(idx=0; idx < cell->raInfo.lstSize; idx++)
2845 lst = &cell->raInfo.raReqLst[idx];
2846 while (lst->first != NULLP)
2848 raReqInfo = (RgSchRaReqInfo *)lst->first->node;
2849 cmLListDelFrm(lst, &raReqInfo->raReqLstEnt);
2850 /* ccpu00117052 - MOD - Passing double pointer
2851 for proper NULLP assignment*/
2852 rgSCHUtlFreeSBuf(inst,(Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
2855 /* ccpu00117052 - MOD - Passing double pointer
2856 for proper NULLP assignment*/
2857 rgSCHUtlFreeSBuf(inst,
2858 (Data **)(&(cell->raInfo.raReqLst)),
2859 sizeof(CmLListCp) * (cell->raInfo.lstSize));
2862 /* Release allocated pdcchs */
2863 lst = &cell->pdcchLst;
2864 while (lst->first != NULLP)
2866 pdcch = (RgSchPdcch *)lst->first->node;
2867 cmLListDelFrm(lst, &pdcch->lnk);
2869 if(cell->emtcEnable)
2871 rgSCHEmtcPdcchFree(cell, pdcch);
2872 rgSCHUtlEmtcResMngmtDeinit(cell);
2875 /* ccpu00117052 - MOD - Passing double pointer
2876 for proper NULLP assignment*/
2877 rgSCHUtlFreeSBuf(inst,(Data **)&pdcch, sizeof(RgSchPdcch));
2880 rgSCHLaaFreeLists(cell);
2883 /* LTE_ADV_FLAG_REMOVED_START */
2884 /* releasing RNTP Aggregation Info from CellCb*/
2885 rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw);
2886 /* LTE_ADV_FLAG_REMOVED_END */
2893 * @brief This function adds the UE to scheduler
2897 * Function: rgSCHUtlRgrUeCfg
2898 * Purpose: This function performs addition of UE to scheduler
2899 * 1. First, it updates the Y table in the UE
2900 * 2. Then, it calls the scheduler's handler for UE addition
2902 * Invoked by: Scheduler
2904 * @param[in] RgSchCellCb *cell
2905 * @param[in] RgSchUeCb *ue
2906 * @param[in] RgrUeCfg *cfg
2907 * @param[in] RgSchErrInfo *err
2912 PUBLIC S16 rgSCHUtlRgrUeCfg
2920 PUBLIC S16 rgSCHUtlRgrUeCfg(cell, ue, cfg, err)
2927 TRC2(rgSCHUtlRgrUeCfg);
2929 /* Assign TM 1 as UE's default TM */
2930 ue->mimoInfo.txMode = RGR_UE_TM_1;
2931 ue->txModeTransCmplt = TRUE;
2932 cmInitTimers(&ue->txModeTransTmr, 1);
2933 if (cfg->txMode.pres == PRSNT_NODEF)
2935 /* DL MU-MIMO not supported */
2936 if (cfg->txMode.txModeEnum == RGR_UE_TM_5)
2938 err->errCause = RGSCHERR_SCH_CFG;
2941 ue->mimoInfo.txMode = cfg->txMode.txModeEnum;
2943 ue->ul.ulTxAntSel = cfg->ulTxAntSel;
2944 ue->mimoInfo.cdbkSbstRstrctn = cfg->ueCodeBookRstCfg;
2946 ue->ueCatEnum = cfg->ueCatEnum;
2947 if ((cfg->puschDedCfg.bACKIdx > 15) ||
2948 (cfg->puschDedCfg.bCQIIdx > 15) ||
2949 (cfg->puschDedCfg.bRIIdx > 15))
2951 err->errCause = RGSCHERR_SCH_CFG;
2954 ue->ul.betaHqOffst = cfg->puschDedCfg.bACKIdx;
2955 ue->ul.betaCqiOffst = cfg->puschDedCfg.bCQIIdx;
2956 ue->ul.betaRiOffst = cfg->puschDedCfg.bRIIdx;
2958 ue->csgMmbrSta = cfg->csgMmbrSta;
2960 cmMemset((U8 *)&ue->pfsStats, 0, sizeof(RgSchPfsStats));
2962 /* Call the handler of the scheduler based on cell configuration */
2963 RETVALUE(cell->sc.apis->rgSCHRgrUeCfg(cell, ue, cfg, err));
2965 /* Start : LTEMAC_2.1_DEV_CFG */
2968 * @brief This function adds a service to scheduler
2972 * Function: rgSCHUtlRgrLcCfg
2973 * Purpose: This function performs addition of service to scheduler
2974 * The addition is performed for each direction based
2975 * the direction field of the configuration
2977 * Invoked by: Scheduler
2979 * @param[in] RgSchCellCb *cell
2980 * @param[in] RgSchUeCb *ue
2981 * @param[in] RgSchDlLcCb *dlLc
2982 * @param[in] RgrLchCfg *cfg
2983 * @param[in] RgSchErrInfo *err
2988 PUBLIC S16 rgSCHUtlRgrLcCfg
2994 RgSchErrInfo *errInfo
2997 PUBLIC S16 rgSCHUtlRgrLcCfg(cell, ue, dlLc, cfg, errInfo)
3002 RgSchErrInfo *errInfo;
3005 TRC2(rgSCHUtlRgrLcCfg);
3006 RETVALUE(cell->sc.apis->rgSCHRgrLchCfg(cell, ue, dlLc, cfg, errInfo));
3011 * @brief This function modifies a service to scheduler
3015 * Function: rgSCHUtlRgrLcRecfg
3016 * Purpose: This function performs modification of a service in
3017 * scheduler. The modification is performed for each direction
3018 * based the direction field of the configuration
3020 * Invoked by: Scheduler
3022 * @param[in] RgSchCellCb *cell
3023 * @param[in] RgSchUeCb *ue
3024 * @param[in] RgSchDlLcCb *dlLc
3025 * @param[in] RgrLchRecfg *recfg
3026 * @param[in] RgSchErrInfo *err
3031 PUBLIC S16 rgSCHUtlRgrLcRecfg
3040 PUBLIC S16 rgSCHUtlRgrLcRecfg(cell, ue, dlLc, recfg, err)
3048 TRC2(rgSCHUtlRgrLcRecfg);
3049 RETVALUE(cell->sc.apis->rgSCHRgrLchRecfg(cell, ue, dlLc, recfg, err));
3053 * @brief This function deletes a Lc in scheduler
3057 * Function: rgSCHUtlRgrLcDel
3058 * Purpose: This function performs deletion of Lc in scheduler
3060 * Invoked by: Scheduler
3062 * @param[in] RgSchCellCb *cell
3063 * @param[in] RgSchUeCb *ue
3064 * @param[in] CmLteLcId lcId
3065 * @param[in] U8 lcgId
3070 PUBLIC S16 rgSCHUtlRgrLcDel
3078 PUBLIC S16 rgSCHUtlRgrLcDel(cell, ue, lcId, lcgId)
3085 TRC2(rgSCHUtlRgrLcDel);
3086 cell->sc.apis->rgSCHRgrLchDel(cell, ue, lcId, lcgId);
3089 } /* rgSCHUtlRgrLcDel */
3092 * @brief This function adds a service to scheduler
3096 * Function: rgSCHUtlRgrLcgCfg
3097 * Purpose: This function performs addition of service to scheduler
3098 * The addition is performed for each direction based
3099 * the direction field of the configuration
3101 * Invoked by: Scheduler
3103 * @param[in] RgSchCellCb *cell
3104 * @param[in] RgSchUeCb *ue
3105 * @param[in] RgrLchCfg *cfg
3106 * @param[in] RgSchErrInfo *err
3111 PUBLIC S16 rgSCHUtlRgrLcgCfg
3116 RgSchErrInfo *errInfo
3119 PUBLIC S16 rgSCHUtlRgrLcgCfg(cell, ue, cfg, errInfo)
3123 RgSchErrInfo *errInfo;
3126 TRC2(rgSCHUtlRgrLcgCfg);
3127 RETVALUE(cell->sc.apis->rgSCHRgrLcgCfg(cell, ue, &(ue->ul.lcgArr[cfg->ulInfo.lcgId]), cfg, errInfo));
3132 * @brief This function modifies a service to scheduler
3136 * Function: rgSCHUtlRgrLcgRecfg
3137 * Purpose: This function performs modification of a service in
3138 * scheduler. The modification is performed for each direction
3139 * based the direction field of the configuration
3141 * Invoked by: Scheduler
3143 * @param[in] RgSchCellCb *cell
3144 * @param[in] RgSchUeCb *ue
3145 * @param[in] RgrLcgRecfg *recfg
3146 * @param[in] RgSchErrInfo *err
3151 PUBLIC S16 rgSCHUtlRgrLcgRecfg
3159 PUBLIC S16 rgSCHUtlRgrLcgRecfg(cell, ue, recfg, err)
3166 TRC2(rgSCHUtlRgrLcgRecfg);
3167 RETVALUE(cell->sc.apis->rgSCHRgrLcgRecfg(cell, ue, &(ue->ul.lcgArr[recfg->ulRecfg.lcgId]), recfg, err));
3168 } /* rgSCHUtlRgrLcRecfg */
3171 * @brief This function modifies a service to scheduler
3175 * Function: rgSCHUtlRgrLcgDel
3176 * Purpose: This function performs modification of a service in
3177 * scheduler. The modification is performed for each direction
3178 * based the direction field of the configuration
3180 * Invoked by: Scheduler
3182 * @param[in] RgSchCellCb *cell
3183 * @param[in] RgSchUeCb *ue
3184 * @param[in] RgrDel *lcDelInfo
3189 PUBLIC Void rgSCHUtlRgrLcgDel
3196 PUBLIC Void rgSCHUtlRgrLcgDel(cell, ue, lcgId)
3202 TRC2(rgSCHUtlRgrLcgDel);
3203 cell->sc.apis->rgSCHFreeLcg(cell, ue, &ue->ul.lcgArr[lcgId]);
3205 /* Stack Crash problem for TRACE5 changes. added the return below . */
3208 } /* rgSCHUtlRgrLcgDel */
3211 /* End: LTEMAC_2.1_DEV_CFG */
3214 * @brief This function is a wrapper to call scheduler specific API.
3218 * Function: rgSCHUtlDoaInd
3219 * Purpose: Updates the DOA for the UE
3223 * @param[in] RgSchCellCb *cell
3224 * @param[in] RgSchUeCb *ue
3225 * @param[in] TfuDoaRpt *doaRpt
3230 PUBLIC Void rgSCHUtlDoaInd
3237 PUBLIC Void rgSCHUtlDoaInd(cell, ue, doaRpt)
3243 TRC2(rgSCHUtlDoaInd);
3244 ue->mimoInfo.doa.pres = PRSNT_NODEF;
3245 ue->mimoInfo.doa.val = doaRpt->doa;
3250 * @brief This function is a wrapper to call scheduler specific API.
3254 * Function: rgSCHUtlDlCqiInd
3255 * Purpose: Updates the DL CQI for the UE
3259 * @param[in] RgSchCellCb *cell
3260 * @param[in] RgSchUeCb *ue
3261 * @param[in] TfuDlCqiRpt *dlCqiRpt
3262 * @param[in] CmLteTimingInfo timingInfo
3267 PUBLIC Void rgSCHUtlDlCqiInd
3271 TfuDlCqiRpt *dlCqiRpt,
3272 CmLteTimingInfo timingInfo
3275 PUBLIC Void rgSCHUtlDlCqiInd(cell, ue, dlCqiRpt, timingInfo)
3278 TfuDlCqiRpt *dlCqiRpt;
3279 CmLteTimingInfo timingInfo;
3282 RgSchCellCb *sCellCb = NULLP;
3283 TRC2(rgSCHUtlDlCqiInd);
3284 if (dlCqiRpt->isPucchInfo)
3286 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pucchCqi.cellIdx]->cell;
3287 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3288 (Void *)&dlCqiRpt->dlCqiInfo.pucchCqi, timingInfo);
3293 for (idx = 0; idx < dlCqiRpt->dlCqiInfo.pusch.numOfCells; idx++)
3295 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx].cellIdx]->cell;
3296 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3297 (Void *)&dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx], timingInfo);
3306 * @brief This function is a wrapper to call scheduler specific API.
3310 * Function: rgSCHUtlSrsInd
3311 * Purpose: Updates the UL SRS for the UE
3315 * @param[in] RgSchCellCb *cell
3316 * @param[in] RgSchUeCb *ue
3317 * @param[in] TfuSrsRpt* srsRpt
3318 * @param[in] CmLteTimingInfo timingInfo
3323 PUBLIC Void rgSCHUtlSrsInd
3328 CmLteTimingInfo timingInfo
3331 PUBLIC Void rgSCHUtlSrsInd(cell, ue, srsRpt, timingInfo)
3335 CmLteTimingInfo timingInfo;
3338 TRC2(rgSCHUtlSrsInd);
3339 cell->sc.apis->rgSCHSrsInd(cell, ue, srsRpt, timingInfo);
3345 * @brief This function is a wrapper to call scheduler specific API.
3349 * Function: rgSCHUtlDlTARpt
3350 * Purpose: Reports PHY TA for a UE.
3354 * @param[in] RgSchCellCb *cell
3355 * @param[in] RgSchUeCb *ue
3360 PUBLIC Void rgSCHUtlDlTARpt
3366 PUBLIC Void rgSCHUtlDlTARpt(cell, ue)
3371 TRC2(rgSCHUtlDlTARpt);
3372 cell->sc.apis->rgSCHDlTARpt(cell, ue);
3378 * @brief This function is a wrapper to call scheduler specific API.
3382 * Function: rgSCHUtlDlRlsSubFrm
3383 * Purpose: Releases scheduler Information from DL SubFrm.
3387 * @param[in] RgSchCellCb *cell
3388 * @param[out] CmLteTimingInfo subFrm
3393 PUBLIC Void rgSCHUtlDlRlsSubFrm
3396 CmLteTimingInfo subFrm
3399 PUBLIC Void rgSCHUtlDlRlsSubFrm(cell, subFrm)
3401 CmLteTimingInfo subFrm;
3404 TRC2(rgSCHUtlDlRlsSubFrm);
3405 cell->sc.apis->rgSCHDlRlsSubFrm(cell, subFrm);
3411 * @brief This API is invoked to update the AperCQI trigger
3416 * Function : rgSCHUtlUpdACqiTrigWt
3417 * - If HqFdbk is ACK then add up weight corresponding
3418 * to ACK to the AcqiTrigWt.
3419 * - If HqFdbk is NACK then add up weight corresponding
3420 * to NACK to the AcqiTrigWt.
3421 * - If AcqiTrigWt crosses threshold then trigger
3422 * grant req for APERCQI to SCH.
3424 * @param[in] RgSchUeCb *ue
3425 * @param[in] U8 isAck
3430 PUBLIC Void rgSCHUtlUpdACqiTrigWt
3433 RgSchUeCellInfo *cellInfo,
3437 PUBLIC Void rgSCHUtlUpdACqiTrigWt(ue,cellInfo, isAck)
3439 RgSchUeCellInfo *cellInfo;
3448 TRC2(rgSCHUtlUpdACqiTrigWt);
3450 if (isAck == TFU_HQFDB_ACK)
3452 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_ACK_WGT;
3456 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_NACK_WGT;
3459 if (cellInfo->acqiCb.aCqiTrigWt > RG_APER_CQI_THRESHOLD_WGT)
3461 RgSchCellCb *cell = ue->cell;
3462 RgSchErrInfo unUsed;
3464 if(ue->dl.reqForCqi)
3466 /* Already one ACQI trigger procedure is going on
3467 * which is not yet satisfied. Delaying this request till
3468 * the previous is getting satisfied*/
3472 ue->dl.reqForCqi = TRUE;
3474 rgSchCmnSetCqiReqField(cellInfo,ue,&ue->dl.reqForCqi);
3475 //Reset aCqiTrigWt for all the serving cells for which we have triggered ACQI
3476 rgSCHTomUtlGetTrigSet(cell, ue, ue->dl.reqForCqi, &triggerSet);
3477 for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++)
3479 /* The Aperiodic requested for SCell index sIdx */
3480 if ((triggerSet >> (7 - sIdx)) & 0x01)
3482 /* The Aperiodic request for SCell index sIdx */
3483 ue->cellInfo[sIdx]->acqiCb.aCqiTrigWt = 0;
3488 /* Force SCH to send UL grant by indicating fake SR.
3489 * If this UE already in UL SCH Qs this SR Ind will
3491 rgSCHUtlSrRcvd(cell, ue, cell->crntTime, &unUsed);
3499 * @brief This API is invoked to indicate scheduler of a CRC indication.
3503 * Function : rgSCHUtlHdlUlTransInd
3504 * This API is invoked to indicate scheduler of a CRC indication.
3506 * @param[in] RgSchCellCb *cell
3507 * @param[in] RgSchUeCb *ue
3508 * @param[in] CmLteTimingInfo timingInfo
3513 PUBLIC Void rgSCHUtlHdlUlTransInd
3517 CmLteTimingInfo timingInfo
3520 PUBLIC Void rgSCHUtlHdlUlTransInd(cell, ue, timingInfo)
3523 CmLteTimingInfo timingInfo;
3526 TRC2(rgSCHUtlHdlUlTransInd);
3527 cell->sc.apis->rgSCHHdlUlTransInd(cell, ue, timingInfo);
3532 * @brief This API is invoked to indicate scheduler of a CRC failure.
3536 * Function : rgSCHUtlHdlCrcInd
3537 * This API is invoked to indicate CRC to scheduler.
3539 * @param[in] RgSchCellCb *cell
3540 * @param[in] RgSchUeCb *ue
3541 * @param[in] CmLteTimingInfo timingInfo
3546 PUBLIC Void rgSCHUtlHdlCrcInd
3550 CmLteTimingInfo timingInfo
3553 PUBLIC Void rgSCHUtlHdlCrcInd(cell, ue, timingInfo)
3556 CmLteTimingInfo timingInfo;
3559 TRC2(rgSCHUtlHdlCrcFail);
3560 cell->sc.apis->rgSCHUlCrcInd(cell, ue, timingInfo);
3562 } /* end of rgSCHUtlHdlCrcFailInd */
3565 * @brief This API is invoked to indicate scheduler of a CRC failure.
3569 * Function : rgSCHUtlHdlCrcFailInd
3570 * This API is invoked to indicate CRC failure to scheduler.
3572 * @param[in] RgSchCellCb *cell
3573 * @param[in] RgSchUeCb *ue
3574 * @param[in] CmLteTimingInfo timingInfo
3579 PUBLIC Void rgSCHUtlHdlCrcFailInd
3583 CmLteTimingInfo timingInfo
3586 PUBLIC Void rgSCHUtlHdlCrcFailInd(cell, ue, timingInfo)
3589 CmLteTimingInfo timingInfo;
3592 TRC2(rgSCHUtlHdlCrcFail);
3593 cell->sc.apis->rgSCHUlCrcFailInd(cell, ue, timingInfo);
3595 } /* end of rgSCHUtlHdlCrcFailInd */
3596 #endif /* LTEMAC_SPS */
3600 * @brief This function is a wrapper to call scheduler specific API.
3604 * Function: rgSCHUtlDlProcAddToRetx
3605 * Purpose: This function adds a HARQ process to retransmission
3606 * queue. This may be performed when a HARQ ack is
3609 * Invoked by: HARQ feedback processing
3611 * @param[in] RgSchCellCb* cell
3612 * @param[in] RgSchDlHqProc* hqP
3617 PUBLIC Void rgSCHUtlDlProcAddToRetx
3620 RgSchDlHqProcCb *hqP
3623 PUBLIC Void rgSCHUtlDlProcAddToRetx(cell, hqP)
3625 RgSchDlHqProcCb *hqP;
3628 TRC2(rgSCHUtlDlProcAddToRetx);
3629 cell->sc.apis->rgSCHDlProcAddToRetx(cell, hqP);
3635 * @brief This function adds a HARQ process TB to transmission
3639 * Function: rgSCHUtlDlHqPTbAddToTx
3640 * Purpose: This function a HarqProcess TB to the subframe
3643 * Invoked by: Scheduler
3645 * @param[in] RgSubFrm* subFrm
3646 * @param[in] RgDlHqProc* hqP
3647 * @param[in] U8 tbIdx
3652 PUBLIC Void rgSCHUtlDlHqPTbAddToTx
3655 RgSchDlHqProcCb *hqP,
3659 PUBLIC Void rgSCHUtlDlHqPTbAddToTx(subFrm, hqP, tbIdx)
3661 RgSchDlHqProcCb *hqP;
3665 RgSchUeCb *ue = NULLP;
3666 RgSchCellCb *cell = hqP->hqE->cell;
3668 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3669 /* ue->cell will always hold PCell information */
3670 if (NULLP == hqP->hqPSfLnk.node)
3675 if(NULLP == ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node)
3677 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)ue;
3678 cmLListAdd2Tail(&cell->subFrms[subFrm->dlIdx]->ueLst,
3679 &ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3681 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].isPuschHarqRecpPres = FALSE;
3685 /* Add Hq proc in particular dlIdx List for this UE
3686 This list will be used while processing feedback*/
3687 hqP->hqPSfLnk.node = (PTR)hqP;
3688 cmLListAdd2Tail(&ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3691 extern U32 gSCellSchedCount,gPrimarySchedCount;
3692 if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue,hqP->hqE->cell))
3696 gPrimarySchedCount++;
3700 else if (hqP->hqE->msg4Proc == hqP)
3702 /* Msg4 will be scheduled on PCELL only hence add directly to subFrm msg4HqpList */
3703 hqP->hqPSfLnk.node = (PTR)hqP;
3704 cmLListAdd2Tail(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3711 if((ue) && (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state))
3714 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt++;
3716 /*totalTbCnt will hold the total number of TBs across all harq Proc from all
3719 hqP->subFrm = subFrm;
3728 * @brief This function removes a HARQ process TB from transmission
3732 * Function: rgSCHUtlDlHqPTbRmvFrmTx
3733 * Purpose: This function removes a HarqProcess TB to the subframe
3736 * Invoked by: Scheduler
3738 * @param[in] RgSubFrm* subFrm
3739 * @param[in] RgDlHqProc* hqP
3740 * @param[in] U8 tbIdx
3741 * @param[in] Bool isRepeting
3746 PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx
3749 RgSchDlHqProcCb *hqP,
3754 PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx(subFrm, hqP, tbIdx, isRepeting)
3756 RgSchDlHqProcCb *hqP;
3761 RgSchCellCb *cell = NULLP;
3762 /* Check with TDD */
3764 (hqP->hqE->ue->ackNakRepCb.cfgRepCnt !=
3765 hqP->tbInfo[tbIdx].fbkRepCntr))
3767 cmLListDelFrm(&subFrm->ackNakRepQ,
3768 &hqP->tbInfo[tbIdx].anRepLnk[hqP->tbInfo[tbIdx].fbkRepCntr]);
3772 if (NULLP != hqP->hqPSfLnk.node)
3775 if (hqP->hqE->msg4Proc == hqP)
3777 /* Msg4 will be scheduled on PCELL only hence delete directly from subFrm msg4HqpList */
3778 cmLListDelFrm(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3782 cell = hqP->hqE->cell;
3783 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3784 /* ue->cell will always hold PCell information */
3785 cmLListDelFrm(&hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3786 if (0 == hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst.count)
3789 cmLListDelFrm(&cell->subFrms[subFrm->dlIdx]->ueLst,
3790 &hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3791 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)NULLP;
3792 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt = 0;
3795 hqP->hqPSfLnk.node = NULLP;
3797 hqP->subFrm = NULLP;
3804 * @brief Handler for accessing the existing SCellCb identified by the key
3805 * SCellId under the CellCb.
3809 * Function : rgSchUtlGetCellCb
3812 * @param[in] *cellCb
3814 * @return RgSchUeCb*
3817 PUBLIC RgSchCellCb* rgSchUtlGetCellCb
3823 PUBLIC RgSchCellCb* rgSchUtlGetCellCb(inst, cellId)
3828 RgSchCellCb *cellCb = NULLP;
3831 TRC2(rgSchUtlGetCellCb);
3833 strtCellId = rgSchCb[inst].genCfg.startCellId;
3834 cellCb = rgSchCb[inst].cells[cellId - strtCellId];
3838 } /* rgSchUtlGetCellCb */
3841 * @brief Handler for deriving the servCellidx
3845 * Function : rgSchUtlGetServCellIdx
3848 * @param[in] *cellId
3849 * @param[in] RgSchUeCb *ue
3850 * @return U8 servCellIdx
3853 PUBLIC U8 rgSchUtlGetServCellIdx
3860 PUBLIC U8 rgSchUtlGetServCellIdx(inst,cellId,ue)
3869 TRC2(rgSchUtlGetCellCb);
3871 strtCellId = rgSchCb[inst].genCfg.startCellId;
3873 servCellIdx = ue->cellIdToCellIdxMap[cellId - strtCellId];
3875 RETVALUE(servCellIdx);
3877 } /* rgSchUtlGetCellCb */
3880 * @brief Handler for validating the Cell Id received secondary Cell Addition
3884 * Function : rgSchUtlGetCellId
3887 * @param[in] *cellCb
3889 * @return RgSchUeCb*
3892 PUBLIC S16 rgSchUtlVldtCellId
3898 PUBLIC S16 rgSchUtlVldtCellId(inst, cellId)
3905 TRC2(rgSchUtlVldtCellId);
3907 strtCellId = rgSchCb[inst].genCfg.startCellId;
3908 if((cellId >= strtCellId) && ((cellId - strtCellId) < CM_LTE_MAX_CELLS))
3913 } /* rgSchUtlVldtCellId */
3917 * @brief UE reconfiguration for scheduler
3921 * Function : rgSCHUtlRgrUeRecfg
3923 * This functions updates UE specific scheduler
3924 * information upon UE reconfiguration
3926 * @param[in] RgSchCellCb *cell
3927 * @param[in] RgSchUeCb *ue
3928 * @param[int] RgrUeRecfg *ueRecfg
3929 * @param[out] RgSchErrInfo *err
3935 PUBLIC S16 rgSCHUtlRgrUeRecfg
3939 RgrUeRecfg *ueRecfg,
3943 PUBLIC S16 rgSCHUtlRgrUeRecfg(cell, ue, ueRecfg, err)
3946 RgrUeRecfg *ueRecfg;
3950 /* Changes for UE Category Reconfiguration feature addition */
3951 RgSchCmnUe *ueSch = RG_SCH_CMN_GET_UE(ue, cell);
3953 TRC2(rgSCHUtlRgrUeRecfg);
3955 /* Changes for UE Category Reconfiguration feature addition */
3956 if (ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
3958 ueSch->cmn.ueCat = ueRecfg->ueCatEnum-1;
3960 ue->ueCatEnum = ueRecfg->ueCatEnum;
3964 /* DL MU-MIMO not supported */
3965 if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
3968 if (ueRecfg->txMode.pres == PRSNT_NODEF)
3970 if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_5)
3972 err->errCause = RGSCHERR_SCH_CFG;
3976 if(ue->mimoInfo.txMode != ueRecfg->txMode.txModeEnum)
3978 /* Decremnt the previos A value for this cell */
3979 ue->f1bCsAVal -= rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode);
3980 /* Update A value with the new TM Mode */
3981 ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(ueRecfg->txMode.txModeEnum);
3984 RLOG1(L_INFO,"UeReCfg A valie is %d\n",ue->f1bCsAVal);
3987 ue->mimoInfo.txMode = ueRecfg->txMode.txModeEnum;
3991 /* [ccpu00123958]-ADD- Check for PUSCH related Reconfig from the bit mask */
3992 if(ueRecfg->ueRecfgTypes & RGR_UE_PUSCH_RECFG)
3994 /* Fix: ccpu00124012 */
3995 /* TODO:: Need to check if this is
3996 mandatory to be re-configured on UE category re-configuration */
3997 /* ue->ul.betaHqOffst = ueRecfg->puschDedCfg.bACKIdx;
3998 ue->ul.betaCqiOffst = ueRecfg->puschDedCfg.bCQIIdx;
3999 ue->ul.betaRiOffst = ueRecfg->puschDedCfg.bRIIdx;*/
4002 if (ueRecfg->ueRecfgTypes & RGR_UE_ULTXANTSEL_RECFG)
4004 ue->ul.ulTxAntSel = ueRecfg->ulTxAntSel;
4006 if (ueRecfg->ueRecfgTypes & RGR_UE_CDBKSBST_RECFG)
4008 ue->mimoInfo.cdbkSbstRstrctn = ueRecfg->ueCodeBookRstRecfg;
4011 /* Commenting here to assign garbage value when it is not set in APP. */
4012 //ue->accessStratumRls = ueRecfg->accessStratumRls;
4013 RETVALUE(cell->sc.apis->rgSCHRgrUeRecfg(cell, ue, ueRecfg, err));
4014 } /* rgSCHUtlRgrUeRecfg */
4017 * @brief This function deletes a service from scheduler
4021 * Function: rgSCHUtlFreeDlLc
4022 * Purpose: This function is made available through a FP for
4023 * making scheduler aware of a service being deleted from UE
4025 * Invoked by: BO and Scheduler
4027 * @param[in] RgSchCellCb* cell
4028 * @param[in] RgSchUeCb* ue
4029 * @param[in] RgSchDlLcCb* svc
4033 PUBLIC Void rgSCHUtlFreeDlLc
4040 PUBLIC Void rgSCHUtlFreeDlLc(cell, ue, svc)
4046 TRC2(rgSCHUtlFreeDlLc);
4047 cell->sc.apis->rgSCHFreeDlLc(cell, ue, svc);
4049 /* Stack Crash problem for TRACE5 changes. added the return below . */
4055 * @brief UE deletion for scheduler
4059 * Function : rgSCHUtlFreeUe
4061 * This functions deletes all scheduler information
4062 * pertaining to a UE
4064 * @param[in] RgSchCellCb *cell
4065 * @param[in] RgSchUeCb *ue
4069 PUBLIC Void rgSCHUtlFreeUe
4075 PUBLIC Void rgSCHUtlFreeUe(cell, ue)
4080 TRC2(rgSCHUtlFreeUe);
4082 rgSCHUtlDelUeANFdbkInfo(ue,RGSCH_PCELL_INDEX);
4084 cell->sc.apis->rgSCHFreeUe(cell, ue);
4086 /* Stack Crash problem for TRACE5 changes. added the return below . */
4089 } /* rgSCHUtlFreeUe */
4092 * @brief This function updates the scheduler with service for a UE
4096 * Function: rgSCHUtlDlDedBoUpd
4097 * Purpose: This function should be called whenever there is a
4098 * change BO for a service.
4100 * Invoked by: BO and Scheduler
4102 * @param[in] RgSchCellCb* cell
4103 * @param[in] RgSchUeCb* ue
4104 * @param[in] RgSchDlLcCb* lc
4108 PUBLIC Void rgSCHUtlDlDedBoUpd
4115 PUBLIC Void rgSCHUtlDlDedBoUpd(cell, ue, lc)
4121 TRC2(rgSCHUtlDlDedBoUpd);
4122 cell->sc.apis->rgSCHDlDedBoUpd(cell, ue, lc);
4126 * @brief Record MSG3 allocation into the UE
4130 * Function : rgSCHUtlRecMsg3Alloc
4132 * This function is invoked to update record msg3 allocation information
4133 * in the UE when UE is detected for RaCb
4135 * @param[in] RgSchCellCb *cell
4136 * @param[in] RgSchUeCb *ue
4137 * @param[in] RgSchRaCb *raCb
4141 PUBLIC Void rgSCHUtlRecMsg3Alloc
4148 PUBLIC Void rgSCHUtlRecMsg3Alloc(cell, ue, raCb)
4154 TRC2(rgSCHUtlRecMsg3Alloc)
4155 cell->sc.apis->rgSCHUlRecMsg3Alloc(cell, ue, raCb);
4158 } /* rgSCHRecMsg3Alloc */
4162 * @brief Update harq process for allocation
4166 * Function : rgSCHUtlUpdUlHqProc
4168 * This function is invoked when harq process
4169 * control block is now in a new memory location
4170 * thus requiring a pointer/reference update.
4172 * @param[in] RgSchCellCb *cell
4173 * @param[in] RgSchUlHqProcCb *curProc
4174 * @param[in] RgSchUlHqProcCb *oldProc
4180 PUBLIC S16 rgSCHUtlUpdUlHqProc
4183 RgSchUlHqProcCb *curProc,
4184 RgSchUlHqProcCb *oldProc
4187 PUBLIC S16 rgSCHUtlUpdUlHqProc(cell, curProc, oldProc)
4189 RgSchUlHqProcCb *curProc;
4190 RgSchUlHqProcCb *oldProc;
4193 TRC2(rgSCHUtlUpdUlHqProc);
4194 RETVALUE(cell->sc.apis->rgSCHUpdUlHqProc(cell, curProc, oldProc));
4195 } /* rgSCHUtlUpdUlHqProc */
4198 * @brief UL grant for contention resolution
4202 * Function : rgSCHUtlContResUlGrant
4204 * Add UE to another queue specifically for CRNTI based contention
4207 * @param[in] RgSchCellCb *cell
4208 * @param[in] RgSchUeCb *ue
4209 * @param[out] RgSchErrInfo *err
4215 PUBLIC S16 rgSCHUtlContResUlGrant
4222 PUBLIC S16 rgSCHUtlContResUlGrant(cell, ue, err)
4228 TRC2(rgSCHUtlContResUlGrant);
4231 ue->isMsg4PdcchWithCrnti = TRUE;
4233 RETVALUE(cell->sc.apis->rgSCHContResUlGrant(cell, ue, err));
4234 } /* rgSCHUtlContResUlGrant */
4237 * @brief SR reception handling
4241 * Function : rgSCHUtlSrRcvd
4243 * - Handles SR reception for UE
4245 * @param[in] RgSchCellCb *cell
4246 * @param[in] RgSchUeCb *ue
4247 * @param[out] RgSchErrInfo *err
4253 PUBLIC S16 rgSCHUtlSrRcvd
4257 CmLteTimingInfo frm,
4261 PUBLIC S16 rgSCHUtlSrRcvd(cell, ue, frm, err)
4264 CmLteTimingInfo frm;
4268 TRC2(rgSCHUtlSrRcvd);
4269 RETVALUE(cell->sc.apis->rgSCHSrRcvd(cell, ue, frm, err));
4270 } /* rgSCHUtlSrRcvd */
4273 * @brief Short BSR update
4277 * Function : rgSCHUtlUpdBsrShort
4279 * This functions does requisite updates to handle short BSR reporting
4281 * @param[in] RgSchCellCb *cell
4282 * @param[in] RgSchUeCb *ue
4283 * @param[in] U8 lcgId
4285 * @param[out] RgSchErrInfo *err
4291 PUBLIC Void rgSCHUtlUpdBsrShort
4300 PUBLIC Void rgSCHUtlUpdBsrShort(cell, ue, lcgId, bsr, err)
4308 TRC2(rgSCHUtlUpdBsrShort);
4309 cell->sc.apis->rgSCHUpdBsrShort(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4311 } /* rgSCHUtlUpdBsrShort */
4315 * @brief Truncated BSR update
4319 * Function : rgSCHUtlUpdBsrTrunc
4321 * This functions does required updates to handle truncated BSR report
4324 * @param[in] RgSchCellCb *cell
4325 * @param[in] RgSchUeCb *ue
4326 * @param[in] U8 lcgId
4328 * @param[out] RgSchErrInfo *err
4334 PUBLIC Void rgSCHUtlUpdBsrTrunc
4343 PUBLIC Void rgSCHUtlUpdBsrTrunc(cell, ue, lcgId, bsr, err)
4351 TRC2(rgSCHUtlUpdBsrTrunc);
4352 cell->sc.apis->rgSCHUpdBsrTrunc(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4354 } /* rgSCHUtlUpdBsrTrunc */
4358 * @brief Long BSR update
4362 * Function : rgSCHUtlUpdBsrLong
4364 * - Update BSRs for all configured LCGs
4365 * - Update priority of LCGs if needed
4366 * - Update UE's position within/across uplink scheduling queues
4369 * @param[in] RgSchCellCb *cell
4370 * @param[in] RgSchUeCb *ue
4371 * @param[in] U8 bsr0
4372 * @param[in] U8 bsr1
4373 * @param[in] U8 bsr2
4374 * @param[in] U8 bsr3
4375 * @param[out] RgSchErrInfo *err
4381 PUBLIC Void rgSCHUtlUpdBsrLong
4392 PUBLIC Void rgSCHUtlUpdBsrLong(cell, ue, bsr0, bsr1, bsr2, bsr3, err)
4403 TRC2(rgSCHUtlUpdBsrLong);
4409 cell->sc.apis->rgSCHUpdBsrLong(cell, ue, bsArr, err);
4411 } /* rgSCHUtlUpdBsrLong */
4414 * @brief EXT PHR update
4418 * Function : rgSCHUtlUpdExtPhr
4420 * Updates extended power headroom info for a UE
4422 * @param[in] RgSchCellCb *cell
4423 * @param[in] RgSchUeCb *ue
4425 * @param[out] RgSchErrInfo *err
4431 PUBLIC S16 rgSCHUtlUpdExtPhr
4435 RgInfExtPhrCEInfo * extPhr,
4439 PUBLIC S16 rgSCHUtlUpdExtPhr(cell, ue, extPhr, err)
4442 RgInfExtPhrCEInfo * extPhr;
4446 TRC2(rgSCHUtlUpdExtPhr);
4447 RETVALUE(cell->sc.apis->rgSCHUpdExtPhr(cell, ue, extPhr, err));
4448 } /* rgSCHUtlUpdExtPhr */
4457 * Function : rgSCHUtlUpdPhr
4459 * Updates power headroom info for a UE
4461 * @param[in] RgSchCellCb *cell
4462 * @param[in] RgSchUeCb *ue
4464 * @param[out] RgSchErrInfo *err
4470 PUBLIC S16 rgSCHUtlUpdPhr
4478 PUBLIC S16 rgSCHUtlUpdPhr(cell, ue, phr, err)
4485 TRC2(rgSCHUtlUpdPhr);
4486 RETVALUE(cell->sc.apis->rgSCHUpdPhr(cell, ue, phr, err));
4487 } /* rgSCHUtlUpdPhr */
4491 * @brief Indication of UL CQI
4495 * Function : rgSCHUtlUlCqiInd
4497 * - Updates uplink CQI information for the UE. Computes and
4498 * stores the lowest CQI of CQIs reported in all subbands
4500 * @param[in] RgSchCellCb *cell
4501 * @param[in] RgSchUeCb *ue
4502 * @param[in] TfuUlCqiRpt *ulCqiInfo
4506 PUBLIC Void rgSCHUtlUlCqiInd
4510 TfuUlCqiRpt *ulCqiInfo
4513 PUBLIC Void rgSCHUtlUlCqiInd(cell, ue, ulCqiInfo)
4516 TfuUlCqiRpt *ulCqiInfo;
4519 TRC2(rgSCHUtlUlCqiInd);
4520 cell->sc.apis->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
4522 } /* rgSCHUtlUlCqiInd */
4525 * @brief Indication of PUCCH power adjustment
4529 * Function : rgSCHUtlPucchDeltaPwrInd
4531 * - Updates uplink CQI information for the UE. Computes and
4532 * stores the lowest CQI of CQIs reported in all subbands
4534 * @param[in] RgSchCellCb *cell
4535 * @param[in] RgSchUeCb *ue
4536 * @param[in] U8 delta
4540 PUBLIC Void rgSCHUtlPucchDeltaPwrInd
4547 PUBLIC Void rgSCHUtlPucchDeltaPwrInd(cell, ue, delta)
4553 TRC2(rgSCHUtlPucchDeltaPwrInd);
4554 cell->sc.apis->rgSCHPucchDeltaPwrInd(cell, ue, delta);
4556 } /* rgSCHUtlPucchDeltaPwrInd */
4558 /* Start: LTEMAC_2.1_DEV_CFG */
4560 * @brief Ue Reset Request
4564 * Function : rgSCHUtlUeReset
4567 * @param[in] RgSchCellCb *cell
4568 * @param[in] RgSchUeCb *ue
4572 PUBLIC Void rgSCHUtlUeReset
4578 PUBLIC Void rgSCHUtlUeReset(cell, ue)
4583 TRC2(rgSCHUtlUeReset);
4585 cell->sc.apis->rgSCHUeReset(cell, ue);
4587 } /* rgSCHUtlUeReset */
4588 /* End: LTEMAC_2.1_DEV_CFG */
4591 * @brief Returns HARQ proc for which data expected now
4595 * Function: rgSCHUtlUlHqProcForUe
4596 * Purpose: This function returns the harq process for
4597 * which data is expected in the current subframe.
4598 * It does not validate if the HARQ process
4599 * has an allocation.
4603 * @param[in] RgSchCellCb *cell
4604 * @param[in] CmLteTimingInfo frm
4605 * @param[in] RgSchUeCb *ue
4606 * @param[out] RgSchUlHqProcCb **procRef
4610 PUBLIC Void rgSCHUtlUlHqProcForUe
4613 CmLteTimingInfo frm,
4615 RgSchUlHqProcCb **procRef
4618 PUBLIC Void rgSCHUtlUlHqProcForUe(cell, frm, ue, procRef)
4620 CmLteTimingInfo frm;
4622 RgSchUlHqProcCb **procRef;
4625 TRC2(rgSCHUtlUlHqProcForUe);
4626 cell->sc.apis->rgSCHUlHqProcForUe(cell, frm, ue, procRef);
4628 /* Stack Crash problems for TRACE5 changes. added the return below */
4634 * @brief Returns first uplink allocation to send reception
4639 * Function: rgSCHUtlFirstRcptnReq(cell)
4640 * Purpose: This function returns the first uplink allocation
4641 * (or NULLP if there is none) in the subframe
4642 * in which is expected to prepare and send reception
4647 * @param[in] RgSchCellCb *cell
4648 * @return RgSchUlAlloc*
4651 PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq
4656 PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq(cell)
4660 TRC2(rgSCHUtlFirstRcptnReq);
4661 RETVALUE(cell->sc.apis->rgSCHFirstRcptnReq(cell));
4665 * @brief Returns first uplink allocation to send reception
4670 * Function: rgSCHUtlNextRcptnReq(cell)
4671 * Purpose: This function returns the next uplink allocation
4672 * (or NULLP if there is none) in the subframe
4673 * in which is expected to prepare and send reception
4678 * @param[in] RgSchCellCb *cell
4679 * @return RgSchUlAlloc*
4682 PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq
4688 PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq(cell, alloc)
4690 RgSchUlAlloc *alloc;
4693 TRC2(rgSCHUtlNextRcptnReq);
4694 RETVALUE(cell->sc.apis->rgSCHNextRcptnReq(cell, alloc));
4698 * @brief Returns first uplink allocation to send HARQ feedback
4703 * Function: rgSCHUtlFirstHqFdbkAlloc
4704 * Purpose: This function returns the first uplink allocation
4705 * (or NULLP if there is none) in the subframe
4706 * in which it is expected to prepare and send HARQ
4711 * @param[in] RgSchCellCb *cell
4713 * @return RgSchUlAlloc*
4716 PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc
4722 PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc(cell, idx)
4727 TRC2(rgSCHUtlFirstHqFdbkAlloc);
4728 RETVALUE(cell->sc.apis->rgSCHFirstHqFdbkAlloc(cell, idx));
4733 * @brief Returns next allocation to send HARQ feedback for
4737 * Function: rgSCHUtlNextHqFdbkAlloc(cell)
4738 * Purpose: This function returns the next uplink allocation
4739 * (or NULLP if there is none) in the subframe
4740 * for which HARQ feedback needs to be sent.
4744 * @param[in] RgSchCellCb *cell
4745 * @return RgSchUlAlloc*
4748 PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc
4751 RgSchUlAlloc *alloc,
4755 PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc(cell, alloc, idx)
4757 RgSchUlAlloc *alloc;
4761 TRC2(rgSCHUtlNextHqFdbkAlloc);
4762 RETVALUE(cell->sc.apis->rgSCHNextHqFdbkAlloc(cell, alloc, idx));
4765 /***********************************
4766 ***********************************/
4768 * @brief This API is invoked to send TFU SAP bind request to PHY.
4772 * Function : rgSCHUtlTfuBndReq
4774 * This API is invoked to send TFU SAP bind request to PHY from scheduler
4775 * isntance. It fills in the Pst structure, spId and suId values and
4776 * invokes bind request primitive at TFU.
4778 * @param[in] Inst instId
4779 * @param[in] SuId suId
4780 * @param[in] SpId spId
4786 PUBLIC S16 rgSCHUtlTfuBndReq
4793 PUBLIC S16 rgSCHUtlTfuBndReq(instId, suId, spId)
4800 RgSchLowSapCb *tfuSap;
4802 TRC2(rgSCHUtlTfuBndReq);
4804 /* Get the lower SAP control block from the layer control block. */
4805 tfuSap = &(rgSchCb[instId].tfuSap[suId]);
4806 (Void)cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
4807 if((ret = RgLiTfuSchBndReq (&pst, suId, spId)) != ROK)
4809 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlTfuBndReq() Call to RgLiTfuBndReq()"
4813 } /* rgSCHUtlTfuBndReq */
4816 * @brief This API is invoked to send TFU SAP unbind request to PHY.
4820 * Function : rgSCHUtlTfuUBndReq
4821 * This API is invoked to send TFU SAP unbind request to PHY from Scheduler
4822 * isntance. It fills in the Pst structure and spId value and invokes
4823 * unbind request primitive at TFU.
4825 * @param[in] SpId spId
4831 PUBLIC S16 rgSCHUtlTfuUBndReq
4834 RgSchLowSapCfgInfo sapCfg,
4838 PUBLIC S16 rgSCHUtlTfuUBndReq(inst, sapCfg, reason)
4840 RgSchLowSapCfgInfo sapCfg;
4847 TRC2(rgSCHUtlTfuUBndReq);
4849 /* Get the lower SAP control block from the layer control block. */
4850 cmMemcpy ((U8*)&pst, (U8*)&(sapCfg.sapPst), sizeof(Pst));
4851 if((ret = RgLiTfuSchUbndReq (&pst, sapCfg.spId, reason)) != ROK)
4853 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuUBndReq() Call to"
4854 " RgLiTfuUbndReq() failed");
4858 } /* rgSCHUtlTfuUBndReq */
4860 /***********************************************************
4862 * Func : rgSCHUtlResetSfAlloc
4864 * Desc : Utility Function to Reset subframe allocation information.
4873 **********************************************************/
4875 PUBLIC S16 rgSCHUtlResetSfAlloc
4877 RgInfSfAlloc *sfAlloc,
4878 Bool resetCmnLcInfo,
4882 PUBLIC S16 rgSCHUtlResetSfAlloc(sfAlloc,resetCmnLcInfo,restAlloc)
4883 RgInfSfAlloc *sfAlloc;
4884 Bool resetCmnLcInfo;
4888 TRC2(rgSCHUtlResetSfAlloc);
4889 if(TRUE == restAlloc)
4891 if(sfAlloc->ueInfo.numUes)
4893 cmMemset((U8 *)sfAlloc->ueInfo.allocInfo,0x00,
4894 (sizeof(RgInfUeAlloc)*sfAlloc->ueInfo.numUes));
4896 sfAlloc->ueInfo.numUes = 0;
4897 sfAlloc->rarInfo.numRaRntis = 0;
4898 sfAlloc->flowCntrlInfo.numUes = 0;
4900 if(TRUE == resetCmnLcInfo)
4902 sfAlloc->cmnLcInfo.bitMask = 0;
4907 /***********************************************************
4909 * Func : rgSCHUtlGetRlsHqAlloc
4911 * Desc : Utility Function to Allocate subframe allocation information.
4920 **********************************************************/
4922 PUBLIC S16 rgSCHUtlGetRlsHqAlloc
4927 PUBLIC S16 rgSCHUtlGetRlsHqAlloc(cell)
4932 Inst inst = cell->instIdx;
4933 TRC2(rgSCHUtlGetRlsHqAlloc);
4934 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4936 cell->rlsHqArr[idx].cellId = cell->cellId;
4938 /* Allocating with additional location, to accommodate
4939 TA scheduling along with maximum no of UEs per SF */
4941 /* Allocate memory for "scheduled UE" Info */
4942 if((rgSCHUtlAllocSBuf(inst,
4943 (Data**)&(cell->rlsHqArr[idx].ueHqInfo),
4944 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
4946 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4956 /***********************************************************
4958 * Func : rgSCHUtlPutRlsHqAlloc
4960 * Desc : Utility Function to deallocate subframe allocation information.
4969 **********************************************************/
4971 PUBLIC S16 rgSCHUtlPutRlsHqAlloc
4976 PUBLIC S16 rgSCHUtlPutRlsHqAlloc(cell)
4981 Inst inst = cell->instIdx;
4982 TRC2(rgSCHUtlPutRlsHqAlloc);
4984 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4986 /* Deallocate memory for "scheduled UE" Info */
4987 if (cell->rlsHqArr[idx].ueHqInfo != NULLP)
4989 /* Freeing with additional location, to accommodate TA
4990 scheduling along with maximum no of UEs per SF */
4991 /* ccpu00117052 - MOD - Passing double pointer
4992 for proper NULLP assignment*/
4993 rgSCHUtlFreeSBuf(inst,
4994 (Data **)(&(cell->rlsHqArr[idx].ueHqInfo)),
4995 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF));
5004 /***********************************************************
5006 * Func : rgSCHUtlGetSfAlloc
5008 * Desc : Utility Function to Allocate subframe allocation information.
5017 **********************************************************/
5019 PUBLIC S16 rgSCHUtlGetSfAlloc
5024 PUBLIC S16 rgSCHUtlGetSfAlloc(cell)
5030 Inst inst = cell->instIdx;
5031 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5032 TRC2(rgSCHUtlGetSfAlloc);
5035 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5037 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5040 cell->sfAllocArr[idx].cellId = cell->cellId;
5042 /* Allocating with additional location, to accommodate
5043 TA scheduling along with maximum no of UEs per SF */
5045 /* Allocate memory for "scheduled UE" Info */
5046 if((rgSCHUtlAllocSBuf(inst,
5047 (Data**)&(cell->sfAllocArr[idx].ueInfo.allocInfo),
5048 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
5050 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5055 /* Allocate memory for "scheduled RAR" Info */
5056 if((rgSCHUtlAllocSBuf(inst,
5057 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo),
5058 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF))) != ROK)
5060 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5064 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5066 if((rgSCHUtlAllocSBuf(inst,
5067 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo),
5068 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)))) != ROK)
5070 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5079 rgSCHEmtcUtlGetSfAlloc(cell);
5086 /***********************************************************
5088 * Func : rgSCHUtlPutSfAlloc
5090 * Desc : Utility Function to deallocate subframe allocation information.
5099 **********************************************************/
5101 PUBLIC S16 rgSCHUtlPutSfAlloc
5106 PUBLIC S16 rgSCHUtlPutSfAlloc(cell)
5112 Inst inst = cell->instIdx;
5113 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5114 TRC2(rgSCHUtlPutSfAlloc);
5117 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5119 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5122 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo != NULLP)
5124 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5126 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo != NULLP)
5127 /* ccpu00117052 - MOD - Passing double pointer
5128 for proper NULLP assignment*/
5129 rgSCHUtlFreeSBuf(inst,
5130 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].\
5132 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)));
5134 /* Deallocate memory for "scheduled RAR" Info */
5135 /* ccpu00117052 - MOD - Passing double pointer
5136 for proper NULLP assignment*/
5137 rgSCHUtlFreeSBuf(inst,
5138 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo)),
5139 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF));
5141 /* Deallocate memory for "scheduled UE" Info */
5142 if (cell->sfAllocArr[idx].ueInfo.allocInfo != NULLP)
5144 /* Freeing with additional location, to accommodate TA
5145 scheduling along with maximum no of UEs per SF */
5146 /* ccpu00117052 - MOD - Passing double pointer
5147 for proper NULLP assignment*/
5148 rgSCHUtlFreeSBuf(inst,
5149 (Data**)(&(cell->sfAllocArr[idx].ueInfo.allocInfo)),
5150 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF));
5155 rgSCHEmtcUtlPutSfAlloc(cell);
5161 /***********************************************************
5163 * Func : rgSCHUtlAllocSBuf
5165 * Desc : Utility Function to Allocate static buffer.
5166 * Memory allocated is assumed contiguous.
5172 * Notes: Caller doesnt need to raise the alarm in case of memory
5173 * allocation gets failed.
5177 **********************************************************/
5179 PUBLIC S16 rgSCHUtlAllocSBuf
5181 Inst inst, /* Instance of the invoking scheduler */
5182 Data **pData, /* Pointer of the data to be returned */
5183 Size size /* size */
5186 PUBLIC S16 rgSCHUtlAllocSBuf(inst, pData, size)
5187 Inst inst; /* Instance of the invoking scheduler */
5188 Data **pData; /* Pointer of the data to be returned */
5189 Size size; /* size */
5192 /* Moving alarm diagnostics to available scope */
5194 TRC2(rgSCHUtlAllocSBuf)
5196 /* Initialize the param to NULLP */
5199 /* May not be necessary for data performance path */
5207 /* allocate buffer */
5208 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5209 MS_BUF_ADD_ALLOC_CALLER();
5211 if (SGetSBuf(rgSchCb[inst].rgSchInit.region, rgSchCb[inst].rgSchInit.pool,
5212 pData, size) != ROK)
5214 RgUstaDgn dgn; /* Alarm diagnostics structure */
5215 dgn.type = LRG_USTA_DGNVAL_MEM;
5216 dgn.u.mem.region = rgSchCb[inst].rgSchInit.region;
5217 dgn.u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5218 /* Send an alarm to Layer Manager */
5219 rgSCHLmmStaInd(inst, LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
5220 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
5221 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG015, 0, "Unable to Allocate Buffer");
5222 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Unable to Allocate the Buffer");
5227 /* zero out the allocated memory */
5228 cmMemset((U8 *)*pData, 0x00, size);
5232 } /* end of rgSCHUtlAllocSBuf */
5237 * Fun: rgSCHUtlFreeSBuf
5239 * Desc: The argument to rgSCHUtlFreeSBuf() is a pointer to a block
5240 * previously allocated by rgSCHUtlAllocSBuf() and size. It
5241 * deallocates the memory.
5249 PUBLIC Void rgSCHUtlFreeSBuf
5251 Inst inst, /* Instance of the invoking scheduler */
5252 Data **data, /* pointer to data */
5253 Size size /* size */
5256 PUBLIC Void rgSCHUtlFreeSBuf(inst, data, size)
5257 Inst inst; /* Instance of the invoking scheduler */
5258 Data **data; /* pointer to data */
5259 Size size; /* size */
5265 TRC2(rgSCHUtlFreeSBuf)
5267 if ((data == NULLP) || (*data == NULLP) || (size == 0))
5273 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5274 MS_BUF_ADD_CALLER();
5276 /* Deallocate buffer */
5277 ret = SPutSBuf(rgSchCb[inst].rgSchInit.region,
5278 rgSchCb[inst].rgSchInit.pool, (*data), size);
5282 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG016, (ErrVal) 0,
5283 "rgSCHUtlFreeSBuf failed.\n");
5284 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHUtlFreeSBuf failed");
5288 /* ccpu00117052 - ADD - Assigning the pointer to NULLP */
5292 } /* end of rgSCHUtlFreeSBuf */
5298 * Fun: rgSCHUtlFreeWarningSiSeg
5300 * Desc: This is used to deallocate Warning SI Seg.
5309 PUBLIC Void rgSCHUtlFreeWarningSiSeg
5316 PUBLIC Void rgSCHUtlFreeWarningSiSeg(reg, pool, siPduLst)
5319 CmLListCp *siPduLst;
5325 TRC2(rgSCHUtlFreeWarningSiSeg)
5327 while (siPduLst->first != NULLP)
5329 node = siPduLst->first;
5330 pdu = (Buffer *)node->node;
5331 cmLListDelFrm(siPduLst, node);
5332 RGSCH_FREE_MSG(pdu);
5333 SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList));
5338 } /* end of rgSCHUtlFreeWarningSiSeg */
5343 * Fun: rgSCHUtlFreeWarningSiPdu
5345 * Desc: This is used to deallocate Warning SI PDU.
5354 PUBLIC Void rgSCHUtlFreeWarningSiPdu
5359 PUBLIC Void rgSCHUtlFreeWarningSiPdu(cell)
5365 RgSchWarningSiInfo *warningSi;
5366 RgSchWarningSiPdu *warningSiPdu;
5368 TRC2(rgSCHUtlFreeWarningSiPdu)
5370 warningSi = (RgSchWarningSiInfo *) cell->siCb.\
5371 siArray[cell->siCb.siCtx.siId-1].si;
5372 /* ccpu00136659: CMAS ETWS design changes */
5373 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5379 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5380 pdu = warningSiPdu->pdu;
5381 /* ccpu00136659: CMAS ETWS design changes */
5382 cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node);
5383 RGSCH_FREE_MSG(pdu);
5384 if(warningSi->warningSiMsg.segLstCp.count == 0)
5386 /* ccpu00136659: CMAS ETWS design changes */
5387 cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP;
5388 rgSCHUtlRgrWarningSiCfgCfm(cell->instIdx,
5389 rgSchCb[cell->instIdx].rgrSap->sapCfg.spId,
5390 cell->siCb.warningSi[warningSi->idx].siId,
5391 warningSi->warningSiMsg.transId, RGR_CFG_CFM_TX_COMPLETE);
5396 } /* end of rgSCHUtlFreeWarningSiPdu */
5401 * Fun: rgSCHUtlGetWarningSiPdu
5403 * Desc: This is used to get Warning SI PDU for Scheduling.
5412 PUBLIC Buffer *rgSCHUtlGetWarningSiPdu
5417 PUBLIC Buffer *rgSCHUtlGetWarningSiPdu(cell)
5421 RgSchWarningSiInfo *warningSi;
5422 RgSchWarningSiPdu *warningSiPdu;
5426 TRC2(rgSCHUtlGetWarningSiPdu)
5428 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5429 siArray[cell->siCb.siCtx.siId-1].si;
5430 /* ccpu00136659: CMAS ETWS design changes */
5431 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5434 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5435 pdu = warningSiPdu->pdu;
5442 } /* rgSCHUtlGetWarningSiPdu */
5447 * Fun: rgSCHUtlGetMcsAndNPrb
5449 * Desc: This is used to get mcs and nPrb value.
5458 PUBLIC S16 rgSCHUtlGetMcsAndNPrb
5466 PUBLIC S16 rgSCHUtlGetMcsAndNPrb(cell, nPrb, mcs, msgLen)
5473 RgSchWarningSiInfo *warningSi;
5474 RgSchWarningSiPdu *warningSiPdu;
5477 TRC2(rgSCHUtlGetMcsAndNPrb)
5479 if(cell->siCb.siCtx.warningSiFlag == FALSE)
5481 *mcs = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].mcs;
5482 *nPrb = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].nPrb;
5483 *msgLen = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].msgLen;
5487 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5488 siArray[cell->siCb.siCtx.siId-1].si;
5489 /* ccpu00136659: CMAS ETWS design changes */
5490 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5496 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5497 *mcs = warningSiPdu->mcs;
5498 *nPrb = warningSiPdu->nPrb;
5499 *msgLen = warningSiPdu->msgLen;
5504 } /* rgSCHUtlGetMcsAndNPrb */
5508 * Fun: rgSCHUtlCalMacAndPrb
5510 * Desc: This is used to Calculate mcs and nPrb value for SIB1 and SIs.
5519 PUBLIC S16 rgSCHUtlCalMcsAndNPrb
5527 PUBLIC S16 rgSCHUtlCalMcsAndNPrb(cell, nPrb, mcs, msgLen)
5537 TRC2(rgSCHUtlCalMcsAndNPrb)
5539 /*Get the nPrb and mcs parametr values */
5540 if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8))
5542 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "msgLen does "
5543 "not match any valid TB Size");
5548 if(cfgType == RGR_SI_CFG_TYPE_SIB1 || cfgType == RGR_SI_CFG_TYPE_SIB1_PWS)
5551 if(cell->siCb.crntSiInfo.sib1Info.sib1 == NULLP)
5553 cell->siCb.crntSiInfo.sib1Info.mcs = mcs;
5554 cell->siCb.crntSiInfo.sib1Info.nPrb = nPrb;
5555 cell->siCb.crntSiInfo.sib1Info.msgLen = msgLen;
5559 cell->siCb.newSiInfo.sib1Info.mcs = mcs;
5560 cell->siCb.newSiInfo.sib1Info.nPrb= nPrb;
5561 cell->siCb.newSiInfo.sib1Info.msgLen = msgLen;
5566 if(cfgType == RGR_SI_CFG_TYPE_SI)
5568 if(cell->siCb.crntSiInfo.siInfo[siId-1].si == NULLP &&
5569 !(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD))
5571 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5572 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5573 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5577 cell->siCb.newSiInfo.siInfo[siId-1].mcs = mcs;
5578 cell->siCb.newSiInfo.siInfo[siId-1].nPrb= nPrb;
5579 cell->siCb.newSiInfo.siInfo[siId-1].msgLen = msgLen;
5583 if(cfgType == RGR_SI_CFG_TYPE_SIB8_CDMA)
5585 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5586 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5587 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5594 /***********************************************************
5596 * Func : rgSCHUtlFillDgnParams
5598 * Desc : Utility Function to Fill Diagonostic params.
5606 **********************************************************/
5608 PUBLIC Void rgSCHUtlFillDgnParams
5615 PUBLIC Void rgSCHUtlFillDgnParams(inst, dgn, dgnType)
5622 TRC2(rgSCHUtlFillDgnParams)
5626 case LRG_USTA_DGNVAL_MEM:
5627 dgn->type = (U8) LRG_USTA_DGNVAL_MEM;
5628 dgn->u.mem.region = rgSchCb[inst].rgSchInit.region;
5629 dgn->u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5637 } /* end of rgSCHUtlFillDgnParams */
5639 /***********************************************************
5641 * Func : rgSCHUtlGetPstToLyr
5643 * Desc : Utility Function to get the pst structure to post a message to MAC
5649 * Notes: This function should be called while sending a msg from
5650 * scheduler instance to MAC
5654 **********************************************************/
5656 PUBLIC Void rgSCHUtlGetPstToLyr
5663 PUBLIC Void rgSCHUtlGetPstToLyr (pst, schCb, macInst)
5669 TRC2(rgSCHUtlGetPstToLyr);
5671 /* Only the needed params are filled */
5672 pst->region = schCb->rgSchInit.region;
5673 pst->pool = schCb->rgSchInit.pool;
5674 pst->srcInst = schCb->rgSchInit.inst+RGSCH_INST_START;
5675 pst->srcProcId = schCb->rgSchInit.procId;
5676 pst->dstProcId = schCb->rgSchInit.procId;
5678 pst->dstInst = macInst;
5679 pst->dstEnt = ENTRG;
5680 pst->srcEnt = ENTRG;
5682 pst->prior = PRIOR0;
5684 pst->route = RTESPEC;
5687 } /* end of rgSCHUtlGetPstToLyr */
5689 /** @brief This function fills in the common lc information to be sent to MAC
5693 * Function: rgSCHUtlFillRgInfCmnLcInfo
5694 * @param RgSchDlSf *sf,
5695 * @param RgInfSfAlloc *sfAlloc,
5696 * @param CmLteLcId lcId,
5697 * @param Bool sendInd
5704 PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo
5707 RgInfSfAlloc *sfAlloc,
5712 PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo(sf, sfAlloc, lcId, sendInd)
5714 RgInfSfAlloc *sfAlloc;
5719 TRC2(rgSCHUtlFillRgInfCmnLcInfo);
5721 if((sf->bch.tbSize)&&
5722 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCH_INFO))
5725 sfAlloc->cmnLcInfo.bchInfo.lcId = lcId;
5727 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCH_INFO;
5729 else if((sf->bcch.pdcch != NULLP)&&
5730 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCCH_INFO))
5732 sfAlloc->cmnLcInfo.bcchInfo.rnti = RGSCH_SI_RNTI;
5733 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.bcchInfo.dciInfo),
5734 &(sf->bcch.pdcch->dci));
5736 sfAlloc->cmnLcInfo.bcchInfo.lcId = lcId;
5737 sfAlloc->cmnLcInfo.bcchInfo.sndStatInd = sendInd;
5739 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCCH_INFO;
5741 else if((sf->pcch.pdcch != NULLP) &&
5742 !(sfAlloc->cmnLcInfo.bitMask & RGINF_PCCH_INFO))
5744 sfAlloc->cmnLcInfo.pcchInfo.rnti = RGSCH_P_RNTI;
5745 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.pcchInfo.dciInfo),
5746 &(sf->pcch.pdcch->dci));
5747 sfAlloc->cmnLcInfo.pcchInfo.lcId = lcId;
5748 sfAlloc->cmnLcInfo.bitMask |= RGINF_PCCH_INFO;
5753 /** @brief This function fills in the RAR information to be sent to MAC
5757 * Function: rgSCHUtlFillRgInfRarInfo
5759 * @param RgSchCellCb *cell
5760 * @param RgSchDlSf *sf
5761 * @param RgInfSfAlloc *sfAlloc
5767 PUBLIC S16 rgSCHUtlFillRgInfRarInfo
5770 RgInfSfAlloc *sfAlloc,
5774 PUBLIC S16 rgSCHUtlFillRgInfRarInfo(sf, sfAlloc, cell)
5776 RgInfSfAlloc *sfAlloc;
5785 RgInfRaRntiInfo *raRntiAlloc;
5787 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5789 TRC2(rgSCHUtlFillRgInfRarInfo);
5792 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
5794 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
5797 for(idx =0; idx < noRaRsps; idx++)
5799 if (sf->raRsp[idx].pdcch == NULLP)
5801 /* No further raResp Allocations. */
5804 /* Added Dl TB count for RACH Response transmission*/
5806 cell->dlUlTbCnt.tbTransDlTotalCnt++;
5808 raRntiAlloc = &(sfAlloc->rarInfo.raRntiInfo[idx]);
5809 raRntiAlloc->raRnti = sf->raRsp[idx].raRnti;
5810 raRntiAlloc->schdTbSz = sf->raRsp[idx].tbSz;
5811 raRntiAlloc->numCrnti = 0;
5812 rgSCHUtlFillPdschDciInfo(&(raRntiAlloc->dciInfo),
5813 &(sf->raRsp[idx].pdcch->dci));
5814 /* RACHO : fill backoff indicator information */
5815 raRntiAlloc->backOffInd = sf->raRsp[idx].backOffInd;
5817 /* Fill for contention free UEs*/
5818 lnkLst = &(sf->raRsp[idx].contFreeUeLst);
5819 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5822 ue = (RgSchUeCb *)tmp->node;
5824 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = ue->ueId;
5825 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = TRUE;
5826 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = ue->ul.rarGrnt.rapId;
5827 #ifndef MAC_5GTF_UPDATE
5828 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5830 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit =
5831 ue->ul.rarGrnt.cqiReqBit;
5833 /* SHASHAHNK ADD RIV CALC */
5834 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5835 ue->ul.rarGrnt.rbStart;
5836 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5837 ue->ul.rarGrnt.numRb;
5838 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5840 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5841 ue->ul.rarGrnt.iMcsCrnt;
5842 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta = ue->ul.rarGrnt.ta;
5843 raRntiAlloc->numCrnti++;
5844 cmLListDelFrm(lnkLst, &ue->ul.rarGrnt.raRspLnk);
5845 ue->ul.rarGrnt.raRspLnk.node = (PTR)NULLP;
5847 /* Fill for contention based UEs*/
5848 lnkLst = &(sf->raRsp[idx].raRspLst);
5850 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5852 while((NULLP != tmp) && ((RgSchRaCb *)tmp->node != NULLP))
5854 raCb = (RgSchRaCb *)tmp->node;
5856 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = raCb->tmpCrnti;
5857 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = FALSE;
5858 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = raCb->rapId;
5859 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.pres = TRUE;
5860 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.val = raCb->ta.val;
5861 #ifndef MAC_5GTF_UPDATE
5862 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5864 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = FALSE;
5866 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5867 raCb->msg3Grnt.rbStart;
5868 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5869 raCb->msg3Grnt.numRb;
5870 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5872 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5873 raCb->msg3Grnt.iMcsCrnt;
5874 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.delayBit =
5875 raCb->msg3Grnt.delayBit;
5876 /* For initial attaching UEs Aperiodic CQI need not be triggered */
5877 raRntiAlloc->numCrnti++;
5878 /* Search the next node */
5879 CM_LLIST_NEXT_NODE(lnkLst, tmp);
5882 sfAlloc->rarInfo.numRaRntis = idx;
5883 /* ccpu00132314-ADD-Update the tx power allocation info
5884 TODO-Need to add a check for max tx power per symbol */
5885 sfAlloc->rarInfo.txPwrOffset = cellDl->rarTxPwrOffset;
5888 } /* end of rgSCHUtlFillRgInfRarInfo */
5890 /** @brief This function fills in the pdsch data related allocation Info
5891 * from the pdcch DCI info.
5896 * Function: rgSCHUtlFillPdschDciInfo
5899 * - Depending upon the DCI Format, fill the appropriate fields.
5901 * @param [out] TfuPdschDciInfo *pdschDci
5902 * @param [in] TfuDciInfo *pdcchDci
5908 PUBLIC S16 rgSCHUtlFillPdschDciInfo
5910 TfuPdschDciInfo *pdsch,
5911 TfuDciInfo *pdcchDci
5914 PUBLIC S16 rgSCHUtlFillPdschDciInfo(pdsch, pdcchDci)
5915 TfuPdschDciInfo *pdsch;
5916 TfuDciInfo *pdcchDci;
5919 TRC2(rgSCHUtlFillPdschDciInfo)
5924 pdsch->format = pdcchDci->dciFormat;
5925 switch(pdcchDci->dciFormat)
5927 case TFU_DCI_FORMAT_1:
5928 pdsch->u.format1AllocInfo = pdcchDci->u.format1Info.allocInfo;
5930 case TFU_DCI_FORMAT_1A:
5931 if (pdcchDci->u.format1aInfo.isPdcchOrder == FALSE)
5933 pdsch->u.format1aAllocInfo = pdcchDci->u.format1aInfo.t.pdschInfo.allocInfo;
5936 case TFU_DCI_FORMAT_1B:
5937 pdsch->u.format1bAllocInfo = pdcchDci->u.format1bInfo.allocInfo;
5939 case TFU_DCI_FORMAT_1C:
5940 pdsch->u.format1cAllocInfo = pdcchDci->u.format1cInfo;
5942 case TFU_DCI_FORMAT_1D:
5943 pdsch->u.format1dAllocInfo = pdcchDci->u.format1dInfo.allocInfo;
5945 case TFU_DCI_FORMAT_2:
5946 pdsch->u.format2AllocInfo = pdcchDci->u.format2Info.allocInfo;
5948 case TFU_DCI_FORMAT_2A:
5949 pdsch->u.format2AAllocInfo = pdcchDci->u.format2AInfo.allocInfo;
5952 case TFU_DCI_FORMAT_B1:
5953 pdsch->u.formatB1Info = pdcchDci->u.formatB1Info;
5955 case TFU_DCI_FORMAT_B2:
5956 pdsch->u.formatB2Info = pdcchDci->u.formatB2Info;
5961 ret = rgSCHEmtcUtlFillPdschDciInfo(pdsch, pdcchDci);
5973 /* LTE_ADV_FLAG_REMOVED_START */
5975 * @brief This function resets temporary variables in Pool
5978 * Function: rgSchSFRResetPoolVariables
5980 * Invoked by: rgSCHSFRUtlTotalPoolInit
5982 * @param[in] RgSchCellCb* cell
5983 * @param[in] RgSubFrm* subFrm
5988 PUBLIC Void rgSchDSFRPwrCheck
5991 Bool *isAllUePwrHigh
5994 PRIVATE Void rgSchDSFRPwrCheck(sf, isAllUePwrHigh)
5996 Bool *isAllUePwrHigh;
6000 RgSchSFRPoolInfo *sfrCCPool;
6005 TRC2(rgSchDSFRPwrCheck);
6007 l = &sf->sfrTotalPoolInfo.ccPool;
6008 n = cmLListFirst(l);
6011 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
6012 if((sfrCCPool->poolstartRB == sfrCCPool->pwrHiCCRange.startRb) &&
6013 (sfrCCPool->poolendRB == sfrCCPool->pwrHiCCRange.endRb))
6020 *isAllUePwrHigh = TRUE;
6027 /* LTE_ADV_FLAG_REMOVED_END */
6028 /***********************************************************
6030 * Func : rgSCHUtlFillRgInfTbInfo
6032 * Desc : Utility Function to fill the allocation info of each Tb
6038 * Notes: This function should be called while sending a msg from
6039 * scheduler instance to MAC
6043 **********************************************************/
6045 PRIVATE Void rgSCHUtlFillRgInfTbInfo
6047 RgSchDlHqProcCb *hqP,
6048 RgInfUeAlloc *allocInfo,
6052 PRIVATE Void rgSCHUtlFillRgInfTbInfo (hqP, allocInfo, cell)
6053 RgSchDlHqProcCb *hqP;
6054 RgInfUeAlloc *allocInfo;
6060 RgInfUeTbInfo *tbInfo;
6062 /* LTE_ADV_FLAG_REMOVED_START */
6064 PRIVATE U32 tmpCnt = 0;
6065 Bool isAllUePwrHigh = FALSE;
6067 /* LTE_ADV_FLAG_REMOVED_END */
6068 RgSchDlLcCb *dlLcCb = NULLP;
6077 CmLteTimingInfo frm;
6079 /* Get Downlink Subframe */
6080 frm = cell->crntTime;
6081 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
6082 sf = rgSCHUtlSubFrmGet(cell, frm);
6083 /* Setting of fillCtrlPdu flag
6084 If both P-cell and S-cell are present,
6085 make TRUE for P-cell and FALSE for all s-cells
6086 For all other cases set TRUE */
6088 if ((rgSchCb[cell->instIdx].genCfg.forceCntrlSrbBoOnPCel) &&
6089 !RG_SCH_CMN_IS_PCELL_HQP(hqP))
6091 allocInfo->fillCtrlPdu = FALSE;
6095 allocInfo->fillCtrlPdu = TRUE;
6099 allocInfo->tbStrtIdx = -1;
6103 allocInfo->tbReqInfo.sCellHqPId = 0xff;
6104 rgSCHLaaHndlFillRgInfTbInfo(cell, hqP, allocInfo);
6107 /*TODO:REEMA: Check and fill the isRetx */
6108 for(tbCnt = 0; tbCnt < 2; tbCnt++)
6110 RgSchUeCb *ue = NULLP;
6111 /*Changed as a result of CR timer*/
6112 if ((hqP->hqE->ue != NULLP)/* &&
6113 ((hqP->tbInfo[tbCnt].lchSchdData[0].lcId != 0) || \
6114 (hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF))*/)
6117 allocInfo->rnti = ue->ueId;
6118 allocInfo->doa = hqP->hqE->ue->mimoInfo.doa;
6119 allocInfo->txMode = (TfuTxMode)(hqP->hqE->ue->mimoInfo.txMode);
6120 allocInfo->puschRptUsd = hqP->hqE->ue->mimoInfo.puschFdbkVld;
6121 allocInfo->puschPmiInfo = hqP->hqE->ue->mimoInfo.puschPmiInfo;
6122 if(hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF)
6124 hqP->tbInfo[tbCnt].taSnt = TRUE;
6127 if (RG_SCH_IS_PAPRSNT(ue,hqP->hqE->cell))
6129 /*update pA value */
6130 allocInfo->pa = (RG_SCH_CMN_GET_PA(ue,hqP->hqE->cell)).val;
6134 /* LTE_ADV_FLAG_REMOVED_START */
6135 /* If ABS is enabled, calculate resource used */
6136 if((0 == tbCnt) && (RGR_ENABLE == ue->cell->lteAdvCb.absCfg.status))
6138 /* For Macro count number resource used in Non-ABS SF */
6139 if(RGR_ABS_MUTE == ue->cell->lteAdvCb.absCfg.absPatternType)
6141 if(RG_SCH_ABS_ENABLED_NONABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6143 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6144 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6147 /* For pico count number resource used in ABS SF for ABS UE */
6148 else if(RGR_ABS_TRANSMIT == ue->cell->lteAdvCb.absCfg.absPatternType)
6150 if(RG_SCH_ABS_ENABLED_ABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6152 if(TRUE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe)
6154 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6155 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6162 /*if SFR is enabled*/
6163 allocInfo->isEnbSFR = (U8)RG_SCH_CMN_IS_SFR_ENB(ue->cell); /* KW fix for LTE_ADV */
6164 if((ue->cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) &&
6165 (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == FALSE))
6167 rgSchDSFRPwrCheck(sf, &isAllUePwrHigh);
6171 allocInfo->pa = (U8)ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; /* KW fix for LTE_ADV */
6172 if(tmpCnt++ == 100000)
6174 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6175 "DSFR::ll UEs can go HIGH, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6181 if (allocInfo->isEnbSFR)
6183 /*Update pA to Plow if it is cell-centred ,else pA will be pHigh*/
6184 if (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == TRUE)
6186 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6187 if(tmpCnt++ == 100000)
6189 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6190 "SFR::UE is CELL EDGE, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6197 if(TRUE == ue->lteAdvUeCb.isCCUePHigh)
6199 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6200 ue->lteAdvUeCb.isCCUePHigh = FALSE;
6204 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pLow;
6205 if(tmpCnt++ == 100000)
6207 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6208 "SFR::UE is CELL CENTRE, PLow(%d) for UE(%d)\n",allocInfo->pa, ue->ueId);
6215 /* LTE_ADV_FLAG_REMOVED_END */
6223 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
6226 allocInfo->pdcchRnti = hqP->hqE->raCb->tmpCrnti;
6228 allocInfo->rnti = hqP->hqE->raCb->tmpCrnti;
6230 /*ccpu00132314-ADD-Use a default pA value
6232 allocInfo->pa = cellDl->msg4pAVal;
6236 /* If TB Is scheduled for this SF */
6237 if(hqP->tbInfo[tbCnt].state == HQ_TB_WAITING)
6239 if (allocInfo->tbStrtIdx == -1){
6240 allocInfo->tbStrtIdx = tbCnt;
6242 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6243 &(hqP->pdcch->dci));
6247 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6248 &(hqP->pdcch->dci));
6250 else if ((ue) && (ue->dl.spsOccPdcch.rnti == ue->spsRnti))
6252 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6253 &(ue->dl.spsOccPdcch.dci));
6255 #endif /* ifndef LTEMAC_SPS */
6260 allocInfo->pdcchRnti = hqP->pdcch->rnti;
6264 allocInfo->pdcchRnti = ue->spsRnti;
6267 tbInfo = &(allocInfo->tbInfo[tbCnt]);
6268 allocInfo->nmbOfTBs++;
6269 allocInfo->hqProcId = hqP->procId;
6270 allocInfo->tbInfo[tbCnt].schdTbSz = hqP->tbInfo[tbCnt].tbSz;
6272 tbInfo->disTb = FALSE;
6273 if(!(hqP->tbInfo[tbCnt].txCntr))
6276 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6277 rgSCHLaaSCellEnabled(cell))))
6280 hqP->tbInfo[tbCnt].txCntr++;
6282 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6284 tbInfo->schdDat[idx].lcId =\
6285 hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6286 tbInfo->schdDat[idx].numBytes =\
6287 hqP->tbInfo[tbCnt].lchSchdData[idx].schdData;
6290 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6293 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6296 RG_SCH_CMN_DL_GET_HDR_EST(dlLcCb, rlcHdrEstmt);
6297 /* Update the totalBo with the scheduled bo */
6298 (hqP->hqE->ue->totalBo <= tbInfo->schdDat[idx].numBytes - rlcHdrEstmt)?\
6299 (hqP->hqE->ue->totalBo = 0):\
6300 (hqP->hqE->ue->totalBo -= tbInfo->schdDat[idx].numBytes-rlcHdrEstmt);
6304 prbUsed = ((hqP->tbInfo[tbCnt].\
6305 lchSchdData[idx].schdData *
6306 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6307 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6308 dlLcCb->qciCb->dlPrbCount += prbUsed;
6309 if(dlLcCb->qciCb->qci > 0)
6311 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6313 #endif /* RRM_RBC_Y */
6316 //if(!(hqP->hqE->ue->pfsStats.lcStats[lcId-1].isLcCntSet))
6320 if (hqP->hqE->ue->cell == hqP->hqE->cell)
6322 idx = RGSCH_PCELL_INDEX;
6326 idx = RG_SCH_GET_SCELL_INDEX((hqP->hqE->ue), (hqP->hqE->cell));
6328 hqP->hqE->ue->pfsStats.lcStats[lcId-1].ueSchdOcc[idx]++;
6329 hqP->hqE->ue->pfsStats.lcStats[lcId-1].perRefresh[ue->pfsStats.lcStats[lcId-1].lastIdx].lcSchdOcc++;
6336 /* Added Dl TB count for SRB/DRB data transmission*/
6338 cell->dlUlTbCnt.tbTransDlTotalCnt++;
6340 tbInfo->ta.pres = hqP->tbInfo[tbCnt].schdTa.pres;
6341 tbInfo->ta.val = hqP->tbInfo[tbCnt].schdTa.val;
6343 tbInfo->sCellActCe = hqP->tbInfo[tbCnt].schdSCellActCe;
6345 tbInfo->numSchLch = hqP->tbInfo[tbCnt].numLch;
6346 if(!(hqP->tbInfo[tbCnt].numLch))
6348 tbInfo->schdDat[tbInfo->numSchLch].numBytes= hqP->tbInfo[tbCnt].tbSz;
6349 /* Fix: If only TA is scheduled, use some dummy LCID */
6350 if (tbInfo->ta.pres)
6351 tbInfo->schdDat[tbInfo->numSchLch].lcId = RG_TA_LCID;
6354 tbInfo->contResCe = hqP->tbInfo[tbCnt].contResCe;
6355 tbInfo->isReTx = FALSE;
6360 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6361 rgSCHLaaSCellEnabled(cell))))
6364 hqP->tbInfo[tbCnt].txCntr++;
6366 tbInfo->isReTx = TRUE;
6368 /* As per 36.314, harq retransmission also considered for
6369 * prb utilization calculation*/
6370 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6375 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6378 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6381 prbUsed = ((hqP->tbInfo[tbCnt].\
6382 lchSchdData[idx].schdData *
6383 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6384 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6385 if(dlLcCb->qciCb->qci > 0)
6387 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6399 rgSCHLaaResetDlHqProcCb(hqP);
6404 /***********************************************************
6406 * Func : rgSCHUtlFillRgInfUeInfo
6408 * Desc : Utility Function to fill the allocation info of Ue
6409 * : MIMO : Filling 2TB's of each UE
6414 * Notes: This function should be called while sending a msg from
6415 * scheduler instance to MAC
6419 **********************************************************/
6422 PUBLIC Void rgSCHUtlFillRgInfUeInfo
6426 CmLListCp *dlDrxInactvTmrLst,
6427 CmLListCp *dlInActvLst,
6428 CmLListCp *ulInActvLst
6431 PUBLIC Void rgSCHUtlFillRgInfUeInfo (sf,cell, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
6435 CmLListCp *dlDrxInactvTmrLst;
6436 CmLListCp *dlInActvLst;
6437 CmLListCp *ulInActvLst;
6440 RgInfSfAlloc *sfAlloc;
6441 CmLListCp *lnkLst; /* lnkLst assignment */
6444 RgSchUeCb *ue = NULLP;
6445 RgInfUeInfo *ueInfo = NULLP;
6446 RgInfUeAlloc *ueAlloc = NULLP;
6447 RgSchDlHqProcCb *hqCb = NULLP;
6449 /* Since Msg4 is sched only on PCELL, use cell arg's sfAllocArr */
6450 sfAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
6451 ueInfo = &(sfAlloc->ueInfo);
6452 ueAlloc = sfAlloc->ueInfo.allocInfo;
6454 lnkLst = &(sf->msg4HqPLst);
6455 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6458 printf("5GTF_ERROR MSG4 Consolidation\n");
6459 hqCb = (RgSchDlHqProcCb *)(tmp->node);
6460 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6462 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], cell);
6468 if((!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) && (ue->isDrxEnabled))
6470 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6471 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6477 lnkLst = &(sf->ueLst);
6478 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6481 #if defined (TENB_STATS) && defined (RG_5GTF)
6482 cell->tenbStats->sch.dl5gtfPdschCons++;
6484 ue = (RgSchUeCb *)(tmp->node);
6485 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6487 hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first;
6490 hqCb = (RgSchDlHqProcCb *)hqPNode->node;
6491 hqPNode = hqPNode->next;
6493 sfAlloc = &(hqCb->hqE->cell->sfAllocArr[hqCb->hqE->cell->crntSfIdx]);
6494 ueInfo = &(sfAlloc->ueInfo);
6495 ueAlloc = sfAlloc->ueInfo.allocInfo;
6497 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes],
6500 if(ue->isDrxEnabled)
6502 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6503 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6508 if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE)
6510 /*If remaining BO is left then increment the count*/
6514 /* Check if trigger for Activation is met or not */
6515 if(rgSCHIsActvReqd(cell, ue))
6518 /*Passing primary cell*/
6519 rgSCHSCellSelectAndActDeAct(ue->cell, ue, RGR_SCELL_ACT);
6524 /*If remaining BO is 0 then reset the count*/
6532 } /* end of rgSCHUtlFillRgInfUeInfo */
6536 /** @brief This function shall update the scheduler with the CEs and data rcvd
6540 * Function: rgSCHUtlUpdSch
6543 * - Collate the information of all the SDUs received and inform the
6544 * scheduler rgSCHDataRcvd
6545 * - Send Data indication to the higher layer with the dedicated data
6546 * (rgUIMSndDedDatInd)
6547 * - Inform scheduler with any MAC CEs if present.
6549 * @param [in] RgCellCb *cellCb
6550 * @param [in] RgUeCb *ueCb
6551 * @param [in] RgMacPdu *pdu
6552 * @param [in] RgSchErrInfo *err
6558 PUBLIC S16 rgSCHUtlUpdSch
6560 RgInfSfDatInd *subfrmInfo,
6561 RgSchCellCb *cellCb,
6567 PUBLIC S16 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err)
6568 RgInfSfDatInd *subfrmInfo;
6569 RgSchCellCb *cellCb;
6577 TRC2(rgSCHUtlUpdSch);
6580 if (RGSCH_UL_SPS_ACT_PRSENT & pdu->ceInfo.bitMask)
6582 /* SPS to be activated due to data on SPS LCG ID*/
6583 rgSCHUtlSpsActInd(cellCb, ueCb, pdu->ceInfo.spsSduSize);
6586 /* TODO : Temp Fix for crash due to UL SDU corruption*/
6587 if (RGSCH_PHR_CE_PRSNT & pdu->ceInfo.bitMask)
6590 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6591 if ((ret = rgSCHUtlUpdPhr(cellCb, ueCb, pdu->ceInfo.ces.phr, err)) != ROK)
6594 /* Note: Order of indication to Sch now is
6595 * 1st Indicate the DataInd info for each LCG's
6596 * 2nd Update the BSR reports received along with data
6597 * this is to make sure the effBsr is updated to the latest BSR
6600 cellCb->sc.apis->rgSCHUpdUeDataIndLcg(cellCb, ueCb, pdu);
6602 #ifndef MAC_5GTF_UPDATE
6603 if (RGSCH_TRUNC_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6605 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6606 /*ccpu00129922 - MOD - Deleted return value
6607 * checking since it returns void*/
6608 rgSCHUtlUpdBsrTrunc (cellCb, ueCb,
6609 (U8)(pdu->ceInfo.ces.bsr.truncBsr >> 6),
6610 (U8)(pdu->ceInfo.ces.bsr.truncBsr & 0x3F), err);
6614 if (RGSCH_SHORT_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6616 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6617 /*ccpu00129922 - MOD - Deleted return value
6618 checking since it returns void*/
6619 rgSCHUtlUpdBsrShort (cellCb, ueCb,
6620 (U8)(pdu->ceInfo.ces.bsr.shortBsr >> 6),
6621 (U8)(pdu->ceInfo.ces.bsr.shortBsr & 0x3F), err);
6625 if (RGSCH_LONG_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6627 if (RGSCH_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6630 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6631 /*ccpu00129922 - MOD - Deleted return value
6632 checking since it returns void*/
6633 rgSCHUtlUpdBsrLong (cellCb, ueCb,
6634 pdu->ceInfo.ces.bsr.longBsr.bs1,
6635 pdu->ceInfo.ces.bsr.longBsr.bs2,
6636 pdu->ceInfo.ces.bsr.longBsr.bs3,
6637 pdu->ceInfo.ces.bsr.longBsr.bs4,
6640 #ifndef MAC_5GTF_UPDATE
6647 } /* end of rgSCHUtlUpdSch */
6650 * @brief Handler for Updating Bo received in StaRsp
6654 * Function : rgSCHUtlAddUeToCcchSduLst
6656 * This function shall be invoked once it receives staRsp on CCCH
6658 * @param[in] RgSchCellCb *cell
6659 * @param[in] RgSchUeCb *ueCb
6664 PUBLIC S16 rgSCHUtlAddUeToCcchSduLst
6670 PUBLIC S16 rgSCHUtlAddUeToCcchSduLst(cell, ueCb)
6675 RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb, cell);
6676 RgSchDlHqProcCb *hqP = (RgSchDlHqProcCb *)ueDl->proc;
6677 TRC2(rgSCHUtlAddUeToCcchSduLst);
6679 /* Temp Guard: For back to back CCCH SDU BO
6680 * twice. Hence an extra guard. If already added to scheduling
6681 * queue or if scheduled and waiting for HQ FDBK, ignore */
6682 if ((ueCb->ccchSduLnk.node) ||
6683 ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
6684 ((hqP != NULLP) && (hqP->hqE->ccchSduProc))))
6686 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unexpected CCCH SDU BO",
6691 ueCb->ccchSduLnk.node = (PTR)(ueCb);
6692 cmLListAdd2Tail(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
6700 * Function : rgSCHUtlUpdtBo
6702 * This function shall be invoked once it receives staRsp on CCCH
6704 * @param[in] RgSchCellCb *cell
6705 * @param[in] RgRguCmnStaRsp *staRsp
6710 PUBLIC S16 rgSCHUtlUpdtBo
6713 RgInfCmnBoRpt *staRsp
6716 PUBLIC S16 rgSCHUtlUpdtBo(cell, staRsp)
6718 RgInfCmnBoRpt *staRsp;
6722 TRC2(rgSCHUtlUpdtBo)
6725 if ((ueCb = rgSCHDbmGetUeCb(cell, staRsp->u.rnti)) == NULLP)
6727 /* Handle Ue fetch failure */
6728 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid UEID:%d",staRsp->u.rnti);
6731 /* Update Bo in ueCb */
6732 ueCb->dlCcchInfo.bo = (U32)(staRsp->bo);
6736 rgSCHUtlAddUeToEmtcCcchSduLst(cell,ueCb);
6741 rgSCHUtlAddUeToCcchSduLst(cell, ueCb);
6745 } /* rgSCHUtlUpdtBo */
6751 * Function : rgSCHUtlHndlCcchBoUpdt
6753 * This function shall fetch the raCb with the given rnti and ask RAM to
6757 * @param[in] RgSchCellCb *cell
6758 * @param[in] RgInfCmnBoRpt *boRpt
6764 PUBLIC S16 rgSCHUtlHndlCcchBoUpdt
6767 RgInfCmnBoRpt *boRpt
6770 PUBLIC S16 rgSCHUtlHndlCcchBoUpdt(cell, boRpt)
6772 RgInfCmnBoRpt *boRpt;
6778 TRC2(rgSCHUtlHndlCcchBoUpdt);
6780 if ((raCb = rgSCHDbmGetRaCb(cell, boRpt->u.rnti)) == NULLP)
6783 /* CR timer implementation changes*/
6784 /*If no raCb, schedule ueCb, ueCb is extracted in rgSCHUtlUpdtBo*/
6785 RETVALUE(rgSCHUtlUpdtBo(cell, boRpt));
6787 /* Handle RaCb fetch failure */
6788 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6789 "Invalid RNTI:%d to fetch raCb",boRpt->u.rnti);
6796 /*Fix: If RaCb exists, then MSG4 is not completed yet*/
6797 /*Check if guard timer has expired, if not CR CE + CCCH SDU will be scheduled*/
6798 if((raCb->contResTmrLnk.node != NULLP) && \
6799 (raCb->schdLnk.node == NULLP) && (raCb->dlHqE->msg4Proc == NULLP))
6802 /*if contention resolution timer left ,Stop the Contention Resolution Guard Timer ,
6803 add in toBeSchduled list and update the Bo */
6804 if(TRUE == raCb->isEmtcRaCb)
6806 rgSCHRamEmtcUpdtBo(cell, raCb, boRpt);
6811 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
6812 raCb->contResTmrLnk.node=NULLP;
6813 rgSCHRamUpdtBo(cell, raCb, boRpt);
6818 /*Fix:Guard timer has expired */
6819 /*Update the BO in UE CB but dont add it to the scheduling list.
6820 *Should be added to the list after MSG4 completion*/
6821 if ((ueCb = rgSCHDbmGetUeCb(cell, boRpt->u.rnti)) == NULLP)
6823 /* Handle Ue fetch failure */
6824 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RNTI:%d",boRpt->u.rnti);
6827 /* Update Bo in ueCb */
6828 ueCb->dlCcchInfo.bo = (U32)(boRpt->bo);
6832 rgSCHRamUpdtBo(cell, raCb, boRpt);
6836 } /* rgSCHUtlHndlCcchBoUpdt */
6839 * @brief Validates BO received for BCCH or PCCH.
6843 * Function : rgSCHUtlGetAllwdCchTbSz
6845 * This function shall return the tbSz equal to or
6846 * the nearest greater value for a given bo.
6847 * If no such value found return -1. The nPrb value is
6852 * @param[out] U8 *nPrb
6858 PUBLIC S32 rgSCHUtlGetAllwdCchTbSz
6865 PUBLIC S32 rgSCHUtlGetAllwdCchTbSz(bo, nPrb, mcs)
6875 TRC2(rgSCHUtlGetAllwdCchTbSz);
6877 for (lt = 0, rt = 43; lt <= rt;)
6880 if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz == bo)
6882 *nPrb = rgSchUtlBcchPcchTbSzTbl[cn].rbIndex;
6883 *mcs = rgSchUtlBcchPcchTbSzTbl[cn].mcs;
6884 RETVALUE(rgSchUtlBcchPcchTbSzTbl[cn].tbSz);
6886 else if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz < bo)
6895 *nPrb = rgSchUtlBcchPcchTbSzTbl[lt].rbIndex;
6896 *mcs = rgSchUtlBcchPcchTbSzTbl[lt].mcs;
6897 RETVALUE(rgSchUtlBcchPcchTbSzTbl[lt].tbSz);
6901 * @brief Handler for BO Updt received for BCCH or PCCH.
6905 * Function : rgSCHUtlHndlBcchPcchBoUpdt
6907 * This function shall store the buffer and time to transmit in lcCb
6910 * @param[in] RgSchCellCb *cell
6911 * @param[in] RgInfCmnBoRpt *boRpt
6917 PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt
6920 RgInfCmnBoRpt *boUpdt
6923 PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt(cell, boUpdt)
6925 RgInfCmnBoRpt *boUpdt;
6928 RgSchClcDlLcCb *dlLc;
6929 RgSchClcBoRpt *boRpt;
6930 Inst inst = cell->instIdx;
6934 TRC2(rgSCHUtlHndlBcchPcchBoUpdt);
6936 dlLc = rgSCHDbmGetBcchOnBch(cell);
6939 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6940 "No Logical Channel dlLc is NULLP for RNTI:%d LCID:%d",boUpdt->u.rnti,boUpdt->lcId);
6943 if (boUpdt->lcId != dlLc->lcId)
6945 /* Added for dropping paging Message*/
6947 if ((rgSCHChkBoUpdate(cell,boUpdt))== ROK) /* Checking if received BO falls within the window of 5120 subframes*/
6949 if (rgSCHUtlGetAllwdCchTbSz(boUpdt->bo*8, &nPrb, &mcs)
6952 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"[%ld]BO: does not match any "
6953 "valid TB Size RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6956 }/*end of rgSCHChkBoUpdate*/
6962 if ((dlLc = rgSCHDbmGetCmnLcCb(cell, boUpdt->lcId)) == NULLP)
6964 /* Handle lcCb fetch failure */
6965 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6966 "LCID:%d Invalid for RNTI:%d",boUpdt->lcId,boUpdt->u.rnti);
6969 if (((rgSCHUtlAllocSBuf(inst, (Data **)(&boRpt), sizeof(RgSchClcBoRpt))) ==RFAILED) ||
6972 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, "Allocation of common bo %dreport "
6973 "failed RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6977 boRpt->bo = boUpdt->bo;
6979 boRpt->timeToTx = boUpdt->u.timeToTx;
6982 if(cell->emtcEnable)
6984 boRpt->emtcDIReason = boUpdt->emtcDIReason;
6985 boRpt->pnb = boUpdt->pnb;
6988 RG_SCH_ADD_TO_CRNT_TIME(boRpt->timeToTx,
6989 boRpt->maxTimeToTx, cell->siCfg.siWinSize)
6990 if((NULLP != dlLc) && (dlLc->si))
6992 boRpt->retxCnt = cell->siCfg.retxCnt;
6998 rgSCHDbmInsCmnLcBoRpt(dlLc, boRpt);
7001 } /* rgSCHUtlHndlBcchPcchBoUpdt */
7004 * @brief API for sending bind confirm from Scheduler instance to RRM
7008 * Function: rgSCHUtlRgrBndCfm
7010 * This API is invoked to send bind confirm from Scheduler instance to RRM.
7011 * This API fills in Pst structure and SAP Ids and invokes
7012 * bind confirm API towards RRM.
7014 * @param[in] SuId suId
7015 * @param[in] U8 status
7021 PUBLIC S16 rgSCHUtlRgrBndCfm
7028 PUBLIC S16 rgSCHUtlRgrBndCfm(instId, suId, status)
7036 TRC2(rgSCHUtlRgrBndCfm)
7039 ret = RgUiRgrBndCfm(&rgSchCb[instId].rgrSap[suId].sapCfg.sapPst, rgSchCb[instId].rgrSap[suId].sapCfg.suId, status);
7042 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrBndCfm: RgUiRgrBndCfm Failed ");
7046 } /* rgSCHUtlRgrBndCfm*/
7049 * @brief API for sending bind confirm from Scheduler instance to RRM via RGM
7054 * Function: rgSCHUtlRgmBndCfm
7056 * This API is invoked to send bind confirm from Scheduler instance to RRM.
7057 * This API fills in Pst structure and SAP Ids and invokes
7059 * @param[in] SuId suId
7060 * @param[in] U8 status
7066 PUBLIC S16 rgSCHUtlRgmBndCfm
7073 PUBLIC S16 rgSCHUtlRgmBndCfm(instId, suId, status)
7081 TRC2(rgSCHUtlRgmBndCfm)
7084 ret = RgUiRgmBndCfm(&rgSchCb[instId].rgmSap[suId].sapCfg.sapPst, rgSchCb[instId].rgmSap[suId].sapCfg.suId, status);
7087 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgmBndCfm: RgUiRgrBndCfm Failed ");
7091 } /* rgSCHUtlRgmBndCfm*/
7096 * @brief API for sending configuration confirm from Scheduler to RRM
7100 * Function: rgSCHUtlRgrCfgCfm
7102 * This API is invoked to send configuration confirm from Scheduler to RRM.
7103 * config confirm API towards RRM.
7105 * @param[in] RgrCfgTransId transId
7106 * @param[in] U8 status
7112 PUBLIC S16 rgSCHUtlRgrCfgCfm
7116 RgrCfgTransId transId,
7120 PUBLIC S16 rgSCHUtlRgrCfgCfm(instId, spId, transId, status)
7123 RgrCfgTransId transId;
7127 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
7129 TRC2(rgSCHUtlRgrCfgCfm)
7131 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
7132 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
7135 if(RgUiRgrCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
7136 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
7137 transId, status) != ROK)
7139 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrCfgCfm: RgUiRgrCfgCfm Failed ");
7143 } /* rgSCHUtlRgrCfgCfm */
7146 * @brief API for sending TTI indication from Scheduler to RRM.
7150 * Function: rgSCHUtlRgrTtiInd
7152 * This API is invoked to send TTI indication from Scheduler instance to RRM.
7153 * This API fills in Pst structure and RgrTtiIndInfo
7155 * @param[in] cell RgSchCellCb
7156 * @param[in] CmLteTimingInfo status
7162 PUBLIC S16 rgSCHUtlRgrTtiInd
7165 RgrTtiIndInfo *rgrTti
7168 PUBLIC S16 rgSCHUtlRgrTtiInd(cell, rgrTti)
7170 RgrTtiIndInfo *rgrTti;
7174 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
7176 extern Bool g_usettitmr;
7177 extern Void mtTmrHdlrPublic(void);
7180 TRC2(rgSCHUtlRgrTtiInd)
7183 rgrSap = cell->rgrSap;
7184 if (rgrSap->sapSta.sapState != LRG_BND)
7186 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
7187 "rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ",
7188 rgrSap->sapSta.sapState);
7191 RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst),
7192 cell->rgrSap->sapCfg.suId, rgrTti);
7200 } /* rgSCHUtlRgrTtiInd*/
7202 /** @brief This function is called by rgMacSchSfRecpInd. This function invokes the
7203 * scheduler with the information of the received Data and any Control Elements
7211 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
7213 * - If UE exists then update the Schduler with any MAC CEs if present.
7214 * - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3
7216 * @param [in] RgSchCellCb *cellCb
7217 * @param [in] RgSchUeCb *ueCb
7218 * @param [in] CmLteRnti rnti
7219 * @param [in] RgMacPdu *pdu
7220 * @param [in] RgSchErrInfo *err
7227 PUBLIC S16 rgSCHUtlProcMsg3
7229 RgInfSfDatInd *subfrmInfo,
7230 RgSchCellCb *cellCb,
7237 PUBLIC S16 rgSCHUtlProcMsg3 (subfrmInfo, cellCb, ueCb, rnti, pdu, err)
7238 RgInfSfDatInd *subfrmInfo;
7239 RgSchCellCb *cellCb;
7249 TRC2(rgSCHUtlProcMsg3)
7252 /* must have an raCb for this case */
7253 raCb = rgSCHDbmGetRaCb (cellCb, rnti);
7256 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, "RNTI:%d Received MSG3, unable to "
7261 /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that
7262 * effBsr of current case only will be considered in scheduling of ContResLst*/
7263 ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err);
7266 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Processing failed in the RAM "
7270 /* if ueCb is present */
7273 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err);
7279 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7280 * scheduler with the information of the received Data.
7284 * Function: rgSCHUtlSpsRelInd
7289 * @param [in] RgSchCellCb *cellCb
7290 * @param [in] RgSchUeCb *ueCb
7291 * @param [in] Bool *isExplRel
7298 PUBLIC S16 rgSCHUtlSpsRelInd
7300 RgSchCellCb *cellCb,
7305 PUBLIC S16 rgSCHUtlSpsRelInd (cellCb, ueCb, isExplRel)
7306 RgSchCellCb *cellCb;
7311 TRC2(rgSCHUtlSpsRelInd);
7312 cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel);
7314 } /* end of rgSCHUtlSpsRelInd */
7317 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7318 * scheduler with the information of the received Data.
7322 * Function: rgSCHUtlSpsActInd
7327 * @param [in] RgSchCellCb *cellCb
7328 * @param [in] RgSchUeCb *ueCb
7329 * @param [in] U16 spsSduSize
7336 PUBLIC S16 rgSCHUtlSpsActInd
7338 RgSchCellCb *cellCb,
7343 PUBLIC S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize)
7344 RgSchCellCb *cellCb;
7349 TRC2(rgSCHUtlSpsActInd);
7350 cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize);
7352 } /* end of rgSCHUtlSpsActInd */
7355 #endif /* LTEMAC_SPS */
7359 * @brief This API is invoked to send uplink group power control request to PHY.
7363 * Function : rgSCHUtlTfuGrpPwrCntrlReq
7365 * This API is invoked to send uplink group power control request to PHY.
7366 * It fills in the Pst structure, spId value and invokes group power
7367 * control request primitive at TFU.
7369 * @param[in] TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7375 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq
7379 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7382 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq(inst, sapId, grpPwrCntrlReq)
7385 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq;
7389 RgSchLowSapCb *tfuSap;
7392 TRC2(rgSCHUtlTfuGrpPwrCntrlReq);
7394 /* Get the lower SAP control block from the layer control block. */
7395 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7396 if (tfuSap->sapSta.sapState != LRG_BND)
7398 RLOG_ARG1(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7399 "rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState);
7402 cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
7403 if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK)
7405 RLOG_ARG0(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7406 "rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed");
7409 } /* rgSCHUtlTfuGrpPwrCntrlReq */
7413 * @brief This API is invoked to send Control Info to PHY.
7417 * Function : rgSCHUtlTfuCntrlReq
7419 * This API is invoked to send Control Info to PHY. It
7420 * fills in the Pst structure, spId value and invokes Cntrl
7421 * request primitive at TFU.
7423 * @param[in] TfuCntrlReqInfo *cntrlReq
7429 PUBLIC S16 rgSCHUtlTfuCntrlReq
7433 TfuCntrlReqInfo *cntrlReq
7436 PUBLIC S16 rgSCHUtlTfuCntrlReq(inst, sapId, cntrlReq)
7439 TfuCntrlReqInfo *cntrlReq;
7443 RgSchLowSapCb *tfuSap;
7445 TRC2(rgSCHUtlTfuCntrlReq)
7447 /* Get the lower SAP control block from the layer control block. */
7448 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7451 if (tfuSap->sapSta.sapState != LRG_BND)
7453 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Lower SAP not bound (%d) ",
7454 tfuSap->sapSta.sapState);
7455 RGSCH_FREE_MEM(cntrlReq);
7460 /* Using local variable for pst is unnecessary - for optimization */
7461 if((ret = RgLiTfuCntrlReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7464 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Call to RgLiTfuCntrlReq() failed");
7467 } /* rgSCHUtlTfuCntrlReq*/
7470 /* FOR ACK NACK REP */
7473 * @brief This API is invoked to tell the DL Scheduler to add the UE back into
7474 * its scheduling queues.
7478 * Function : rgSCHUtlDlActvtUe
7480 * This API is invoked from Measurement gap moduled.
7482 * @param[in] RgSchCellCb *cell
7483 * @param[in] RgSchUeCb *ueCb
7490 PUBLIC S16 rgSCHUtlDlActvtUe
7496 PUBLIC S16 rgSCHUtlDlActvtUe(cell, ue)
7501 TRC2(rgSCHUtlDlActvtUe);
7502 cell->sc.apis->rgSCHActvtDlUe(cell, ue);
7507 * @brief This API is invoked to tell the UL Scheduler to add the UE back into
7508 * its scheduling queues.
7512 * Function : rgSCHUtlUlActvtUe
7514 * This API is invoked from Measurement gap moduled.
7516 * @param[in] RgSchCellCb *cell
7517 * @param[in] RgSchUeCb *ueCb
7524 PUBLIC S16 rgSCHUtlUlActvtUe
7530 PUBLIC S16 rgSCHUtlUlActvtUe(cell, ue)
7535 TRC2(rgSCHUtlUlActvtUe);
7536 cell->sc.apis->rgSCHActvtUlUe(cell, ue);
7541 * @brief This API is invoked to send Reception Request Info to PHY.
7545 * Function : rgSCHUtlTfuRecpReq
7547 * This API is invoked to send Reception Request Info to PHY. It
7548 * fills in the Pst structure, spId value and invokes Reception
7549 * request primitive at TFU.
7551 * @param[in] TfuRecpReqInfo *recpReq
7557 PUBLIC S16 rgSCHUtlTfuRecpReq
7561 TfuRecpReqInfo *recpReq
7564 PUBLIC S16 rgSCHUtlTfuRecpReq(inst, sapId, recpReq)
7567 TfuRecpReqInfo *recpReq;
7571 RgSchLowSapCb *tfuSap;
7573 TRC2(rgSCHUtlTfuRecpReq)
7575 /* Get the lower SAP control block from the layer control block. */
7576 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7579 if (tfuSap->sapSta.sapState != LRG_BND)
7581 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Lower SAP not bound (%d) ",
7582 tfuSap->sapSta.sapState);
7583 RGSCH_FREE_MEM(recpReq);
7588 /* Using local variable for pst is unnecessary - for optimization */
7589 if((ret = RgLiTfuRecpReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7592 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Call to RgLiTfuRecpReq() failed");
7595 } /* rgSCHUtlTfuRecpReq */
7597 /** @brief This function Validates the SAP information received along with the
7598 * primitive from the lower layer.
7600 * Function: rgSCHUtlValidateTfuSap
7602 * Validates SAP information.
7603 * @param suId The SAP Id
7609 PUBLIC S16 rgSCHUtlValidateTfuSap
7615 PUBLIC S16 rgSCHUtlValidateTfuSap(inst, suId)
7620 RgSchLowSapCb *tfuSap;
7622 TRC2(rgSCHUtlValidateTfuSap)
7624 if(suId >= rgSchCb[inst].numSaps)
7626 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Incorrect SuId");
7629 tfuSap = &(rgSchCb[inst].tfuSap[suId]);
7631 /* First lets check the suId */
7632 if( suId != tfuSap->sapCfg.suId)
7634 RLOG_ARG2(L_ERROR,DBG_INSTID,inst,"Incorrect SuId. Configured (%d) Recieved (%d)",
7635 tfuSap->sapCfg.suId, suId);
7638 if (tfuSap->sapSta.sapState != LRG_BND)
7640 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"Lower SAP not enabled SuId (%d)",
7641 tfuSap->sapCfg.suId);
7645 } /* end of rgSCHUtlValidateTfuSap */
7649 * Fun: rgSCHUtlAllocEventMem
7651 * Desc: This function allocates event memory
7653 * Ret: ROK - on success
7654 * RFAILED - on failure
7662 PUBLIC S16 rgSCHUtlAllocEventMem
7669 PUBLIC S16 rgSCHUtlAllocEventMem(inst, memPtr, memSize)
7676 VOLATILE U32 startTime=0;
7678 TRC2(rgSCHUtlAllocEventMem)
7680 sMem.region = rgSchCb[inst].rgSchInit.region;
7681 sMem.pool = rgSchCb[inst].rgSchInit.pool;
7683 #if (ERRCLASS & ERRCLS_DEBUG)
7686 RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize,
7687 "rgAllocEventMem(): memSize invalid\n");
7690 #endif /* ERRCLASS & ERRCLS_DEBUG */
7692 SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
7694 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
7695 MS_BUF_ADD_ALLOC_CALLER();
7697 #ifdef TFU_ALLOC_EVENT_NO_INIT
7698 if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7700 if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7703 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed.");
7707 SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
7709 } /* end of rgSCHUtlAllocEventMem*/
7713 * Fun: rgGetEventMem
7715 * Desc: This function allocates event memory
7717 * Ret: ROK - on success
7718 * RFAILED - on failure
7726 PUBLIC S16 rgSCHUtlGetEventMem
7733 PUBLIC S16 rgSCHUtlGetEventMem(ptr, len, memCp)
7741 TRC2(rgSCHUtlGetEventMem)
7742 #ifdef TFU_ALLOC_EVENT_NO_INIT
7743 ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
7745 ret = cmGetMem(memCp, len, (Ptr *)ptr);
7748 } /* end of rgSCHUtlGetEventMem*/
7754 * @brief Handler to allocate memory for ACK/NACk feedback information
7758 * Function : rgSCHUtlAllocUeANFdbkInfo
7760 * It allocates memory for the UE related ACK NACK information.
7762 * @param[in] RgSchUeCb *ue
7766 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo
7772 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx)
7779 TRC2(rgSCHUtlAllocUeANFdbkInfo);
7781 if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
7782 (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
7783 ue->cell->ackNackFdbkArrSize) != ROK)
7788 for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
7790 rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
7793 /* Set it to the first index */
7794 ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
7796 } /* rgSCHUtlAllocUeANFdbkInfo */
7799 * @brief Handler to release memory for ACK/NACk feedback information
7803 * Function : rgSCHUtlDelUeANFdbkInfo
7805 * It releases memory for the UE related ACK NACK information.
7807 * @param[in] RgSchUeCb *ue
7811 PUBLIC Void rgSCHUtlDelUeANFdbkInfo
7817 PUBLIC Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx)
7822 TRC2(rgSCHUtlDelUeANFdbkInfo);
7824 /* ccpu00117052 - MOD - Passing double pointer
7825 for proper NULLP assignment*/
7826 rgSCHUtlFreeSBuf(ue->cell->instIdx,
7827 (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
7828 ue->cell->ackNackFdbkArrSize);
7831 } /* rgSCHUtlDelUeANFdbkInfo */
7834 * @brief Handler to initialise UE ACK/NACk feedback information
7838 * Function : rgSCHUtlInitUeANFdbkInfo
7840 * It initialises UE related ACK NACK information.
7842 * @param[in] RgSchTddANInfo *anFdInfo
7846 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo
7848 RgSchTddANInfo *anFdInfo
7851 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo)
7852 RgSchTddANInfo *anFdInfo;
7855 TRC2(rgSCHUtlInitUeANFdbkInfo);
7857 anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
7858 anFdInfo->subframe = 0;
7859 anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
7860 anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
7861 anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
7864 } /* rgSCHUtlInitUeANFdbkInfo */
7867 * @brief Handler to get UE related ACK NACK feedback information
7871 * Function : rgSCHUtlGetUeANFdbkInfo
7873 * It gets the UE related ACK NACK information based on
7874 * SFN and subframe number.
7876 * @param[in] RgSchUeCb *ueCb
7877 * @param[in] CmLteTimingInfo *time
7878 * @return RgSchTddANInfo*
7881 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo
7884 CmLteTimingInfo *timeInfo,
7888 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx)
7890 CmLteTimingInfo *timeInfo;
7896 TRC2(rgSCHUtlGetUeANFdbkInfo);
7898 for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
7900 if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
7901 (timeInfo->subframe == ueCb->cellInfo[servCellIdx]->anInfo[idx].subframe))
7903 RETVALUE(&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
7908 } /* rgSCHUtlGetUeANFdbkInfo */
7911 * @brief To get downlink subframe index
7915 * Function: rgSCHUtlGetDlSfIdx
7916 * Purpose: Gets downlink subframe index based on SFN and subframe no
7918 * @param[in] CmLteTimingInfo *timeInfo
7919 * @param[in] RgSchCellCb *cell
7924 PUBLIC U8 rgSCHUtlGetDlSfIdx
7927 CmLteTimingInfo *timeInfo
7930 PUBLIC U8 rgSCHUtlGetDlSfIdx(cell, timeInfo)
7932 CmLteTimingInfo *timeInfo;
7936 TRC2(rgSCHUtlGetDlSfIdx);
7938 idx = RGSCH_NUM_SUB_FRAMES - \
7939 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7940 idx = ((idx * timeInfo->sfn) + \
7941 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->subframe]) - 1;
7942 idx = idx % cell->numDlSubfrms;
7948 * @brief To get the next downlink subframe
7952 * Function: rgSCHUtlGetNxtDlSfInfo
7953 * Purpose: Gets next downlink subframe based on current DL subframe
7955 * @param[in] CmLteTimingInfo curDlTime
7956 * @param[in] RgSchCellCb *cell
7957 * @param[in] RgSchDlSf *dlSf
7958 * @param[in] RgSchDlSf **nxtDlsf
7959 * @param[in] CmLteTimingInfo *nxtDlTime
7964 PUBLIC Void rgSCHUtlGetNxtDlSfInfo
7966 CmLteTimingInfo curDlTime,
7969 RgSchDlSf **nxtDlsf,
7970 CmLteTimingInfo *nxtDlTime
7973 PUBLIC Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime)
7974 CmLteTimingInfo curDlTime;
7977 RgSchDlSf **nxtDlsf;
7978 CmLteTimingInfo *nxtDlTime;
7981 U16 idx = curDlTime.subframe;
7983 TRC2(rgSCHUtlGetNxtDlSfInfo);
7989 idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
7991 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
7992 != RG_SCH_TDD_DL_SUBFRAME);
7993 RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
7994 *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
7995 if(dlSf->dlFdbkInfo.subframe != (*nxtDlsf)->dlFdbkInfo.subframe)
8004 * @brief To get the previous downlink subframe
8008 * Function: rgSCHUtlGetPrevDlSfInfo
8009 * Purpose: Gets previous downlink subframe based on current DL subframe
8011 * @param[in] RgSchCellCb *cell
8012 * @param[in] CmLteTimingInfo curDlTime
8013 * @param[in] CmLteTimingInfo *prevDlTime
8014 * @param[in] U8 *numSubfrm
8019 PUBLIC Void rgSCHUtlGetPrevDlSfInfo
8022 CmLteTimingInfo curDlTime,
8023 CmLteTimingInfo *prevDlTime,
8027 PUBLIC Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm)
8029 CmLteTimingInfo curDlTime;
8030 CmLteTimingInfo *prevDlTime;
8034 S16 idx = curDlTime.subframe;
8036 TRC2(rgSCHUtlGetPrevDlSfInfo);
8043 idx = RGSCH_NUM_SUB_FRAMES-1;
8046 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
8047 != RG_SCH_TDD_DL_SUBFRAME);
8049 RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
8054 /* Added Holes Management functions for Adaptive Re transmission */
8055 /******* </AllocHolesMemMgmnt>: START *****/
8056 /***********************************************************
8058 * Func : rgSCHUtlUlSfInit
8060 * Desc : UL subframe init.
8068 **********************************************************/
8070 PUBLIC S16 rgSCHUtlUlSfInit
8078 PUBLIC S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf)
8086 TRC2(rgSCHUtlUlSfInit);
8094 if(cell->ulDlCfgIdx == 0)
8096 /* Store the Uplink subframe number corresponding to the idx */
8097 sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6];
8100 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
8101 sizeof(RgSchUlAllocDb));
8106 ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
8109 /* ccpu00117052 - MOD - Passing double pointer
8110 for proper NULLP assignment*/
8111 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8112 sizeof(RgSchUlAllocDb));
8115 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
8116 sizeof(RgSchUlHoleDb));
8119 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8120 /* ccpu00117052 - MOD - Passing double pointer
8121 for proper NULLP assignment*/
8122 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8123 sizeof(RgSchUlAllocDb));
8126 /* Initialize the hole with CFI 1 Pusch Bw Info */
8127 ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (U8)(maxUePerSf + 2), \
8128 0, cell->dynCfiCb.bwInfo[1].numSb);
8132 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8133 /* ccpu00117052 - MOD - Passing double pointer
8134 for proper NULLP assignment*/
8135 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8136 sizeof(RgSchUlAllocDb));
8137 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8138 sizeof(RgSchUlHoleDb));
8141 cmLListInit(&sf->reTxLst);
8143 /* Fix ccpu00120610*/
8144 sf->allocCountRef = &sf->allocDb->count;
8146 /* initialize UL available subbands for current sub-frame */
8147 sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
8149 sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
8150 sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
8151 for(index = 0; index < MAX_5GTF_BEAMS; index++)
8153 sf->sfBeamInfo[index].totVrbgAllocated = 0;
8154 sf->sfBeamInfo[index].totVrbgRequired = 0;
8155 sf->sfBeamInfo[index].vrbgStart = 0;
8163 /***********************************************************
8165 * Func : rgSCHUtlUlSfDeinit
8167 * Desc : Deinitialises a subframe
8175 **********************************************************/
8177 PUBLIC Void rgSCHUtlUlSfDeinit
8183 PUBLIC Void rgSCHUtlUlSfDeinit(cell, sf)
8188 TRC2(rgSCHUtlUlSfDeinit);
8191 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8192 /* ccpu00117052 - MOD - Passing double pointer
8193 for proper NULLP assignment*/
8194 /* ccpu00117052 - MOD - Passing double pointer
8195 for proper NULLP assignment*/
8196 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8197 sizeof(RgSchUlAllocDb));
8201 rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
8202 /* ccpu00117052 - MOD - Passing double pointer
8203 for proper NULLP assignment*/
8204 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8205 sizeof(RgSchUlHoleDb));
8210 /***********************************************************
8212 * Func : rgSCHUtlUlAllocDbInit
8214 * Desc : Initialise allocation DB
8216 * Ret : S16 (ROK/RFAILED)
8222 **********************************************************/
8224 PRIVATE S16 rgSCHUtlUlAllocDbInit
8227 RgSchUlAllocDb *allocDb,
8231 PRIVATE S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs)
8233 RgSchUlAllocDb *allocDb;
8237 S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
8238 TRC2(rgSCHUtlUlAllocDbInit);
8244 allocDb->first = NULLP;
8248 /***********************************************************
8250 * Func : rgSCHUtlUlAllocDbDeinit
8252 * Desc : Deinitialises allocation DB
8253 * sent to UE, for a UE with accumulation disabled
8261 **********************************************************/
8263 PRIVATE Void rgSCHUtlUlAllocDbDeinit
8266 RgSchUlAllocDb *allocDb
8269 PRIVATE Void rgSCHUtlUlAllocDbDeinit(cell, allocDb)
8271 RgSchUlAllocDb *allocDb;
8274 TRC2(rgSCHUtlUlAllocDbDeinit);
8275 rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
8277 allocDb->first = NULLP;
8281 /***********************************************************
8283 * Func : rgSCHUtlUlHoleDbInit
8285 * Desc : Initialise hole DB
8287 * Ret : S16 (ROK/RFAILED)
8293 **********************************************************/
8295 PRIVATE S16 rgSCHUtlUlHoleDbInit
8298 RgSchUlHoleDb *holeDb,
8304 PRIVATE S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num)
8306 RgSchUlHoleDb *holeDb;
8313 RgSchUlHole *hole = NULLP;
8314 TRC2(rgSCHUtlUlHoleDbInit);
8316 ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
8322 holeDb->first = hole;
8323 hole->start = start;
8325 hole->prv = hole->nxt = NULLP;
8329 /***********************************************************
8331 * Func : rgSCHUtlUlHoleDbDeinit
8333 * Desc : Deinitialises hole DB
8341 **********************************************************/
8343 PRIVATE Void rgSCHUtlUlHoleDbDeinit
8346 RgSchUlHoleDb *holeDb
8349 PRIVATE Void rgSCHUtlUlHoleDbDeinit(cell, holeDb)
8351 RgSchUlHoleDb *holeDb;
8354 TRC2(rgSCHUtlUlHoleDbDeinit);
8355 rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
8357 holeDb->first = NULLP;
8362 /***********************************************************
8364 * Func : rgSCHUtlUlAllocGetHole
8366 * Desc : Get allocation from hole
8368 * Ret : RgSchUlAlloc *
8374 **********************************************************/
8376 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole
8383 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole)
8389 TRC2(rgSCHUtlUlAllocGetHole);
8390 if (numSb < hole->num)
8392 RETVALUE(rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
8396 RETVALUE(rgSCHUtlUlAllocGetCompHole(sf, hole));
8401 /***********************************************************
8403 * Func : rgSCHUtlUlAllocGetCompHole
8405 * Desc : Get an allocation corresponding to an entire hole
8407 * Ret : RgSchUlAlloc *
8413 **********************************************************/
8415 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole
8421 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole)
8426 RgSchUlAlloc *alloc;
8427 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8428 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8429 * updated, causing another check for prv */
8430 RgSchUlAlloc *prv = hole->prvAlloc;
8431 RgSchUlAlloc *nxt = hole->nxtAlloc;
8432 TRC2(rgSCHUtlUlAllocGetCompHole);
8436 if (hole->start == prv->nxtHole->start)
8438 prv->nxtHole = NULLP;
8440 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8444 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8447 RGSCH_NULL_CHECK( 0, alloc);
8448 alloc->prvHole = NULLP;
8449 alloc->nxtHole = NULLP;
8451 alloc->sbStart = hole->start;
8452 alloc->numSb = hole->num;
8456 nxt->prvHole = NULLP;
8459 rgSCHUtlUlHoleRls(sf->holeDb, hole);
8461 /* UL_ALLOC_CHANGES*/
8462 alloc->allocDbRef = (void*)sf->allocDb;
8463 alloc->holeDbRef = (void*)sf->holeDb;
8467 /***********************************************************
8469 * Func : rgSCHUtlUlAllocGetPartHole
8471 * Desc : Get an allocation corresponding to a part of a hole.
8472 * The initial 'numSb' part of the hole shall be taken
8473 * away for this alloc.
8475 * Ret : RgSchUlAlloc *
8481 **********************************************************/
8483 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole
8490 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)
8496 RgSchUlAlloc *alloc;
8497 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8498 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8499 * updated, causing another check for prv */
8500 RgSchUlAlloc *prv = hole->prvAlloc;
8501 TRC2(rgSCHUtlUlAllocGetPartHole);
8505 if (hole->start == prv->nxtHole->start)
8507 prv->nxtHole = NULLP;
8509 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8513 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8516 RGSCH_NULL_CHECK( 0, alloc);
8517 alloc->prvHole = NULLP;
8518 alloc->nxtHole = hole;
8519 hole->prvAlloc = alloc;
8521 alloc->sbStart = hole->start;
8522 alloc->numSb = numSb;
8523 hole->start += numSb;
8526 rgSCHUtlUlHoleDecr(sf->holeDb, hole);
8528 /* UL_ALLOC_CHANGES*/
8529 alloc->allocDbRef = (void*)sf->allocDb;
8530 alloc->holeDbRef = (void*)sf->holeDb;
8535 /***********************************************************
8537 * Func : rgSCHUtlUlAllocFirst
8539 * Desc : Get first alloc in subframe
8541 * Ret : RgSchUlAlloc *
8547 **********************************************************/
8549 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst
8554 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf)
8558 TRC2(rgSCHUtlUlAllocFirst);
8559 RETVALUE(sf->allocDb->first);
8562 /***********************************************************
8564 * Func : rgSCHUtlUlAllocNxt
8566 * Desc : Get next alloc
8568 * Ret : RgSchUlAlloc *
8574 **********************************************************/
8576 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt
8582 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc)
8584 RgSchUlAlloc *alloc;
8587 TRC2(rgSCHUtlUlAllocNxt);
8589 RETVALUE(alloc->nxt);
8592 /***********************************************************
8594 * Func : rgSCHUtlUlAllocGetAdjNxt
8596 * Desc : Get alloc which is immediately after the passed one.
8597 * 1. Gets alloc from mem.
8598 * 2. Inserts alloc into list (between prv and
8599 * prv->nxt, prv is not NULLP).
8600 * 3. Increments alloc count.
8601 * Note 1: Holes are not dealt with here.
8602 * Note 2: Assumes prv to be NULL.
8604 * Ret : RgSchUlAlloc *
8610 **********************************************************/
8612 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt
8618 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv)
8623 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8624 RgSchUlAlloc *nxt = prv->nxt;
8625 TRC2(rgSCHUtlUlAllocGetAdjNxt);
8627 #if (ERRCLASS & ERRCLS_DEBUG)
8628 if ( alloc == NULLP )
8646 /***********************************************************
8648 * Func : rgSCHUtlUlAllocGetFirst
8650 * Desc : Get alloc which is to be the first one in the alloc list
8651 * 1. Gets alloc from mem.
8652 * 2. Inserts alloc as first element into list.
8653 * 3. Increments alloc count.
8654 * Note 1: Holes are not dealt with here.
8655 * Note 2: prv to necessarily NULLP.
8657 * Ret : RgSchUlAlloc *
8663 **********************************************************/
8665 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst
8670 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db)
8674 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8675 RgSchUlAlloc *nxt = db->first;
8676 TRC2(rgSCHUtlUlAllocGetFirst);
8678 #if (ERRCLASS & ERRCLS_DEBUG)
8679 if ( alloc == NULLP )
8698 /* UL_ALLOC_ENHANCEMENT */
8699 /***********************************************************
8701 * Func : rgSCHUtlUlHoleAddAllocation
8703 * Desc : On freeing an alloc, add to hole
8711 **********************************************************/
8713 PUBLIC Void rgSCHUtlUlHoleAddAllocation
8718 PUBLIC Void rgSCHUtlUlHoleAddAllocation(alloc)
8719 RgSchUlAlloc *alloc;
8722 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8723 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8724 * The excessive branching is meant to utilise the knowledge of whether prv
8725 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8726 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8727 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8728 RgSchUlHoleDb *db = alloc->holeDbRef;
8729 RgSchUlHole *prv = alloc->prvHole;
8730 RgSchUlHole *nxt = alloc->nxtHole;
8731 TRC2(rgSCHUtlUlHoleAddAllocation);
8737 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8740 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8746 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8749 rgSCHUtlUlHoleNew(db, alloc);
8755 /***********************************************************
8757 * Func : rgSCHUtlUlAllocRelease
8759 * Desc : Releases an uplink allocation, only take alloc ptr
8767 **********************************************************/
8769 PUBLIC Void rgSCHUtlUlAllocRelease
8774 PUBLIC Void rgSCHUtlUlAllocRelease(alloc)
8775 RgSchUlAlloc *alloc;
8778 RgSchUlAllocDb *allocDb = alloc->allocDbRef;
8779 RgSchUlAlloc *prv = alloc->prv;
8780 RgSchUlAlloc *nxt = alloc->nxt;
8781 TRC2(rgSCHUtlUlAllocRelease);
8784 alloc->raCb = NULLP;
8785 alloc->isAdaptive = FALSE;
8790 if (nxt) /* general case: this allocation lies btw two */
8797 allocDb->first = nxt;
8804 rgSCHUtlUlHoleAddAllocation(alloc);
8805 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8811 /***********************************************************
8813 * Func : rgSCHUtlUlAllocRls
8815 * Desc : Releases an uplink allocation
8823 **********************************************************/
8825 PUBLIC Void rgSCHUtlUlAllocRls
8831 PUBLIC Void rgSCHUtlUlAllocRls(sf, alloc)
8833 RgSchUlAlloc *alloc;
8836 RgSchUlAllocDb *allocDb = sf->allocDb;
8837 RgSchUlAlloc *prv = alloc->prv;
8838 RgSchUlAlloc *nxt = alloc->nxt;
8839 TRC2(rgSCHUtlUlAllocRls);
8842 alloc->raCb = NULLP;
8843 alloc->isAdaptive = FALSE;
8850 if (nxt) /* general case: this allocation lies btw two */
8857 allocDb->first = nxt;
8864 rgSCHUtlUlHoleAddAlloc(sf, alloc);
8865 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8870 printf("\nError: allocDb->count is ZERO ====\n");
8873 //printf("\nallocDb->count:%u\n",allocDb->count);
8878 /***********************************************************
8880 * Func : rgSCHUtlUlHoleFirst
8882 * Desc : Get first (largest) hole
8884 * Ret : RgSchUlHole *
8890 **********************************************************/
8892 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst
8897 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst(sf)
8901 TRC2(rgSCHUtlUlHoleFirst);
8902 RETVALUE(sf->holeDb->first);
8905 /***********************************************************
8907 * Func : rgSCHUtlUlHoleNxt
8909 * Desc : Get next largest hole
8911 * Ret : RgSchUlHole *
8917 **********************************************************/
8919 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt
8925 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole)
8930 TRC2(rgSCHUtlUlHoleNxt);
8932 RETVALUE(hole->nxt);
8935 /***********************************************************
8937 * Func : rgSCHUtlUlHoleAddAlloc
8939 * Desc : On freeing an alloc, add to hole
8947 **********************************************************/
8949 PUBLIC Void rgSCHUtlUlHoleAddAlloc
8955 PUBLIC Void rgSCHUtlUlHoleAddAlloc(sf, alloc)
8957 RgSchUlAlloc *alloc;
8960 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8961 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8962 * The excessive branching is meant to utilise the knowledge of whether prv
8963 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8964 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8965 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8966 RgSchUlHoleDb *db = sf->holeDb;
8967 RgSchUlHole *prv = alloc->prvHole;
8968 RgSchUlHole *nxt = alloc->nxtHole;
8969 TRC2(rgSCHUtlUlHoleAddAlloc);
8975 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8978 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8984 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8987 rgSCHUtlUlHoleNew(db, alloc);
8990 /* increment the number of subbands getting freed to total available list */
8991 sf->availSubbands += alloc->numSb;
8996 /***********************************************************
8998 * Func : rgSCHUtlUlHoleJoin
9000 * Desc : Join two holes (due to alloc being deleted)
9008 **********************************************************/
9010 PUBLIC Void rgSCHUtlUlHoleJoin
9018 PUBLIC Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc)
9022 RgSchUlAlloc *alloc;
9025 TRC2(rgSCHUtlUlHoleJoin);
9026 prv->num += alloc->numSb + nxt->num;
9027 rgSCHUtlUlHoleRls(db, nxt);
9028 rgSCHUtlUlHoleIncr(db, prv);
9029 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9034 /***********************************************************
9036 * Func : rgSCHUtlUlHoleExtndRight
9038 * Desc : Extend hole due to alloc coming 'after' the hole
9047 **********************************************************/
9049 PUBLIC Void rgSCHUtlUlHoleExtndRight
9056 PUBLIC Void rgSCHUtlUlHoleExtndRight(db, prv, alloc)
9059 RgSchUlAlloc *alloc;
9062 TRC2(rgSCHUtlUlHoleExtndRight);
9063 prv->num += alloc->numSb;
9064 rgSCHUtlUlHoleIncr(db, prv);
9065 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9069 /***********************************************************
9071 * Func : rgSCHUtlUlHoleExtndLeft
9073 * Desc : Extend hole due to alloc coming 'before' the hole
9082 **********************************************************/
9084 PUBLIC Void rgSCHUtlUlHoleExtndLeft
9091 PUBLIC Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc)
9094 RgSchUlAlloc *alloc;
9097 TRC2(rgSCHUtlUlHoleExtndLeft);
9098 nxt->num += alloc->numSb;
9099 nxt->start = alloc->sbStart;
9100 rgSCHUtlUlHoleIncr(db, nxt);
9101 rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
9105 /***********************************************************
9107 * Func : rgSCHUtlUlHoleNew
9109 * Desc : Create new hole due to alloc being deleted
9117 **********************************************************/
9119 PUBLIC Void rgSCHUtlUlHoleNew
9125 PUBLIC Void rgSCHUtlUlHoleNew(db, alloc)
9127 RgSchUlAlloc *alloc;
9130 RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
9131 #if (ERRCLASS & ERRCLS_DEBUG)
9132 if ( hole == NULLP )
9137 TRC2(rgSCHUtlUlHoleNew);
9138 hole->start = alloc->sbStart;
9139 hole->num = alloc->numSb;
9141 rgSCHUtlUlHoleIns(db, hole);
9142 rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
9146 /***********************************************************
9148 * Func : rgSCHUtlUlHoleUpdAllocLnks
9150 * Desc : Update alloc links in hole
9158 **********************************************************/
9160 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks
9163 RgSchUlAlloc *prvAlloc,
9164 RgSchUlAlloc *nxtAlloc
9167 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc)
9169 RgSchUlAlloc *prvAlloc;
9170 RgSchUlAlloc *nxtAlloc;
9173 TRC2(rgSCHUtlUlHoleUpdAllocLnks);
9176 prvAlloc->nxtHole = hole;
9180 nxtAlloc->prvHole = hole;
9182 hole->prvAlloc = prvAlloc;
9183 hole->nxtAlloc = nxtAlloc;
9188 /***********************************************************
9190 * Func : rgSCHUtlUlHoleIns
9192 * Desc : Insert (newly created) hole in sorted list of holes.
9193 * Searches linearly, beginning with the largest hole.
9201 **********************************************************/
9203 PUBLIC Void rgSCHUtlUlHoleIns
9209 PUBLIC Void rgSCHUtlUlHoleIns(db, hole)
9215 TRC2(rgSCHUtlUlHoleIns);
9217 if ((cur = db->first) != NULLP)
9220 if (cur->num < hole->num)
9230 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9232 if (nxt->num < hole->num)
9234 /* Insert hole: cur <-> hole <-> nxt */
9250 /* This is the first hole */
9252 hole->prv = NULLP; /* may not be needed */
9258 /***********************************************************
9260 * Func : rgSCHUtlUlHoleIncr
9262 * Desc : hole->num has increeased, reposition in sorted
9271 **********************************************************/
9273 PUBLIC Void rgSCHUtlUlHoleIncr
9279 PUBLIC Void rgSCHUtlUlHoleIncr(db, hole)
9285 TRC2(rgSCHUtlUlHoleIncr);
9287 if ((cur = hole->prv) != NULLP)
9291 if (cur->num > hole->num)
9296 /* Remove hole from current position */
9297 cur->nxt = hole->nxt;
9300 hole->nxt->prv = cur;
9303 for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
9305 if (prv->num > hole->num)
9307 /* Insert hole: prv <-> hole <-> cur */
9326 /***********************************************************
9328 * Func : rgSCHUtlUlHoleDecr
9330 * Desc : hole->num has decreeased, reposition in sorted
9339 **********************************************************/
9341 PUBLIC Void rgSCHUtlUlHoleDecr
9347 PUBLIC Void rgSCHUtlUlHoleDecr(db, hole)
9353 TRC2(rgSCHUtlUlHoleDecr);
9355 if ((cur = hole->nxt) != NULLP)
9359 if (cur->num < hole->num)
9364 /* Remove hole from current position */
9365 cur->prv = hole->prv;
9368 hole->prv->nxt = cur;
9370 else /* no prv, so cur to replace hole as first in list */
9375 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9377 if (nxt->num < hole->num)
9379 /* Insert hole: cur <-> hole <-> nxt */
9397 /***********************************************************
9399 * Func : rgSCHUtlUlHoleRls
9401 * Desc : Releases hole.
9402 * 1. Decrements hole count.
9403 * 2. Deletes hole from list.
9404 * 3. Frees hole (hole memory release).
9412 **********************************************************/
9414 PUBLIC Void rgSCHUtlUlHoleRls
9420 PUBLIC Void rgSCHUtlUlHoleRls(db, hole)
9425 RgSchUlHole *prv = hole->prv;
9426 RgSchUlHole *nxt = hole->nxt;
9427 TRC2(rgSCHUtlUlHoleRls);
9447 rgSCHUtlUlHoleMemRls(&db->mem, hole);
9452 /***********************************************************
9454 * Func : rgSCHUtlUlAllocMemInit
9456 * Desc : Initialises alloc free pool
9458 * Ret : S16 (ROK/RFAILED)
9464 **********************************************************/
9466 PUBLIC S16 rgSCHUtlUlAllocMemInit
9469 RgSchUlAllocMem *mem,
9473 PUBLIC S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs)
9475 RgSchUlAllocMem *mem;
9480 RgSchUlAlloc *allocs;
9481 TRC2(rgSCHUtlUlAllocMemInit);
9483 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
9484 maxAllocs * sizeof(*allocs));
9489 mem->allocs = allocs;
9490 mem->maxAllocs = maxAllocs;
9491 if (mem->maxAllocs == 1)
9493 allocs[0].prv = NULLP;
9494 allocs[0].nxt = NULLP;
9499 allocs[0].prv = NULLP;
9500 allocs[0].nxt = &allocs[1];
9501 for (i = 1; i < mem->maxAllocs - 1; ++i)
9503 allocs[i].prv = &allocs[i-1];
9504 allocs[i].nxt = &allocs[i+1];
9506 allocs[i].prv = &allocs[i-1];
9507 allocs[i].nxt = NULLP;
9509 mem->firstFree = &allocs[0];
9513 /***********************************************************
9515 * Func : rgSCHUtlUlAllocMemDeinit
9517 * Desc : Deinitialises alloc free pool
9525 **********************************************************/
9527 PUBLIC Void rgSCHUtlUlAllocMemDeinit
9530 RgSchUlAllocMem *mem
9533 PUBLIC Void rgSCHUtlUlAllocMemDeinit(cell, mem)
9535 RgSchUlAllocMem *mem;
9538 TRC2(rgSCHUtlUlAllocMemDeinit);
9539 /* ccpu00117052 - MOD - Passing double pointer
9540 for proper NULLP assignment*/
9541 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
9542 mem->maxAllocs * sizeof(*mem->allocs));
9544 mem->firstFree = NULLP;
9548 /***********************************************************
9550 * Func : rgSCHUtlUlHoleMemInit
9552 * Desc : Initialises hole free pool. Assumes maxHoles
9555 * Ret : S16 (ROK/RFAILED)
9561 **********************************************************/
9563 PUBLIC S16 rgSCHUtlUlHoleMemInit
9566 RgSchUlHoleMem *mem,
9568 RgSchUlHole **holeRef
9571 PUBLIC S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef)
9573 RgSchUlHoleMem *mem;
9575 RgSchUlHole **holeRef;
9580 TRC2(rgSCHUtlUlHoleMemInit);
9582 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
9583 maxHoles * sizeof(*holes));
9590 mem->maxHoles = maxHoles;
9592 /* first hole is taken up */
9593 holes[0].prv = NULLP; /* not needed */
9594 holes[0].nxt = NULLP; /* not needed */
9595 *holeRef = &holes[0];
9597 if (mem->maxHoles == 2)
9599 holes[1].prv = NULLP; /* may not be needed */
9600 holes[1].nxt = NULLP; /* may not be needed */
9605 holes[1].prv = NULLP;
9606 holes[0].nxt = &holes[1];
9607 for (i = 1; i < mem->maxHoles - 1; ++i)
9609 holes[i].prv = &holes[i-1];
9610 holes[i].nxt = &holes[i+1];
9612 holes[i].prv = &holes[i-1];
9613 holes[i].nxt = NULLP;
9615 mem->firstFree = &holes[1];
9620 /***********************************************************
9622 * Func : rgSCHUtlUlHoleMemDeinit
9624 * Desc : Deinitialises hole free pool
9632 **********************************************************/
9634 PUBLIC Void rgSCHUtlUlHoleMemDeinit
9640 PUBLIC Void rgSCHUtlUlHoleMemDeinit(cell, mem)
9642 RgSchUlHoleMem *mem;
9645 TRC2(rgSCHUtlUlHoleMemDeinit);
9646 /* ccpu00117052 - MOD - Passing double pointer
9647 for proper NULLP assignment*/
9648 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
9649 mem->maxHoles * sizeof(*mem->holes));
9651 mem->firstFree = NULLP;
9655 /***********************************************************
9657 * Func : rgSCHUtlUlAllocMemGet
9659 * Desc : Gets an 'alloc' from the free pool
9661 * Ret : RgSchUlAlloc *
9667 **********************************************************/
9669 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet
9671 RgSchUlAllocMem *mem
9674 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem)
9675 RgSchUlAllocMem *mem;
9678 RgSchUlAlloc *alloc;
9679 TRC2(rgSCHUtlUlAllocMemGet);
9681 #if (ERRCLASS & ERRCLS_DEBUG)
9682 if (mem->firstFree == NULLP)
9688 alloc = mem->firstFree;
9689 mem->firstFree = alloc->nxt;
9690 alloc->nxt = NULLP; /* probably not needed */
9691 /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
9696 /***********************************************************
9698 * Func : rgSCHUtlUlAllocMemRls
9700 * Desc : Returns an 'alloc' to the free pool
9708 **********************************************************/
9710 PUBLIC Void rgSCHUtlUlAllocMemRls
9712 RgSchUlAllocMem *mem,
9716 PUBLIC Void rgSCHUtlUlAllocMemRls(mem, alloc)
9717 RgSchUlAllocMem *mem;
9718 RgSchUlAlloc *alloc;
9721 TRC2(rgSCHUtlUlAllocMemRls);
9724 alloc->nxt = mem->firstFree;
9725 if (mem->firstFree != NULLP)
9727 mem->firstFree->prv = alloc;
9729 mem->firstFree = alloc;
9733 /***********************************************************
9735 * Func : rgSCHUtlUlHoleMemGet
9737 * Desc : Gets a 'hole' from the free pool
9739 * Ret : RgSchUlHole *
9745 **********************************************************/
9747 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet
9752 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet(mem)
9753 RgSchUlHoleMem *mem;
9757 TRC2(rgSCHUtlUlHoleMemGet);
9759 #if (ERRCLASS & ERRCLS_DEBUG)
9760 if (mem->firstFree == NULLP)
9766 hole = mem->firstFree;
9767 mem->firstFree = hole->nxt;
9768 mem->firstFree->prv = NULLP; /* may not be needed, under error class */
9769 hole->nxt = NULLP; /* probably not needed */
9770 /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
9775 /***********************************************************
9777 * Func : rgSCHUtlUlHoleMemRls
9779 * Desc : Returns a 'hole' to the free pool
9787 **********************************************************/
9789 PUBLIC Void rgSCHUtlUlHoleMemRls
9791 RgSchUlHoleMem *mem,
9795 PUBLIC Void rgSCHUtlUlHoleMemRls(mem, hole)
9796 RgSchUlHoleMem *mem;
9800 TRC2(rgSCHUtlUlHoleMemRls);
9803 hole->nxt = mem->firstFree;
9804 if (mem->firstFree != NULLP)
9806 mem->firstFree->prv = hole;
9808 mem->firstFree = hole;
9813 * @brief Get an alloc from the specified position in the BW.
9817 * Function : rgSCHUtlUlGetSpfcAlloc
9819 * - Return an alloc from the specified position in the BW.
9820 * Note: This function assumes there is always a hole
9821 * Existing which completely has the specified
9822 * allocation. The reason for such an assumption is
9823 * the function's usage as of now guarantees that there
9824 * will always be such hole. And also for efficiency.
9826 * @param[in] RgSchUlSf *sf
9827 * @param[in] U8 startSb
9828 * @param[in] U8 numSb
9829 * @return RgSchUlAlloc*
9832 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc
9839 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb)
9845 RgSchUlHole *hole, *nxtHole;
9846 RgSchUlAlloc *alloc = NULLP;
9847 TRC2(rgSCHUtlUlGetSpfcAlloc);
9849 if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
9855 nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
9856 if ((startSb >= hole->start) &&
9857 (startSb+numSb <= hole->start+hole->num))
9859 if (startSb != hole->start)
9861 /* Create a new hole to accomodate Subbands between
9862 * hole start and req alloc start */
9863 RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
9865 #if (ERRCLASS & ERRCLS_DEBUG)
9866 if ( newHole == NULLP )
9871 newHole->start = hole->start;
9872 newHole->num = startSb - hole->start;
9873 hole->start = startSb;
9874 /* [ccpu00122847]-MOD- Correctly updating the hole->num */
9875 hole->num -= newHole->num;
9876 ++(sf->holeDb->count);
9877 rgSCHUtlUlHoleIns(sf->holeDb, newHole);
9878 newHole->prvAlloc = hole->prvAlloc;
9879 if (newHole->prvAlloc)
9881 newHole->prvAlloc->nxtHole = newHole;
9883 if (numSb == hole->num)
9885 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9889 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9891 alloc->prvHole = newHole;
9892 newHole->nxtAlloc = alloc;
9894 else /* Hole start and req alloc start are same */
9896 if (numSb == hole->num)
9898 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9902 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9907 } while ((hole = nxtHole) != NULLP);
9912 * @brief Validates the qci values
9916 * Function :rgSCHUtlValidateQci
9918 * @param[in] RgSchCellCb *cellCb
9919 * @param[in] U8 numQci
9920 * @param[out] U8 *qci
9926 PRIVATE S16 rgSCHUtlValidateQci
9928 RgSchCellCb *cellCb,
9933 PRIVATE S16 rgSCHUtlValidateQci(cellCb, numQci, qci)
9934 RgSchCellCb *cellCb;
9942 TRC3(rgSCHUtlValidateQci)
9944 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
9946 qciVal = qci[qciIdx];
9947 if(qciVal == 0 || qciVal > 9)
9951 if(qciVal != cellCb->qciArray[qciVal].qci)
9958 }/* rgSCHUtlValidateQci */
9960 * @brief Validates the measurement request parameters.
9964 * Function :rgSCHUtlValidateMeasReq
9966 * @param[in] RgSchCellCb *cellCb
9967 * @param[in] LrgSchMeasReqInfo *schL2MeasInfo
9968 * @param[out] RgSchErrInfo *err
9969 * @return RgSchUlAlloc*
9972 PUBLIC S16 rgSCHUtlValidateMeasReq
9974 RgSchCellCb *cellCb,
9975 LrgSchMeasReqInfo *schL2MeasInfo,
9979 PUBLIC S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err)
9980 RgSchCellCb *cellCb;
9981 LrgSchMeasReqInfo *schL2MeasInfo;
9988 TRC3(rgSCHUtlValidateMeasReq)
9990 measType = schL2MeasInfo->measType;
9992 if((measType == 0) ||
9995 err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
9996 err->errCause = RGSCHERR_SCH_L2MEAS;
9999 if((schL2MeasInfo->timePrd !=0) &&
10000 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
10001 ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
10002 (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
10004 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10005 err->errCause = RGSCHERR_SCH_L2MEAS;
10008 if((schL2MeasInfo->timePrd !=0) &&
10009 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
10010 (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ))
10012 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10013 err->errCause = RGSCHERR_SCH_L2MEAS;
10016 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
10017 ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
10018 (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
10019 ((schL2MeasInfo->timePrd !=0)&&
10020 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
10021 (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
10023 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10024 err->errCause = RGSCHERR_SCH_L2MEAS;
10027 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
10028 ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
10029 (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
10030 ((schL2MeasInfo->timePrd !=0) &&
10031 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
10032 (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
10034 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10035 err->errCause = RGSCHERR_SCH_L2MEAS;
10038 if((schL2MeasInfo->timePrd !=0) &&
10039 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
10041 RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \
10042 (schL2MeasInfo->avgPrbQciDl.numQci));
10043 ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
10044 schL2MeasInfo->avgPrbQciDl.qci);
10047 err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
10048 err->errCause = RGSCHERR_SCH_L2MEAS;
10053 }/* rgSCHUtlValidateMeasReq */
10054 #endif /* LTE_L2_MEAS */
10055 /******* </AllocHolesMemMgmnt>: END *****/
10058 * @brief API for sending SI configuration confirm from Scheduler to RRM
10062 * Function: rgSCHUtlRgrSiCfgCfm
10064 * This API is invoked to send SI configuration confirm from Scheduler
10066 * This API fills in Pst structure and SAP Ids and invokes
10067 * config confirm API towards RRM.
10069 * @param[in] RgrCfgTransId transId
10070 * @param[in] U8 status
10076 PUBLIC S16 rgSCHUtlRgrSiCfgCfm
10080 RgrCfgTransId transId,
10084 PUBLIC S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status)
10087 RgrCfgTransId transId;
10091 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10093 TRC2(rgSCHUtlRgrSiCfgCfm)
10095 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10096 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10099 if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10100 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10101 transId, status) != ROK)
10103 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10104 "RgUiRgrSiCfgCfm Failed ");
10109 } /* rgSCHUtlRgrSiCfgCfm */
10113 * @brief API for sending Warning SI configuration confirm from
10119 * This API is invoked to send Warning SI configuration confirm
10120 * from Scheduler to RRM.
10121 * This API fills in Pst structure and SAP Ids and invokes
10122 * config confirm API towards RRM.
10124 * @param[in] RgrCfgTransId transId
10125 * @param[in] U8 status
10131 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm
10136 RgrCfgTransId transId,
10140 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status)
10144 RgrCfgTransId transId;
10148 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10150 TRC2(rgSCHUtlRgrWarningSiCfgCfm)
10152 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10153 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10156 if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10157 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10158 transId, siId, status) != ROK)
10160 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10161 "RgUiRgrSiCfgCfm Failed ");
10166 } /* rgSCHUtlRgrWarningSiCfgCfm */
10168 /***********************************************************
10170 * Func : rgSCHUtlPutSiInfo
10172 * Desc : Utility Function to deallocate SI information
10180 **********************************************************/
10182 PUBLIC Void rgSCHUtlPutSiInfo
10187 PUBLIC Void rgSCHUtlPutSiInfo(cell)
10192 U32 sizeOfSiInfo = 0;
10193 TRC2(rgSCHUtlPutSiInfo)
10194 /*Free the buffers in crntSiInfo*/
10195 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
10196 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
10198 sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
10200 for(idx=0; idx < sizeOfSiInfo; idx++)
10202 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
10205 /*Free the buffers in newSiInfo */
10206 RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
10207 RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
10209 sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
10211 for(idx=0; idx < sizeOfSiInfo; idx++)
10213 RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
10218 #endif /*RGR_SI_SCH */
10222 /***********************************************************
10224 * Func : rgSCHUtlGetDrxSchdUesInDl
10226 * Desc : Utility Function to fill the get the list of
10227 * scheduled UEs. On these UE's, drx-inactivity
10228 * timer will be started/restarted.
10237 **********************************************************/
10239 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl
10241 RgSchCellCb *cellCb,
10243 RgSchDlHqProcCb *dlHq,
10244 RgInfUeAlloc *allocInfo,
10245 CmLListCp *dlDrxInactvTmrLst,
10246 CmLListCp *dlInActvLst,
10247 CmLListCp *ulInActvLst
10250 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
10251 RgSchCellCb *cellCb;
10253 RgSchDlHqProcCb *dlHq;
10254 RgInfUeAlloc *allocInfo;
10255 CmLListCp *dlDrxInactvTmrLst;
10256 CmLListCp *dlInActvLst;
10257 CmLListCp *ulInActvLst;
10260 Bool isNewTx = FALSE;
10262 RgSchDrxDlHqProcCb *drxHq;
10263 RgSchDRXCellCb *drxCell = cellCb->drxCb;
10264 RgSchDrxUeCb *drxUe;
10266 Inst inst = cellCb->instIdx;
10268 U8 cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
10272 for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
10274 if(allocInfo->tbInfo[idx].isReTx == FALSE)
10277 /* Removing break here, since in 2 TB case if 2nd TB is proceeding with
10278 retx then drxretx timer should be stopped.*/
10282 /*Stop the DRX retransmission timer as UE scheduled for retx. Here
10283 * we stop the timer and inactivate the UE for both UL and DL.
10284 * This may result in loss of one subframe for UL but this trade
10285 * off is taken to avoid the overhead of maintaining a list of UEs
10286 * to be inactivated in the next subframe.*/
10287 drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
10288 drxUe = RG_SCH_DRX_GET_UE(ueCb);
10289 if(drxHq->reTxIndx != DRX_INVALID)
10291 /* This condition should never occur */
10292 if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
10294 RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]"
10295 "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
10296 drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId));
10299 drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10300 drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10302 dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10303 ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10305 for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
10307 dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
10308 ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
10311 drxUe->drxDlInactvMask |= dlInactvMask;
10312 drxUe->drxUlInactvMask |= ulInactvMask;
10314 /* if no other condition is keeping ue active,
10315 * inactivate the Ue
10317 if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
10319 /* BUG 2 : HARQ_RTT, changed for consistency */
10320 ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
10322 /* Add to DL inactive list */
10323 cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
10324 ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
10327 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
10329 /*BUG 2: HARQ_RTT changed for consistency */
10330 ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
10332 cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
10333 ueCb->ulDrxInactvLnk.node = (PTR)ueCb;
10336 /* Deleting entry from HARQ RTT queue for the same HARQ proc,
10337 * if exist. This is the special case which can happen iF UL
10338 * scheduling is done later. */
10339 if(drxHq->rttIndx != DRX_INVALID)
10341 cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
10342 &(drxHq->harqRTTEnt));
10344 drxHq->rttIndx = DRX_INVALID;
10347 cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
10348 &(drxHq->harqRetxEnt));
10349 drxHq->reTxIndx = DRX_INVALID;
10354 if(isNewTx == TRUE)
10356 if(ueCb->drxCb->raRcvd == TRUE)
10358 ueCb->drxCb->raRcvd = FALSE;
10360 /* mark the ra bit */
10361 ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10362 ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10364 }/*if(ra->rcvd) == TRUE */
10366 if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
10368 cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
10369 ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
10371 }/*if(isNewTx == TRUE) */
10374 }/* rgSCHUtlGetSchdUes*/
10376 /* ccpu00117452 - MOD - Changed macro name from
10377 RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
10378 #ifdef RGR_CQI_REPT
10380 * @brief This function fills StaInd struct
10384 * Function: rgSCHUtlFillSndStaInd
10385 * Purpose: Fills StaInd struct and sends the
10388 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10389 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10390 * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled
10391 * @param[in] U8 numCqiRept NUmber of reports to be filled
10396 PUBLIC S16 rgSCHUtlFillSndStaInd
10400 RgrStaIndInfo *staInfo,
10404 PUBLIC S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept)
10407 RgrStaIndInfo *staInfo;
10413 /* Fill StaInd for sending collated Latest N CQI rpeorts */
10414 /* Find index in the array from where Latest N
10415 reports needs to be fetched. Use this value to index in the array
10416 and copy the reports into staInfo */
10418 /* Fill the Cell Id of PCC of the UE */
10419 staInfo->cellId = ue->cell->cellId;
10420 staInfo->crnti = ue->ueId;
10422 idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
10424 cmMemcpy ((U8*)&(staInfo->ueCqiInfo.cqiRept),
10425 (U8*)&(ue->schCqiInfo.cqiRept[idxStart]),
10426 numCqiRept * sizeof(RgrUeCqiRept));
10428 staInfo->ueCqiInfo.numCqiRept = numCqiRept;
10430 ue->schCqiInfo.cqiCount = 0;
10432 /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
10433 if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
10435 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10436 "CQI reports for RNTI:%d",ue->ueId);
10442 }/* End of rgSCHUtlFillSndStaInd */
10447 * @brief API for sending STA indication from Scheduler to RRM.
10451 * Function: rgSCHUtlRgrStaInd
10453 * This API is invoked to send STA indication from Scheduler instance to RRM.
10454 * This API fills in Pst structure and RgrStaIndInfo
10455 * and calls the Sta primitive API towards RRM.
10457 * @param[in] cell RgSchCellCb
10458 * @param[in] RgrStsIndInfo *rgrSta
10464 PUBLIC S16 rgSCHUtlRgrStaInd
10467 RgrStaIndInfo *rgrSta
10470 PUBLIC S16 rgSCHUtlRgrStaInd(cell, rgrSta)
10472 RgrStaIndInfo *rgrSta;
10476 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10478 TRC2(rgSCHUtlRgrStaInd)
10481 rgrSap = cell->rgrSap;
10482 if (rgrSap->sapSta.sapState != LRG_BND)
10484 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10485 "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
10486 rgrSap->sapSta.sapState);
10489 RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
10490 cell->rgrSap->sapCfg.suId, rgrSta);
10492 } /* rgSCHUtlRgrStaInd*/
10493 #endif /* End of RGR_CQI_REPT */
10495 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
10497 * @brief Indicates MAC to release any rnti context it has.
10500 * Function : rgSCHUtlIndRntiRls2Mac
10501 * This function indicates MAC for this rnti release.
10502 * In case of ueId change it will indicate MAC
10503 * about the new rnti to be updated.
10504 * It will post a release RNTI indication to MAC.
10508 * @param[in] RgSchCellCb *cell
10509 * @param[in] CmLteRnti rnti
10510 * @param[in] Bool ueIdChng
10511 * @param[in] CmLteRnti newRnti
10516 PUBLIC Void rgSCHUtlIndRntiRls2Mac
10524 PUBLIC Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti)
10532 Inst inst = cell->instIdx;
10533 RgInfRlsRnti rntiInfo;
10535 TRC2(rgSCHUtlIndRntiRls2Mac)
10537 /* Copy the info to rntiInfo */
10538 rntiInfo.cellId = cell->cellId;
10539 rntiInfo.rnti = rnti;
10540 /* Fix : syed ueId change as part of reestablishment.
10541 * Now SCH to trigger this. CRG ueRecfg for ueId change
10543 rntiInfo.ueIdChng = ueIdChng;
10544 rntiInfo.newRnti = newRnti;
10546 rntiInfo.isUeSCellDel = FALSE;
10548 /* Invoke MAC to release the rnti */
10549 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
10550 RgSchMacRlsRnti(&pst, &rntiInfo);
10554 /* LTE_ADV_FLAG_REMOVED_START */
10556 * @brief API for sending LOAD INF indication from Scheduler to RRM.
10559 * Function: rgSCHUtlRgrLoadInfInd
10561 * This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
10562 * This API fills in Pst structure and RgrLoadInfIndInfo
10563 * and calls the Sta primitive API towards RRM.
10565 * @param[in] cell RgSchCellCb
10566 * @param[in] RgrLoadInfIndInfo *rgrLoadInf
10572 PUBLIC S16 rgSCHUtlRgrLoadInfInd
10575 RgrLoadInfIndInfo *rgrLoadInf
10578 PUBLIC S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf)
10580 RgrLoadInfIndInfo *rgrLoadInf;
10584 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10586 TRC2(rgSCHUtlRgrLoadInfInd)
10589 rgrSap = cell->rgrSap;
10590 if (rgrSap->sapSta.sapState != LRG_BND)
10592 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10593 "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
10594 rgrSap->sapSta.sapState);
10597 RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
10598 cell->rgrSap->sapCfg.suId, rgrLoadInf);
10600 } /* rgSCHUtlRgrLoadInfInd*/
10601 /* LTE_ADV_FLAG_REMOVED_END */
10603 /* MS_FIX : syed SCH to act as MASTER in maintaining
10604 * rnti related context. Trigger to rnti del/Chng at SCH
10605 * will result in a Indication to MAC to release its
10606 * RNTI context. MAC inturn indicates the context cleared
10607 * indication to SCH, upon which SCH would set this
10609 * @brief API for sending STA indication from Scheduler to RRM.
10613 * Function: rgSCHUtlRlsRnti
10615 * This API is invoked to indicate MAC to release rnti
10617 * @param[in] RgSchCellCb *cellCb
10618 * @param[in] RgSchRntiLnk *rntiLnk,
10619 * @param[in] Bool ueIdChngd,
10620 * @param[in] CmLteRnti newRnti
10625 PUBLIC Void rgSCHUtlRlsRnti
10628 RgSchRntiLnk *rntiLnk,
10633 PUBLIC Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti)
10635 RgSchRntiLnk *rntiLnk;
10641 TRC2(rgSCHUtlRlsRnti)
10644 if(cell->emtcEnable)
10646 rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
10651 /*Add to Guard Pool*/
10652 cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
10653 rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
10655 /* Fix: syed Explicitly Inidcate MAC to release RNTI */
10656 rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
10663 * @brief This function fills StaInd struct
10667 * Function: rgSCHUtlFillSndUeStaInd
10668 * Purpose: Fills StaInd struct and sends the
10671 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10672 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10673 * @param[in] U8 numCqiRept NUmber of reports to be filled
10678 PUBLIC S16 rgSCHUtlFillSndUeStaInd
10682 RgrUeStaIndInfo *ueStaInfo
10685 PUBLIC S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo)
10688 RgrUeStaIndInfo *ueStaInfo;
10692 ueStaInfo->cellId = cell->cellId;
10693 ueStaInfo->crnti = ue->ueId;
10695 /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
10696 if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
10698 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10699 "UE Sta reports CRNTI:%d",ue->ueId);
10705 }/* End of rgSCHUtlFillSndStaInd */
10710 * @brief API for sending STA indication from Scheduler to RRM.
10714 * Function: rgSCHUtlRgrStaInd
10716 * This API is invoked to send STA indication from Scheduler instance to RRM.
10717 * This API fills in Pst structure and RgrStaIndInfo
10718 * and calls the Sta primitive API towards RRM.
10720 * @param[in] cell RgSchCellCb
10721 * @param[in] RgrStsIndInfo *rgrSta
10727 PUBLIC S16 rgSCHUtlRgrUeStaInd
10730 RgrUeStaIndInfo *rgrUeSta
10733 PUBLIC S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta)
10735 RgrUeStaIndInfo *rgrUeSta;
10739 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10741 TRC2(rgSCHUtlRgrStaInd)
10744 rgrSap = cell->rgrSap;
10745 if (rgrSap->sapSta.sapState != LRG_BND)
10747 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10748 "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
10749 rgrSap->sapSta.sapState);
10752 RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
10753 cell->rgrSap->sapCfg.suId, rgrUeSta);
10755 } /* rgSCHUtlRgrStaInd*/
10759 * @brief function to report DL and UL PRB usage to RRM.
10762 * Function: rgSCHUtlUpdAvgPrbUsage
10763 * This function sends the PRB usage report to
10764 * RRM with the interval configured by RRM.
10766 * @param[in] cell *RgSchCellCb
10772 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage
10777 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage(cell)
10781 CmLteTimingInfo frm;
10782 RgmPrbRprtInd *prbRprtInd;
10785 #ifdef DBG_MAC_RRM_PRB_PRINT
10786 static U32 count = 0;
10787 const U32 reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
10792 TRC2(rgSCHUtlUpdAvgPrbUsage);
10794 frm = cell->crntTime;
10795 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
10801 if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
10803 /* Get the total number of DL and UL subframes within the reporting period*/
10804 numDlSf = (cell->prbUsage.rprtPeriod *
10805 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10806 / RGSCH_NUM_SUB_FRAMES;
10807 numUlSf = (cell->prbUsage.rprtPeriod *
10808 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10809 / RGSCH_NUM_SUB_FRAMES;
10813 /* Get the total number of DL and UL subframes < 10 ms interval */
10814 numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe];
10815 numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.subframe];
10818 numDlSf = cell->prbUsage.rprtPeriod;
10819 numUlSf = cell->prbUsage.rprtPeriod;
10822 if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
10823 cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd,
10824 sizeof(RgmPrbRprtInd)) != ROK)
10829 cmMemset((U8 *) &prbRprtInd->stQciPrbRpts[0],
10831 (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
10833 prbRprtInd->bCellId = cell->cellId;
10837 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL;
10838 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10840 prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage =
10841 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
10842 (numDlSf * cell->bwCfg.dlTotalBw));
10843 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10844 cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
10850 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL;
10851 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10853 prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage =
10854 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
10855 (numUlSf * cell->ulAvailBw));
10856 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10857 cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
10861 #ifdef DBG_MAC_RRM_PRB_PRINT
10862 if((count % reprotForEvery20Sec) == 0 )
10864 printf("\n====================================================================");
10865 printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n");
10866 printf("======================================================================\n");
10867 printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n",
10868 prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
10869 prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
10870 prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
10871 prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
10872 prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
10873 prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
10874 prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
10875 prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
10878 RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst),
10879 cell->rgmSap->sapCfg.suId, prbRprtInd);
10887 * @brief This function resends the Ta in case of
10888 * max retx failure or DTX for the Ta transmitted
10892 * Function: rgSCHUtlReTxTa
10895 * @param[in] RgSchCellCb *cell
10896 * @param[in] RgSchUeCb *ue
10901 PUBLIC Void rgSCHUtlReTxTa
10903 RgSchCellCb *cellCb,
10907 PUBLIC Void rgSCHUtlReTxTa(cellCb, ueCb)
10908 RgSchCellCb *cellCb;
10912 TRC2(rgSCHUtlReTxTa)
10914 /* If TA Timer is running. Stop it */
10915 if (ueCb->taTmr.tmrEvnt != TMR_NONE)
10917 rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
10919 /*[ccpu00121813]-ADD-If maxretx is reached then
10920 * use outstanding TA val for scheduling again */
10921 if(ueCb->dl.taCb.outStndngTa == TRUE)
10923 ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
10924 ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
10925 ueCb->dl.taCb.outStndngTa = FALSE;
10928 /* Fix : syed TA state updation missing */
10929 ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
10930 rgSCHUtlDlTARpt(cellCb, ueCb);
10935 /* Added function for dropping Paging Message*/
10937 * @brief Handler for BO Updt received for BCCH or PCCH.
10941 * Function : rgSCHChkBoUpdate
10943 * This function shall check for BO received falls within the scheduling window or not
10946 * @param[in] RgSchCellCb *cell
10952 PRIVATE S16 rgSCHChkBoUpdate
10955 RgInfCmnBoRpt *boUpdt
10958 PRIVATE S16 rgSCHChkBoUpdate (cell, boUpdt)
10960 RgInfCmnBoRpt *boUpdt;
10964 U32 crntTimeInSubFrms = 0;
10965 U32 boUpdTimeInSubFrms = 0;
10967 TRC2(rgSCHChkBoUpdate);
10969 crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.subframe +
10970 RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI
10971 so incrementing with +1 more */
10972 boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.subframe;
10975 distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
10976 boUpdTimeInSubFrms - crntTimeInSubFrms : \
10977 (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
10979 if (distance > RGSCH_PCCHBCCH_WIN)
10985 }/*rgSCHChkBoUpdate*/
10990 * @brief Utility function to calculate the UL reTxIdx in TDD cfg0
10994 * Function : rgSchUtlCfg0ReTxIdx
10996 * Update the reTxIdx according to the rules mentioned
10997 * in 3GPP TS 36.213 section 8 for TDD Cfg0
10999 * @param[in] RgSchCellCb *cell
11000 * @param[in] CmLteTimingInfo phichTime
11001 * @param[in] U8 hqFdbkIdx
11005 PUBLIC U8 rgSchUtlCfg0ReTxIdx
11008 CmLteTimingInfo phichTime,
11012 PUBLIC U8 rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx)
11014 CmLteTimingInfo phichTime;
11018 U8 reTxIdx = RGSCH_INVALID_INFO;
11020 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
11022 U8 ulSF; /* UL SF in the TDD frame */
11024 TRC2(rgSchUtlCfg0ReTxIdx);
11026 ulSf = &cellUl->ulSfArr[hqFdbkIdx];
11027 ulSF = ulSf->ulSfIdx;
11029 /* Check for the UL SF 4 or 9 */
11030 if(ulSF == 9 || ulSF == 4)
11034 if(phichTime.subframe == 0 || phichTime.subframe == 5)
11038 /* Retx will happen according to the Pusch k table */
11039 reTxIdx = cellUl->schdIdx;
11043 /* Retx will happen at n+7 */
11044 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11045 /* Fetch the corresponding UL subframe Idx in UL sf array */
11046 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11049 else if(phichTime.subframe == 1 || phichTime.subframe == 6)
11051 /* Retx will happen at n+7 */
11052 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11053 /* Fetch the corresponding UL subframe Idx in UL sf array */
11054 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11061 * @brief Utility function to calculate total num of PRBs required to
11062 * satisfy DL BO for TM1/TM2/TM6/TM7
11066 * Function : rgSchUtlDlCalc1CwPrb
11068 * Calculate PRBs required for UE to satisfy BO in DL
11070 * Note : Total calculated PRBs will be assigned to *prbReqrd
11073 * @param[in] RgSchCellCb *cell
11074 * @param[in] RgSchUeCb *ue
11075 * @param[in] U32 bo
11076 * @param[out] U32 *prbReqrd
11080 PUBLIC Void rgSchUtlDlCalc1CwPrb
11088 PUBLIC Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd)
11095 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11096 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11100 U8 cfi = dlCell->currCfi;
11102 TRC2(rgSchUtlDlCalc1CwPrb);
11104 iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11105 eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
11107 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11108 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11109 noRes = ((U64)((bo << 3) << 10)) / (eff);
11110 /* Get the number of RBs needed for this transmission */
11111 /* Number of RBs = No of REs / No of REs per RB */
11112 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11115 } /* rgSchUtlDlCalc1CwPrb*/
11118 * @brief Utility function to calculate total num of PRBs required to
11119 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11124 * Function : rgSchUtlDlCalc2CwPrb
11126 * Calculate PRBs required for UE to satisfy BO in DL
11128 * Note : Total calculated PRBs will be assigned to *prbReqrd
11131 * @param[in] RgSchCellCb *cell
11132 * @param[in] RgSchUeCb *ue
11133 * @param[in] U32 bo
11134 * @param[out] U32 *prbReqrd
11138 PUBLIC Void rgSchUtlDlCalc2CwPrb
11146 PUBLIC Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd)
11153 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11154 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11159 U8 cfi = dlCell->currCfi;
11161 TRC2(rgSchUtlDlCalc2CwPrb);
11163 if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
11164 (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
11166 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11167 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
11169 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11170 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11171 noRes = ((U64)((bo << 3) << 10)) / (eff1);
11172 /* Get the number of RBs needed for this transmission */
11173 /* Number of RBs = No of REs / No of REs per RB */
11174 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11178 noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
11179 noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
11180 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
11181 iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
11182 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
11183 eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
11185 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11186 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11187 noRes = ((U64)((bo << 3) << 10)) / (eff1 + eff2);
11188 /* Get the number of RBs needed for this transmission */
11189 /* Number of RBs = No of REs / No of REs per RB */
11190 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11193 } /* rgSchUtlDlCalc2CwPrb */
11196 * @brief Utility function to calculate total num of PRBs required to
11197 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11201 * Function : rgSchUtlCalcTotalPrbReq
11203 * This function calls TM specific routine to calculate PRB
11206 * @param[in] RgSchCellCb *cell
11207 * @param[in] RgSchUeCb *ue
11208 * @param[in] U32 bo
11209 * @param[out] U32 *prbReqrd
11213 PUBLIC Void rgSchUtlCalcTotalPrbReq
11221 PUBLIC Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd)
11228 TRC2(rgSchUtlCalcTotalPrbReq);
11230 /* Call TM specific Prb calculation routine */
11231 (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
11234 } /* rgSchUtlCalcTotalPrbReq */
11236 /***********************************************************
11238 * Func : rgSCHUtlFetchPcqiBitSz
11241 * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
11250 **********************************************************/
11252 PRIVATE U8 rgSCHUtlFetchPcqiBitSz
11259 PRIVATE U8 rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt)
11268 RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
11270 TRC3(rgSCHUtlFetchPcqiBitSz);
11271 confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
11272 if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) &&
11273 (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
11279 ri = cqiCb->perRiVal;
11281 switch(confRepMode)
11283 case RGR_PRD_CQI_MOD10:
11289 case RGR_PRD_CQI_MOD11:
11302 else if(numTxAnt == 4)
11315 /* This is number of antenna case 1.
11316 * This is not applicable for Mode 1-1.
11317 * So setting it to invalid value */
11323 case RGR_PRD_CQI_MOD20:
11331 pcqiSz = 4 + cqiCb->label;
11336 case RGR_PRD_CQI_MOD21:
11351 else if(numTxAnt == 4)
11364 /* This might be number of antenna case 1.
11365 * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
11366 * So setting invalid value.*/
11374 pcqiSz = 4 + cqiCb->label;
11378 pcqiSz = 7 + cqiCb->label;
11393 * @brief Utility function to returns the number of subbands based on the
11398 * Function : rgSchUtlGetNumSbs
11400 * Calculate the number of PRBs
11401 * Update the subbandRequired based on the nPrbs and subband size
11403 * @param[in] RgSchCellCb *cell
11404 * @param[in] RgSchUeCb *ue
11405 * @param[in] U32 *numSbs
11409 PUBLIC U8 rgSchUtlGetNumSbs
11416 PUBLIC U8 rgSchUtlGetNumSbs (cell, ue, numSbs)
11423 //Currently hardcoding MAX prb for each UE
11424 nPrb = ue->ue5gtfCb.maxPrb;
11425 (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
11430 * @brief Utility function to insert the UE node into UE Lst based on the
11431 * number of subbands allocated for the UE for the current TTI.
11435 * Function : rgSchUtlSortInsUeLst
11437 * If subbandRequired < Min, then insert at head
11438 * Else If subbandRequired > Max, then insert at tail
11439 * Else, traverse the list and place the node at the appropriate place
11441 * @param[in] RgSchCellCb *cell
11442 * @param[in] RgSchUeCb *ue
11446 PUBLIC U8 rgSchUtlSortInsUeLst
11454 PUBLIC U8 rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired)
11462 CmLList *firstUeInLst;
11463 CmLList *lastUeInLst;
11465 RgSchCmnUlUe *ueUl;
11467 //firstUeInLst = cmLListFirst(ueLst);
11468 CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
11469 if(NULLP == firstUeInLst)
11471 /* first node to be added to the list */
11472 cmLListAdd2Tail(ueLst, node);
11476 /* Sb Required for the UE is less than the first node in the list */
11477 tempUe = (RgSchUeCb *)(firstUeInLst->node);
11478 ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
11480 if(vrbgRequired <= ueUl->vrbgRequired)
11482 cmLListInsCrnt(ueLst, (node));
11486 /* Sb Required for this UE is higher than the UEs in the list */
11487 lastUeInLst = cmLListLast(ueLst);
11488 tempUe = (RgSchUeCb *)(lastUeInLst->node);
11489 if(vrbgRequired >= ueUl->vrbgRequired)
11491 cmLListAdd2Tail(ueLst, (node));
11495 /* This UE needs to be in the middle. Search and insert the UE */
11496 ueInLst = cmLListFirst(ueLst);
11499 tempUe = (RgSchUeCb *)(ueInLst->node);
11501 if(vrbgRequired <= ueUl->vrbgRequired)
11503 cmLListInsCrnt(ueLst, (node));
11507 ueInLst = cmLListNext(ueLst);
11509 } while(NULLP != ueInLst && ueInLst != firstUeInLst);
11518 * @brief Function to Send LCG GBR register to MAC
11522 * Function: rgSCHUtlBuildNSendLcgReg
11524 * Handler for sending LCG GBR registration
11529 * Processing Steps:
11531 * @param[in] RgSchCellCb *cell
11532 * @param[in] CmLteRnti crnti
11533 * @param[in] U8 lcgId
11534 * @param[in] Bool isGbr
11539 PUBLIC S16 rgSCHUtlBuildNSendLcgReg
11547 PUBLIC S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr)
11555 RgInfLcgRegReq lcgRegReq;
11557 TRC3(rgSCHUtlBuildNSendLcgReg);
11559 cmMemset((U8*)&pst, (U8)0, sizeof(Pst));
11560 lcgRegReq.isGbr = isGbr;
11561 lcgRegReq.cellId = cell->cellId;
11562 lcgRegReq.crnti = crnti;
11563 lcgRegReq.lcgId = lcgId;
11564 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
11565 /* code Coverage portion of the test case */
11566 RgSchMacLcgReg(&pst, &lcgRegReq);
11575 * @brief Function to map RGR pucch type to TFU type
11579 * Function: rgSchUtlGetFdbkMode
11585 * Processing Steps:
11587 * @param[in] RgrSchFrmt1b3TypEnum
11588 * @return TfuAckNackMode
11592 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode
11594 RgrSchFrmt1b3TypEnum fdbkType
11597 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType)
11598 RgrSchFrmt1b3TypEnum fdbkType;
11602 TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
11604 TRC2(rgSchUtlGetFdbkMode);
11608 case RG_SCH_UCI_FORMAT_NON_CA:
11609 case RG_SCH_UCI_FORMAT1A_1B:
11611 mode = TFU_UCI_FORMAT_1A_1B;
11614 case RG_SCH_UCI_FORMAT1B_CS:
11616 mode = TFU_UCI_FORMAT_1B_CS;
11619 case RG_SCH_UCI_FORMAT3:
11621 mode = TFU_UCI_FORMAT_3;
11627 #endif /* TFU_TDD */
11628 #endif /* LTE_ADV */
11629 #endif /*TFU_UPGRADE */
11633 * @brief Send Ue SCell delete to SMAC.
11637 * Function : rgSCHUtlSndUeSCellDel2Mac
11638 * This function populates the struct RgInfRlsRnti and
11639 * get the pst for SMac and mark field isUeSCellDel to TRUE which
11640 * indicates that it is a Ue SCell delete.
11644 * @param[in] RgSchCellCb *cell
11645 * @param[in] CmLteRnti rnti
11650 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac
11656 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti)
11662 Inst inst = cell->instIdx;
11663 RgInfRlsRnti rntiInfo;
11665 TRC2(rgSCHUtlSndUeSCellDel2Mac)
11667 RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti));
11668 /* Copy the info to rntiInfo */
11669 rntiInfo.cellId = cell->cellId;
11670 rntiInfo.rnti = rnti;
11671 /* Fix : syed ueId change as part of reestablishment.
11672 * Now SCH to trigger this. CRG ueRecfg for ueId change
11674 rntiInfo.ueIdChng = FALSE;
11675 rntiInfo.newRnti = rnti;
11676 rntiInfo.isUeSCellDel = TRUE;
11677 /* Invoke MAC to release the rnti */
11678 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
11679 RgSchMacRlsRnti(&pst, &rntiInfo);
11684 * @brief Returns max TB supported by a given txMode
11688 * Function : rgSCHUtlGetMaxTbSupp
11689 * Max TB supported for TM Modes (1,2,5,6 and 7) is 1
11693 * @param[in] RgrTxMode txMode
11694 * @return U8 maxTbCount;
11698 PUBLIC U8 rgSCHUtlGetMaxTbSupp
11703 PUBLIC U8 rgSCHUtlGetMaxTbSupp(txMode)
11709 TRC2(rgSCHUtlGetMaxTbSupp);
11733 RETVALUE(maxTbCount);
11737 * @brief Send Ue SCell delete to SMAC.
11741 * Function : rgSCHTomUtlGetTrigSet
11742 * This function gets the triggerset based on cqiReq
11744 * @param[in] RgSchCellCb *cell
11745 * @param[in] RgSchUeCb ueCb
11746 * @param[in] U8 cqiReq,
11747 * @param[out] U8 *triggerSet
11753 PUBLIC Void rgSCHTomUtlGetTrigSet
11761 PRIVATE S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet)
11768 RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
11771 case RG_SCH_APCQI_SERVING_CC:
11773 /* APeriodic CQI request for Current Carrier.*/
11774 U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
11775 *triggerSet = 1 << (7 - sCellIdx);
11778 case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
11780 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
11783 case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
11785 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
11798 * @brief This function updates the value of UE specific DCI sizes
11802 * Function: rgSCHUtlUpdUeDciSize
11803 * Purpose: This function calculates and updates DCI Sizes in bits.
11805 * Invoked by: Scheduler
11807 * @param[in] RgSchCellCb *cell
11808 * @param[in] RgSchUeCb *ueCb
11809 * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI
11814 PUBLIC Void rgSCHUtlUpdUeDciSize
11821 PUBLIC Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit)
11827 U8 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11828 U8 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11829 if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
11831 dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
11832 dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
11834 if (isCsi2Bit == TRUE)
11836 dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
11840 dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
11843 /* Common CSI is always 1 bit DCI 0 */
11844 dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
11846 /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
11847 if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11849 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11851 if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11853 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11856 /* 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 */
11857 dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
11858 dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
11860 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize;
11861 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
11863 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize;
11864 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
11866 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11868 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11869 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11870 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11871 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11872 if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
11874 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
11877 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11878 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11879 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11880 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11881 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
11882 } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
11884 /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
11885 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11886 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11887 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11888 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11890 /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource
11891 * on a secondary cell without an uplink configuration associated with the secondary cell */
11892 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11893 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
11894 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11896 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11897 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11898 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11899 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11900 if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
11902 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
11905 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11906 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11907 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11908 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11909 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
11910 } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
11912 rgSCHEmtcUtlUpdUeDciSize(cell, ueCb);
11917 * @brief This function initialises the DCI Size table
11921 * Function: rgSCHUtlCalcDciSizes
11922 * Purpose: This function calculates and initialises DCI Sizes in bits.
11924 * Invoked by: Scheduler
11926 * @param[in] RgSchCellCb *cell
11931 PUBLIC Void rgSCHUtlCalcDciSizes
11936 PUBLIC Void rgSCHUtlCalcDciSizes(cell)
11942 U32 bits = 0, idx = 0;
11944 switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
11946 case TFU_DCI_FORMAT_0:
11948 /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
11950 /*-- Calculate resource block assignment bits need to be set
11951 Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
11952 bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
11953 while ((bits & 0x8000) == 0)
11960 dciSize = 1 /* DCI 0 bit indicator */ + \
11961 1 /* Frequency hoping enable bit field */ + \
11962 (U8)bits /* For frequency Hopping */ + \
11969 2 /* UL Index Config 0 or DAI Config 1-6 */
11973 cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
11975 /* If hoping flag is enabled */
11976 if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
11978 cell->dciSize.dci0HopSize = 1;
11982 cell->dciSize.dci0HopSize = 2;
11985 /* Update common non-CRNTI scrambled DCI 0/1A flag */
11986 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
11988 case TFU_DCI_FORMAT_1A:
11990 /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
11993 /* Calculate resource block assignment bits need to be set
11994 Which is ln(N(N+1)/2) */
11995 bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
11996 while ((bits & 0x8000) == 0)
12003 dciSize += 1 /* Format 1A */ + \
12004 1 /* Local or Distributed */ + \
12005 (U8)bits /* Resource block Assignment */ + \
12008 4 /* HARQ Proc Id */ +
12010 3 /* HARQ Proc Id */ +
12020 cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
12022 /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI,
12023 * and the number of information bits in format 1A is less than that of format 0,
12024 * zeros shall be appended to format 1A until the payload size equals that of format 0. */
12025 /* Compare the size with DCI 1A and DCI 0 and consider the greater one */
12026 if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
12028 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
12030 /* If the number of information bits in format 1A belongs to one of the sizes in
12031 * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
12032 dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
12033 cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
12035 case TFU_DCI_FORMAT_1:
12037 /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
12039 if (cell->bwCfg.dlTotalBw > 10)
12041 dciSize = 1; /* Resource Allocation header bit */
12044 /* Resouce allocation bits Type 0 and Type 1 */
12045 bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
12046 if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
12051 dciSize += (U8)bits /* Resource Allocation bits */ + \
12059 2 /* Redunancy Version */ + \
12068 cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
12070 cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
12073 /* If the UE is not configured to decode PDCCH with CRC
12074 * scrambled by the C-RNTI and the number of information bits in format 1
12075 * is equal to that for format 0/1A, one bit of value zero shall be appended
12077 if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
12079 cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
12082 /* If the number of information bits in format 1 belongs to one of the sizes in
12083 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until
12084 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1
12085 * and is not equal to that of format 0/1A mapped onto the same search space. */
12086 cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
12087 } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
12089 case TFU_DCI_FORMAT_2:
12091 /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
12093 if (cell->bwCfg.dlTotalBw > 10)
12095 dciSize = 1; /* Resource Allocation bit */
12098 dciSize += (U8)bits /* Resource Allocation bits */ + \
12106 1 /* CW Swap Flag */ + \
12107 5 /* MCS for TB1 */+ \
12108 1 /* NDI for TB1 */+ \
12109 2 /* RV for TB1 */ + \
12110 5 /* MCS for TB2 */+ \
12111 1 /* NDI for TB2 */+ \
12112 2 /* RV for TB2 */;
12113 if (cell->numTxAntPorts == 2)
12117 else if (cell->numTxAntPorts == 4)
12121 cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
12122 cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
12124 case TFU_DCI_FORMAT_2A:
12126 /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
12128 if (cell->bwCfg.dlTotalBw > 10)
12130 dciSize = 1; /* Resource Allocation bit */
12133 dciSize += (U8)bits /* Resource Allocation bits */ + \
12141 1 /* CW Swap Flag */ + \
12142 5 /* MCS for TB1 */+ \
12143 1 /* NDI for TB1 */+ \
12144 2 /* RV for TB1 */ + \
12145 5 /* MCS for TB2 */+ \
12146 1 /* NDI for TB2 */+ \
12147 2 /* RV for TB2 */;
12148 if (cell->numTxAntPorts == 4)
12152 cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
12153 cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
12154 rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
12156 case TFU_DCI_FORMAT_3:
12158 /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
12159 cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
12160 if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
12162 cell->dciSize.size[TFU_DCI_FORMAT_3]++;
12165 case TFU_DCI_FORMAT_3A:
12167 /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
12168 cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
12171 case TFU_DCI_FORMAT_6_0A:
12173 rgSCHEmtcGetDciFrmt60ASize(cell);
12175 case TFU_DCI_FORMAT_6_1A:
12177 rgSCHEmtcGetDciFrmt61ASize(cell);
12182 /* DCI format not supported */
12189 * @brief Handler for the CPU OvrLd related state adjustment.
12193 * Function : rgSCHUtlCpuOvrLdAdjItbsCap
12195 * Processing Steps:
12196 * - Record dl/ulTpts
12197 * - Adjust maxItbs to acheive target throughputs
12199 * @param[in] RgSchCellCb *cell
12203 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap
12208 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap(cell)
12214 TRC3(rgSCHUtlCpuOvrLdAdjItbsCap)
12216 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP |
12217 RGR_CPU_OVRLD_DL_TPT_DOWN))
12219 /* Regulate DL Tpt for CPU overload */
12220 if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
12222 tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
12223 /* Upto 0.5% drift in measured vs target tpt is ignored */
12224 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12226 cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
12231 tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
12232 /* Upto 0.5% drift in measured vs target tpt is ignored */
12233 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12235 cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
12238 #ifdef CPU_OL_DBG_PRINTS
12239 printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt,
12240 cell->thresholds.maxDlItbs);
12244 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP |
12245 RGR_CPU_OVRLD_UL_TPT_DOWN))
12247 /* Regualte DL Tpt for CPU overload */
12248 if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
12250 tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
12251 /* Upto 1% drift in measured vs target tpt is ignored */
12252 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12254 cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
12259 tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
12260 /* Upto 1% drift in measured vs target tpt is ignored */
12261 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12263 cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
12266 #ifdef CPU_OL_DBG_PRINTS
12267 printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt,
12268 cell->thresholds.maxUlItbs);
12275 * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
12279 * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12281 * Processing Steps:
12282 * - Validate the config params.
12283 * - Update numUEperTTi CPU OL related information.
12284 * - If successful, return ROK else RFAILED.
12286 * @param[in] RgSchCellCb *cell
12287 * @param[in] U8 cnrtCpuOvrLdIns
12291 PRIVATE Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12297 PRIVATE S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns)
12299 U8 crntCpuOvrLdIns;
12302 RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl);
12303 RgSchCmnCell *cellSch;
12304 U8 maxUeNewDlTxPerTti;
12305 U8 maxUeNewUlTxPerTti;
12306 U8 tmpSubFrame = 0;
12307 #ifdef CPU_OL_DBG_PRINTS
12313 cellSch = RG_SCH_CMN_GET_CELL(cell);
12315 maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti;
12316 maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
12318 /* Calculate Maximum Decremen */
12319 maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12320 maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12322 /* Check for DL CPU Commands */
12323 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI )
12325 /* Decrement till 90% of maxUeNewDlTxPerTti */
12326 if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
12328 tmpSubFrame = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12329 cpuInstr->dlNxtIndxDecNumUeTti++;
12330 if ( cpuInstr->maxUeNewTxPerTti[tmpSubFrame] > 1 )
12332 cpuInstr->maxUeNewTxPerTti[tmpSubFrame]--;
12336 #ifdef CPU_OL_DBG_PRINTS
12337 printf("CPU_OL_TTI__ERROR\n");
12339 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12342 #ifdef CPU_OL_DBG_PRINTS
12343 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12345 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12346 cpuInstr->dlNxtIndxDecNumUeTti);
12348 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
12350 if ( cpuInstr->dlNxtIndxDecNumUeTti > 0)
12352 cpuInstr->dlNxtIndxDecNumUeTti--;
12353 tmpSubFrame = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12354 if ( cpuInstr->maxUeNewTxPerTti[tmpSubFrame] < maxUeNewDlTxPerTti )
12356 cpuInstr->maxUeNewTxPerTti[tmpSubFrame]++;
12360 #ifdef CPU_OL_DBG_PRINTS
12361 printf("CPU_OL_TTI__ERROR\n");
12363 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12366 #ifdef CPU_OL_DBG_PRINTS
12367 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12369 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12370 cpuInstr->dlNxtIndxDecNumUeTti);
12372 /* Check for UL CPU commands */
12373 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
12375 /* Decrement till 90% of maxUeNewDlTxPerTti */
12376 if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
12378 tmpSubFrame = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12379 cpuInstr->ulNxtIndxDecNumUeTti++;
12380 if ( cpuInstr->maxUeNewRxPerTti[tmpSubFrame] > 1 )
12382 cpuInstr->maxUeNewRxPerTti[tmpSubFrame]--;
12386 #ifdef CPU_OL_DBG_PRINTS
12387 printf("CPU_OL_TTI__ERROR\n");
12389 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12392 #ifdef CPU_OL_DBG_PRINTS
12393 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12395 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12396 cpuInstr->dlNxtIndxDecNumUeTti);
12398 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
12400 if ( cpuInstr->ulNxtIndxDecNumUeTti > 0)
12402 cpuInstr->ulNxtIndxDecNumUeTti--;
12403 tmpSubFrame = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12404 if ( cpuInstr->maxUeNewRxPerTti[tmpSubFrame] < maxUeNewUlTxPerTti )
12406 cpuInstr->maxUeNewRxPerTti[tmpSubFrame]++;
12410 #ifdef CPU_OL_DBG_PRINTS
12411 printf("CPU_OL_TTI__ERROR\n");
12413 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12416 #ifdef CPU_OL_DBG_PRINTS
12417 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12419 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12420 cpuInstr->dlNxtIndxDecNumUeTti);
12422 #ifdef CPU_OL_DBG_PRINTS
12423 /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
12424 printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
12425 printf("DL Sf numUePerTti:");
12426 for ( idx = 0; idx < 10 ; idx ++ )
12428 printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]);
12430 printf("\nUL Sf numUePerTti:");
12431 for ( idx = 0; idx < 10 ; idx ++ )
12433 printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]);
12439 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
12442 * @brief Handler for the CPU OvrLd related cell Recfg.
12446 * Function : rgSCHUtlResetCpuOvrLdState
12448 * Processing Steps:
12449 * - Validate the config params.
12450 * - Update CPU OL related state information.
12451 * - If successful, return ROK else RFAILED.
12453 * @param[in] RgSchCellCb *cell
12454 * @param[in] U8 cnrtCpuOvrLdIns
12460 PUBLIC S16 rgSCHUtlResetCpuOvrLdState
12466 PUBLIC S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns)
12468 U8 crntCpuOvrLdIns;
12473 RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
12476 TRC3(rgSCHUtlResetCpuOvrLdState)
12478 #ifdef CPU_OL_DBG_PRINTS
12479 printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
12481 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd");
12483 if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
12485 /* The CPU OL instruction received with RESET (0), hence reset it */
12486 #ifdef CPU_OL_DBG_PRINTS
12487 printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
12489 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD");
12490 cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
12491 /* Reset the max UL and DL itbs to 26 */
12492 cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
12493 cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
12494 /* Reset the num UE per TTI intructions */
12495 cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
12496 cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
12497 for ( idx = 0; idx < 10; idx++ )
12499 cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] =
12500 schCmnCell->dl.maxUeNewTxPerTti;
12501 cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] =
12502 schCmnCell->ul.maxUeNewTxPerTti;
12507 /* Check and Update numUEPer TTI based CPU overload instruction before
12508 * going for TP based CPU OL
12509 * TTI based intrcuctions shall be > 0xF */
12510 if ( crntCpuOvrLdIns > 0xF )
12512 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
12513 /* If need to have both TP and numUePerTti instrcution together in
12514 * one command then dont return from here */
12518 crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
12519 (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
12520 if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) &&
12521 (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
12523 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12526 crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
12527 (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
12528 if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) &&
12529 (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
12531 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12534 if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
12536 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12540 cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
12544 if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
12546 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
12547 (cell->measurements.ulTpt * 3 )/100;
12551 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
12552 (cell->measurements.ulTpt * 2 )/100;
12554 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to "
12555 "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
12556 #ifdef CPU_OL_DBG_PRINTS
12557 printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
12558 cell->measurements.ulTpt);
12564 if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
12566 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
12567 (cell->measurements.dlTpt * 1 )/100;
12571 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
12572 (cell->measurements.dlTpt * 1 )/100;
12574 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to "
12575 "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
12577 #ifdef CPU_OL_DBG_PRINTS
12578 printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
12579 cell->measurements.dlTpt);
12582 rgSCHUtlCpuOvrLdAdjItbsCap(cell);
12586 PUBLIC S16 rgSCHUtlAddToResLst
12589 RgSchIotRes *iotRes
12592 cmLListAdd2Tail(cp, &iotRes->resLnk);
12593 iotRes->resLnk.node = (PTR)iotRes;
12596 PUBLIC S16 rgSCHUtlDelFrmResLst
12599 RgSchIotRes *iotRes
12602 CmLListCp *cp = NULLP;
12603 RgSchEmtcUeInfo *emtcUe = NULLP;
12604 emtcUe = RG_GET_EMTC_UE_CB(ue);
12605 if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
12607 cp = &emtcUe->ulResLst;
12608 }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
12610 cp = &emtcUe->dlResLst;
12613 RLOG0(L_INFO, "*****restype mismatch");
12619 RLOG0(L_INFO,"****error count*****\n");
12623 cmLListDelFrm(cp, &iotRes->resLnk);
12624 iotRes->resLnk.node = NULLP;
12628 /**********************************************************************
12631 **********************************************************************/