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 slot. It removes the list of PDCCHs allocated
663 * in the prior use of this slot 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 slot 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 slot.
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 slot. It removes the list of PHICHs allocated
1296 * in the prior use of this slot 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 slot data structure for a cell
1341 * Function: rgSCHUtlSubFrmGet
1342 * Purpose: This function resets the slot data structure
1343 * when the slot 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 slot is selected */
1375 dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
1376 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1377 sf = cell->subFrms[dlIdx];
1387 * @brief This function returns slot data structure for a cell
1391 * Function: rgSCHUtlSubFrmPut
1392 * Purpose: This function resets the slot data structure
1393 * when the slot 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, sf->rntpInfo.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 slot occasions
2201 * Function: rgSCHUtlUpdPrachOcc
2202 * Purpose: This function updates the PRACH slots 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_slot)
2249 if(cellCfg->ulStartSfIdx == count)
2251 size = cell->rachCfg.raOccasion.size;
2252 cell->rachCfg.raOccasion.slotNum[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 slot 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.slotNum[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 slot 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 maxDlslots = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
2386 maxslots = 2 * maxDlslots;
2387 cell->numDlSubfrms = maxslots;
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 *) * maxslots);
2421 if (cell->subFrms == NULLP)
2426 /* Create memory for each frame. */
2427 for(i = 0; i < maxslots; i++)
2429 while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
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;
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 *) * maxslots);
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 slots and thereby perform the initialization */
2503 for (i = 0; i < maxslots; i++)
2505 if((i > 0) && (i%maxDlslots == 0))
2510 frm.slot = 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 slots 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_slotS */
2586 for(i = 0; i < RGSCH_NUM_DL_slotS; 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_slotS */
2647 if (i != RGSCH_NUM_DL_slotS)
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 slots and thereby perform the initialization */
2668 for (i = 0; i < RGSCH_NUM_DL_slotS; 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.slot = 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 slot.
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 maxslots = cell->numDlSubfrms;
2788 maxslots = RGSCH_NUM_DL_slotS;
2792 /* Invoke the index for scheduler, cell deletion */
2793 cell->sc.apis->rgSCHFreeCell(cell);
2795 /* Release the slots allocated */
2796 for (i = 0; i < maxslots; 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 slot pointers */
2838 /* ccpu00117052 - MOD - Passing double pointer
2839 for proper NULLP assignment*/
2840 rgSCHUtlFreeSBuf(inst,
2841 (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
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 slot
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 slot
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 slot.
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 slot
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 slot
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 slot
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 slot
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 slot 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 slot 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 slot 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 slot 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 slot 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+SCH_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 slot */
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 slots*/
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 DU APP
7100 * Function: schSendCfgCfm
7102 * This API is invoked to send configuration confirm from Scheduler to DU
7105 * @param[in] Pst pst
7106 * @param[in] RgrCfgTransId transId
7107 * @param[in] U8 status
7113 PUBLIC S16 schSendCfgCfm
7117 RgrCfgTransId transId,
7121 PUBLIC S16 schSendCfgCfm(reg, pool, transId, status)
7124 RgrCfgTransId transId;
7132 cmMemset((U8 *)(&cfmPst), 0, sizeof(Pst));
7134 cfmPst.srcEnt = (Ent)ENTDUAPP;
7135 cfmPst.srcInst = (Inst) 0;
7136 cfmPst.srcProcId = SFndProcId();
7137 cfmPst.dstEnt = (Ent)ENTRG;
7138 cfmPst.dstInst = (Inst) 0;
7139 cfmPst.dstProcId = SFndProcId();
7140 cfmPst.selector = RGR_SEL_LC;
7141 cfmPst.region = reg;
7144 if(RgUiRgrCfgCfm(&cfmPst,transId, status) != ROK)
7146 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"schSendCfgCfm: RgUiRgrCfgCfm Failed ");
7147 printf("\nschSendCfgCfm: RgUiRgrCfgCfm Failed ");
7151 } /* schSendCfgCfm*/
7154 * @brief API for sending TTI indication from Scheduler to RRM.
7158 * Function: rgSCHUtlRgrTtiInd
7160 * This API is invoked to send TTI indication from Scheduler instance to RRM.
7161 * This API fills in Pst structure and RgrTtiIndInfo
7163 * @param[in] cell RgSchCellCb
7164 * @param[in] CmLteTimingInfo status
7170 PUBLIC S16 rgSCHUtlRgrTtiInd
7173 RgrTtiIndInfo *rgrTti
7176 PUBLIC S16 rgSCHUtlRgrTtiInd(cell, rgrTti)
7178 RgrTtiIndInfo *rgrTti;
7182 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
7184 extern Bool g_usettitmr;
7185 extern Void mtTmrHdlrPublic(void);
7188 TRC2(rgSCHUtlRgrTtiInd)
7191 rgrSap = cell->rgrSap;
7192 if (rgrSap->sapSta.sapState != LRG_BND)
7194 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
7195 "rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ",
7196 rgrSap->sapSta.sapState);
7199 RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst),
7200 cell->rgrSap->sapCfg.suId, rgrTti);
7208 } /* rgSCHUtlRgrTtiInd*/
7210 /** @brief This function is called by rgMacSchSfRecpInd. This function invokes the
7211 * scheduler with the information of the received Data and any Control Elements
7219 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
7221 * - If UE exists then update the Schduler with any MAC CEs if present.
7222 * - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3
7224 * @param [in] RgSchCellCb *cellCb
7225 * @param [in] RgSchUeCb *ueCb
7226 * @param [in] CmLteRnti rnti
7227 * @param [in] RgMacPdu *pdu
7228 * @param [in] RgSchErrInfo *err
7235 PUBLIC S16 rgSCHUtlProcMsg3
7237 RgInfSfDatInd *subfrmInfo,
7238 RgSchCellCb *cellCb,
7245 PUBLIC S16 rgSCHUtlProcMsg3 (subfrmInfo, cellCb, ueCb, rnti, pdu, err)
7246 RgInfSfDatInd *subfrmInfo;
7247 RgSchCellCb *cellCb;
7257 TRC2(rgSCHUtlProcMsg3)
7260 /* must have an raCb for this case */
7261 raCb = rgSCHDbmGetRaCb (cellCb, rnti);
7264 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, "RNTI:%d Received MSG3, unable to "
7269 /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that
7270 * effBsr of current case only will be considered in scheduling of ContResLst*/
7271 ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err);
7274 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Processing failed in the RAM "
7278 /* if ueCb is present */
7281 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err);
7287 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7288 * scheduler with the information of the received Data.
7292 * Function: rgSCHUtlSpsRelInd
7297 * @param [in] RgSchCellCb *cellCb
7298 * @param [in] RgSchUeCb *ueCb
7299 * @param [in] Bool *isExplRel
7306 PUBLIC S16 rgSCHUtlSpsRelInd
7308 RgSchCellCb *cellCb,
7313 PUBLIC S16 rgSCHUtlSpsRelInd (cellCb, ueCb, isExplRel)
7314 RgSchCellCb *cellCb;
7319 TRC2(rgSCHUtlSpsRelInd);
7320 cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel);
7322 } /* end of rgSCHUtlSpsRelInd */
7325 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7326 * scheduler with the information of the received Data.
7330 * Function: rgSCHUtlSpsActInd
7335 * @param [in] RgSchCellCb *cellCb
7336 * @param [in] RgSchUeCb *ueCb
7337 * @param [in] U16 spsSduSize
7344 PUBLIC S16 rgSCHUtlSpsActInd
7346 RgSchCellCb *cellCb,
7351 PUBLIC S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize)
7352 RgSchCellCb *cellCb;
7357 TRC2(rgSCHUtlSpsActInd);
7358 cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize);
7360 } /* end of rgSCHUtlSpsActInd */
7363 #endif /* LTEMAC_SPS */
7367 * @brief This API is invoked to send uplink group power control request to PHY.
7371 * Function : rgSCHUtlTfuGrpPwrCntrlReq
7373 * This API is invoked to send uplink group power control request to PHY.
7374 * It fills in the Pst structure, spId value and invokes group power
7375 * control request primitive at TFU.
7377 * @param[in] TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7383 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq
7387 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7390 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq(inst, sapId, grpPwrCntrlReq)
7393 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq;
7397 RgSchLowSapCb *tfuSap;
7400 TRC2(rgSCHUtlTfuGrpPwrCntrlReq);
7402 /* Get the lower SAP control block from the layer control block. */
7403 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7404 if (tfuSap->sapSta.sapState != LRG_BND)
7406 RLOG_ARG1(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7407 "rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState);
7410 cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
7411 if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK)
7413 RLOG_ARG0(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7414 "rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed");
7417 } /* rgSCHUtlTfuGrpPwrCntrlReq */
7421 * @brief This API is invoked to send Control Info to PHY.
7425 * Function : rgSCHUtlTfuCntrlReq
7427 * This API is invoked to send Control Info to PHY. It
7428 * fills in the Pst structure, spId value and invokes Cntrl
7429 * request primitive at TFU.
7431 * @param[in] TfuCntrlReqInfo *cntrlReq
7437 PUBLIC S16 rgSCHUtlTfuCntrlReq
7441 TfuCntrlReqInfo *cntrlReq
7444 PUBLIC S16 rgSCHUtlTfuCntrlReq(inst, sapId, cntrlReq)
7447 TfuCntrlReqInfo *cntrlReq;
7451 RgSchLowSapCb *tfuSap;
7453 TRC2(rgSCHUtlTfuCntrlReq)
7455 /* Get the lower SAP control block from the layer control block. */
7456 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7459 if (tfuSap->sapSta.sapState != LRG_BND)
7461 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Lower SAP not bound (%d) ",
7462 tfuSap->sapSta.sapState);
7463 RGSCH_FREE_MEM(cntrlReq);
7468 /* Using local variable for pst is unnecessary - for optimization */
7469 if((ret = RgLiTfuCntrlReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7472 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Call to RgLiTfuCntrlReq() failed");
7475 } /* rgSCHUtlTfuCntrlReq*/
7478 /* FOR ACK NACK REP */
7481 * @brief This API is invoked to tell the DL Scheduler to add the UE back into
7482 * its scheduling queues.
7486 * Function : rgSCHUtlDlActvtUe
7488 * This API is invoked from Measurement gap moduled.
7490 * @param[in] RgSchCellCb *cell
7491 * @param[in] RgSchUeCb *ueCb
7498 PUBLIC S16 rgSCHUtlDlActvtUe
7504 PUBLIC S16 rgSCHUtlDlActvtUe(cell, ue)
7509 TRC2(rgSCHUtlDlActvtUe);
7510 cell->sc.apis->rgSCHActvtDlUe(cell, ue);
7515 * @brief This API is invoked to tell the UL Scheduler to add the UE back into
7516 * its scheduling queues.
7520 * Function : rgSCHUtlUlActvtUe
7522 * This API is invoked from Measurement gap moduled.
7524 * @param[in] RgSchCellCb *cell
7525 * @param[in] RgSchUeCb *ueCb
7532 PUBLIC S16 rgSCHUtlUlActvtUe
7538 PUBLIC S16 rgSCHUtlUlActvtUe(cell, ue)
7543 TRC2(rgSCHUtlUlActvtUe);
7544 cell->sc.apis->rgSCHActvtUlUe(cell, ue);
7549 * @brief This API is invoked to send Reception Request Info to PHY.
7553 * Function : rgSCHUtlTfuRecpReq
7555 * This API is invoked to send Reception Request Info to PHY. It
7556 * fills in the Pst structure, spId value and invokes Reception
7557 * request primitive at TFU.
7559 * @param[in] TfuRecpReqInfo *recpReq
7565 PUBLIC S16 rgSCHUtlTfuRecpReq
7569 TfuRecpReqInfo *recpReq
7572 PUBLIC S16 rgSCHUtlTfuRecpReq(inst, sapId, recpReq)
7575 TfuRecpReqInfo *recpReq;
7579 RgSchLowSapCb *tfuSap;
7581 TRC2(rgSCHUtlTfuRecpReq)
7583 /* Get the lower SAP control block from the layer control block. */
7584 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7587 if (tfuSap->sapSta.sapState != LRG_BND)
7589 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Lower SAP not bound (%d) ",
7590 tfuSap->sapSta.sapState);
7591 RGSCH_FREE_MEM(recpReq);
7596 /* Using local variable for pst is unnecessary - for optimization */
7597 if((ret = RgLiTfuRecpReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7600 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Call to RgLiTfuRecpReq() failed");
7603 } /* rgSCHUtlTfuRecpReq */
7605 /** @brief This function Validates the SAP information received along with the
7606 * primitive from the lower layer.
7608 * Function: rgSCHUtlValidateTfuSap
7610 * Validates SAP information.
7611 * @param suId The SAP Id
7617 PUBLIC S16 rgSCHUtlValidateTfuSap
7623 PUBLIC S16 rgSCHUtlValidateTfuSap(inst, suId)
7628 RgSchLowSapCb *tfuSap;
7630 TRC2(rgSCHUtlValidateTfuSap)
7632 if(suId >= rgSchCb[inst].numSaps)
7634 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Incorrect SuId");
7637 tfuSap = &(rgSchCb[inst].tfuSap[suId]);
7639 /* First lets check the suId */
7640 if( suId != tfuSap->sapCfg.suId)
7642 RLOG_ARG2(L_ERROR,DBG_INSTID,inst,"Incorrect SuId. Configured (%d) Recieved (%d)",
7643 tfuSap->sapCfg.suId, suId);
7646 if (tfuSap->sapSta.sapState != LRG_BND)
7648 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"Lower SAP not enabled SuId (%d)",
7649 tfuSap->sapCfg.suId);
7653 } /* end of rgSCHUtlValidateTfuSap */
7657 * Fun: rgSCHUtlAllocEventMem
7659 * Desc: This function allocates event memory
7661 * Ret: ROK - on success
7662 * RFAILED - on failure
7670 PUBLIC S16 rgSCHUtlAllocEventMem
7677 PUBLIC S16 rgSCHUtlAllocEventMem(inst, memPtr, memSize)
7684 VOLATILE U32 startTime=0;
7686 TRC2(rgSCHUtlAllocEventMem)
7688 sMem.region = rgSchCb[inst].rgSchInit.region;
7689 sMem.pool = rgSchCb[inst].rgSchInit.pool;
7691 #if (ERRCLASS & ERRCLS_DEBUG)
7694 RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize,
7695 "rgAllocEventMem(): memSize invalid\n");
7698 #endif /* ERRCLASS & ERRCLS_DEBUG */
7700 SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
7702 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
7703 MS_BUF_ADD_ALLOC_CALLER();
7705 #ifdef TFU_ALLOC_EVENT_NO_INIT
7706 if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7708 if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7711 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed.");
7715 SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
7717 } /* end of rgSCHUtlAllocEventMem*/
7721 * Fun: rgGetEventMem
7723 * Desc: This function allocates event memory
7725 * Ret: ROK - on success
7726 * RFAILED - on failure
7734 PUBLIC S16 rgSCHUtlGetEventMem
7741 PUBLIC S16 rgSCHUtlGetEventMem(ptr, len, memCp)
7749 TRC2(rgSCHUtlGetEventMem)
7750 #ifdef TFU_ALLOC_EVENT_NO_INIT
7751 ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
7753 ret = cmGetMem(memCp, len, (Ptr *)ptr);
7756 } /* end of rgSCHUtlGetEventMem*/
7762 * @brief Handler to allocate memory for ACK/NACk feedback information
7766 * Function : rgSCHUtlAllocUeANFdbkInfo
7768 * It allocates memory for the UE related ACK NACK information.
7770 * @param[in] RgSchUeCb *ue
7774 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo
7780 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx)
7787 TRC2(rgSCHUtlAllocUeANFdbkInfo);
7789 if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
7790 (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
7791 ue->cell->ackNackFdbkArrSize) != ROK)
7796 for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
7798 rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
7801 /* Set it to the first index */
7802 ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
7804 } /* rgSCHUtlAllocUeANFdbkInfo */
7807 * @brief Handler to release memory for ACK/NACk feedback information
7811 * Function : rgSCHUtlDelUeANFdbkInfo
7813 * It releases memory for the UE related ACK NACK information.
7815 * @param[in] RgSchUeCb *ue
7819 PUBLIC Void rgSCHUtlDelUeANFdbkInfo
7825 PUBLIC Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx)
7830 TRC2(rgSCHUtlDelUeANFdbkInfo);
7832 /* ccpu00117052 - MOD - Passing double pointer
7833 for proper NULLP assignment*/
7834 rgSCHUtlFreeSBuf(ue->cell->instIdx,
7835 (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
7836 ue->cell->ackNackFdbkArrSize);
7839 } /* rgSCHUtlDelUeANFdbkInfo */
7842 * @brief Handler to initialise UE ACK/NACk feedback information
7846 * Function : rgSCHUtlInitUeANFdbkInfo
7848 * It initialises UE related ACK NACK information.
7850 * @param[in] RgSchTddANInfo *anFdInfo
7854 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo
7856 RgSchTddANInfo *anFdInfo
7859 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo)
7860 RgSchTddANInfo *anFdInfo;
7863 TRC2(rgSCHUtlInitUeANFdbkInfo);
7865 anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
7867 anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
7868 anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
7869 anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
7872 } /* rgSCHUtlInitUeANFdbkInfo */
7875 * @brief Handler to get UE related ACK NACK feedback information
7879 * Function : rgSCHUtlGetUeANFdbkInfo
7881 * It gets the UE related ACK NACK information based on
7882 * SFN and slot number.
7884 * @param[in] RgSchUeCb *ueCb
7885 * @param[in] CmLteTimingInfo *time
7886 * @return RgSchTddANInfo*
7889 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo
7892 CmLteTimingInfo *timeInfo,
7896 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx)
7898 CmLteTimingInfo *timeInfo;
7904 TRC2(rgSCHUtlGetUeANFdbkInfo);
7906 for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
7908 if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
7909 (timeInfo->slot == ueCb->cellInfo[servCellIdx]->anInfo[idx].slot))
7911 RETVALUE(&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
7916 } /* rgSCHUtlGetUeANFdbkInfo */
7919 * @brief To get downlink slot index
7923 * Function: rgSCHUtlGetDlSfIdx
7924 * Purpose: Gets downlink slot index based on SFN and slot no
7926 * @param[in] CmLteTimingInfo *timeInfo
7927 * @param[in] RgSchCellCb *cell
7932 PUBLIC U8 rgSCHUtlGetDlSfIdx
7935 CmLteTimingInfo *timeInfo
7938 PUBLIC U8 rgSCHUtlGetDlSfIdx(cell, timeInfo)
7940 CmLteTimingInfo *timeInfo;
7944 TRC2(rgSCHUtlGetDlSfIdx);
7946 idx = RGSCH_NUM_SUB_FRAMES - \
7947 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7948 idx = ((idx * timeInfo->sfn) + \
7949 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->slot]) - 1;
7950 idx = idx % cell->numDlSubfrms;
7956 * @brief To get the next downlink slot
7960 * Function: rgSCHUtlGetNxtDlSfInfo
7961 * Purpose: Gets next downlink slot based on current DL slot
7963 * @param[in] CmLteTimingInfo curDlTime
7964 * @param[in] RgSchCellCb *cell
7965 * @param[in] RgSchDlSf *dlSf
7966 * @param[in] RgSchDlSf **nxtDlsf
7967 * @param[in] CmLteTimingInfo *nxtDlTime
7972 PUBLIC Void rgSCHUtlGetNxtDlSfInfo
7974 CmLteTimingInfo curDlTime,
7977 RgSchDlSf **nxtDlsf,
7978 CmLteTimingInfo *nxtDlTime
7981 PUBLIC Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime)
7982 CmLteTimingInfo curDlTime;
7985 RgSchDlSf **nxtDlsf;
7986 CmLteTimingInfo *nxtDlTime;
7989 U16 idx = curDlTime.slot;
7991 TRC2(rgSCHUtlGetNxtDlSfInfo);
7997 idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
7999 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
8000 != RG_SCH_TDD_DL_slot);
8001 RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
8002 *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
8003 if(dlSf->dlFdbkInfo.slot != (*nxtDlsf)->dlFdbkInfo.slot)
8012 * @brief To get the previous downlink slot
8016 * Function: rgSCHUtlGetPrevDlSfInfo
8017 * Purpose: Gets previous downlink slot based on current DL slot
8019 * @param[in] RgSchCellCb *cell
8020 * @param[in] CmLteTimingInfo curDlTime
8021 * @param[in] CmLteTimingInfo *prevDlTime
8022 * @param[in] U8 *numSubfrm
8027 PUBLIC Void rgSCHUtlGetPrevDlSfInfo
8030 CmLteTimingInfo curDlTime,
8031 CmLteTimingInfo *prevDlTime,
8035 PUBLIC Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm)
8037 CmLteTimingInfo curDlTime;
8038 CmLteTimingInfo *prevDlTime;
8042 S16 idx = curDlTime.slot;
8044 TRC2(rgSCHUtlGetPrevDlSfInfo);
8051 idx = RGSCH_NUM_SUB_FRAMES-1;
8054 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
8055 != RG_SCH_TDD_DL_slot);
8057 RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
8062 /* Added Holes Management functions for Adaptive Re transmission */
8063 /******* </AllocHolesMemMgmnt>: START *****/
8064 /***********************************************************
8066 * Func : rgSCHUtlUlSfInit
8068 * Desc : UL slot init.
8076 **********************************************************/
8078 PUBLIC S16 rgSCHUtlUlSfInit
8086 PUBLIC S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf)
8094 TRC2(rgSCHUtlUlSfInit);
8102 if(cell->ulDlCfgIdx == 0)
8104 /* Store the Uplink slot number corresponding to the idx */
8105 sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6];
8108 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
8109 sizeof(RgSchUlAllocDb));
8114 ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
8117 /* ccpu00117052 - MOD - Passing double pointer
8118 for proper NULLP assignment*/
8119 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8120 sizeof(RgSchUlAllocDb));
8123 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
8124 sizeof(RgSchUlHoleDb));
8127 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8128 /* ccpu00117052 - MOD - Passing double pointer
8129 for proper NULLP assignment*/
8130 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8131 sizeof(RgSchUlAllocDb));
8134 /* Initialize the hole with CFI 1 Pusch Bw Info */
8135 ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (U8)(maxUePerSf + 2), \
8136 0, cell->dynCfiCb.bwInfo[1].numSb);
8140 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8141 /* ccpu00117052 - MOD - Passing double pointer
8142 for proper NULLP assignment*/
8143 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8144 sizeof(RgSchUlAllocDb));
8145 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8146 sizeof(RgSchUlHoleDb));
8149 cmLListInit(&sf->reTxLst);
8151 /* Fix ccpu00120610*/
8152 sf->allocCountRef = &sf->allocDb->count;
8154 /* initialize UL available subbands for current sub-frame */
8155 sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
8157 sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
8158 sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
8159 for(index = 0; index < MAX_5GTF_BEAMS; index++)
8161 sf->sfBeamInfo[index].totVrbgAllocated = 0;
8162 sf->sfBeamInfo[index].totVrbgRequired = 0;
8163 sf->sfBeamInfo[index].vrbgStart = 0;
8171 /***********************************************************
8173 * Func : rgSCHUtlUlSfDeinit
8175 * Desc : Deinitialises a slot
8183 **********************************************************/
8185 PUBLIC Void rgSCHUtlUlSfDeinit
8191 PUBLIC Void rgSCHUtlUlSfDeinit(cell, sf)
8196 TRC2(rgSCHUtlUlSfDeinit);
8199 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8200 /* ccpu00117052 - MOD - Passing double pointer
8201 for proper NULLP assignment*/
8202 /* ccpu00117052 - MOD - Passing double pointer
8203 for proper NULLP assignment*/
8204 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8205 sizeof(RgSchUlAllocDb));
8209 rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
8210 /* ccpu00117052 - MOD - Passing double pointer
8211 for proper NULLP assignment*/
8212 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8213 sizeof(RgSchUlHoleDb));
8218 /***********************************************************
8220 * Func : rgSCHUtlUlAllocDbInit
8222 * Desc : Initialise allocation DB
8224 * Ret : S16 (ROK/RFAILED)
8230 **********************************************************/
8232 PRIVATE S16 rgSCHUtlUlAllocDbInit
8235 RgSchUlAllocDb *allocDb,
8239 PRIVATE S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs)
8241 RgSchUlAllocDb *allocDb;
8245 S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
8246 TRC2(rgSCHUtlUlAllocDbInit);
8252 allocDb->first = NULLP;
8256 /***********************************************************
8258 * Func : rgSCHUtlUlAllocDbDeinit
8260 * Desc : Deinitialises allocation DB
8261 * sent to UE, for a UE with accumulation disabled
8269 **********************************************************/
8271 PRIVATE Void rgSCHUtlUlAllocDbDeinit
8274 RgSchUlAllocDb *allocDb
8277 PRIVATE Void rgSCHUtlUlAllocDbDeinit(cell, allocDb)
8279 RgSchUlAllocDb *allocDb;
8282 TRC2(rgSCHUtlUlAllocDbDeinit);
8283 rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
8285 allocDb->first = NULLP;
8289 /***********************************************************
8291 * Func : rgSCHUtlUlHoleDbInit
8293 * Desc : Initialise hole DB
8295 * Ret : S16 (ROK/RFAILED)
8301 **********************************************************/
8303 PRIVATE S16 rgSCHUtlUlHoleDbInit
8306 RgSchUlHoleDb *holeDb,
8312 PRIVATE S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num)
8314 RgSchUlHoleDb *holeDb;
8321 RgSchUlHole *hole = NULLP;
8322 TRC2(rgSCHUtlUlHoleDbInit);
8324 ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
8330 holeDb->first = hole;
8331 hole->start = start;
8333 hole->prv = hole->nxt = NULLP;
8337 /***********************************************************
8339 * Func : rgSCHUtlUlHoleDbDeinit
8341 * Desc : Deinitialises hole DB
8349 **********************************************************/
8351 PRIVATE Void rgSCHUtlUlHoleDbDeinit
8354 RgSchUlHoleDb *holeDb
8357 PRIVATE Void rgSCHUtlUlHoleDbDeinit(cell, holeDb)
8359 RgSchUlHoleDb *holeDb;
8362 TRC2(rgSCHUtlUlHoleDbDeinit);
8363 rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
8365 holeDb->first = NULLP;
8370 /***********************************************************
8372 * Func : rgSCHUtlUlAllocGetHole
8374 * Desc : Get allocation from hole
8376 * Ret : RgSchUlAlloc *
8382 **********************************************************/
8384 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole
8391 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole)
8397 TRC2(rgSCHUtlUlAllocGetHole);
8398 if (numSb < hole->num)
8400 RETVALUE(rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
8404 RETVALUE(rgSCHUtlUlAllocGetCompHole(sf, hole));
8409 /***********************************************************
8411 * Func : rgSCHUtlUlAllocGetCompHole
8413 * Desc : Get an allocation corresponding to an entire hole
8415 * Ret : RgSchUlAlloc *
8421 **********************************************************/
8423 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole
8429 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole)
8434 RgSchUlAlloc *alloc;
8435 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8436 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8437 * updated, causing another check for prv */
8438 RgSchUlAlloc *prv = hole->prvAlloc;
8439 RgSchUlAlloc *nxt = hole->nxtAlloc;
8440 TRC2(rgSCHUtlUlAllocGetCompHole);
8444 if (hole->start == prv->nxtHole->start)
8446 prv->nxtHole = NULLP;
8448 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8452 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8455 RGSCH_NULL_CHECK( 0, alloc);
8456 alloc->prvHole = NULLP;
8457 alloc->nxtHole = NULLP;
8459 alloc->sbStart = hole->start;
8460 alloc->numSb = hole->num;
8464 nxt->prvHole = NULLP;
8467 rgSCHUtlUlHoleRls(sf->holeDb, hole);
8469 /* UL_ALLOC_CHANGES*/
8470 alloc->allocDbRef = (void*)sf->allocDb;
8471 alloc->holeDbRef = (void*)sf->holeDb;
8475 /***********************************************************
8477 * Func : rgSCHUtlUlAllocGetPartHole
8479 * Desc : Get an allocation corresponding to a part of a hole.
8480 * The initial 'numSb' part of the hole shall be taken
8481 * away for this alloc.
8483 * Ret : RgSchUlAlloc *
8489 **********************************************************/
8491 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole
8498 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)
8504 RgSchUlAlloc *alloc;
8505 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8506 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8507 * updated, causing another check for prv */
8508 RgSchUlAlloc *prv = hole->prvAlloc;
8509 TRC2(rgSCHUtlUlAllocGetPartHole);
8513 if (hole->start == prv->nxtHole->start)
8515 prv->nxtHole = NULLP;
8517 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8521 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8524 RGSCH_NULL_CHECK( 0, alloc);
8525 alloc->prvHole = NULLP;
8526 alloc->nxtHole = hole;
8527 hole->prvAlloc = alloc;
8529 alloc->sbStart = hole->start;
8530 alloc->numSb = numSb;
8531 hole->start += numSb;
8534 rgSCHUtlUlHoleDecr(sf->holeDb, hole);
8536 /* UL_ALLOC_CHANGES*/
8537 alloc->allocDbRef = (void*)sf->allocDb;
8538 alloc->holeDbRef = (void*)sf->holeDb;
8543 /***********************************************************
8545 * Func : rgSCHUtlUlAllocFirst
8547 * Desc : Get first alloc in slot
8549 * Ret : RgSchUlAlloc *
8555 **********************************************************/
8557 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst
8562 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf)
8566 TRC2(rgSCHUtlUlAllocFirst);
8567 RETVALUE(sf->allocDb->first);
8570 /***********************************************************
8572 * Func : rgSCHUtlUlAllocNxt
8574 * Desc : Get next alloc
8576 * Ret : RgSchUlAlloc *
8582 **********************************************************/
8584 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt
8590 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc)
8592 RgSchUlAlloc *alloc;
8595 TRC2(rgSCHUtlUlAllocNxt);
8597 RETVALUE(alloc->nxt);
8600 /***********************************************************
8602 * Func : rgSCHUtlUlAllocGetAdjNxt
8604 * Desc : Get alloc which is immediately after the passed one.
8605 * 1. Gets alloc from mem.
8606 * 2. Inserts alloc into list (between prv and
8607 * prv->nxt, prv is not NULLP).
8608 * 3. Increments alloc count.
8609 * Note 1: Holes are not dealt with here.
8610 * Note 2: Assumes prv to be NULL.
8612 * Ret : RgSchUlAlloc *
8618 **********************************************************/
8620 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt
8626 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv)
8631 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8632 RgSchUlAlloc *nxt = prv->nxt;
8633 TRC2(rgSCHUtlUlAllocGetAdjNxt);
8635 #if (ERRCLASS & ERRCLS_DEBUG)
8636 if ( alloc == NULLP )
8654 /***********************************************************
8656 * Func : rgSCHUtlUlAllocGetFirst
8658 * Desc : Get alloc which is to be the first one in the alloc list
8659 * 1. Gets alloc from mem.
8660 * 2. Inserts alloc as first element into list.
8661 * 3. Increments alloc count.
8662 * Note 1: Holes are not dealt with here.
8663 * Note 2: prv to necessarily NULLP.
8665 * Ret : RgSchUlAlloc *
8671 **********************************************************/
8673 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst
8678 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db)
8682 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8683 RgSchUlAlloc *nxt = db->first;
8684 TRC2(rgSCHUtlUlAllocGetFirst);
8686 #if (ERRCLASS & ERRCLS_DEBUG)
8687 if ( alloc == NULLP )
8706 /* UL_ALLOC_ENHANCEMENT */
8707 /***********************************************************
8709 * Func : rgSCHUtlUlHoleAddAllocation
8711 * Desc : On freeing an alloc, add to hole
8719 **********************************************************/
8721 PUBLIC Void rgSCHUtlUlHoleAddAllocation
8726 PUBLIC Void rgSCHUtlUlHoleAddAllocation(alloc)
8727 RgSchUlAlloc *alloc;
8730 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8731 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8732 * The excessive branching is meant to utilise the knowledge of whether prv
8733 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8734 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8735 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8736 RgSchUlHoleDb *db = alloc->holeDbRef;
8737 RgSchUlHole *prv = alloc->prvHole;
8738 RgSchUlHole *nxt = alloc->nxtHole;
8739 TRC2(rgSCHUtlUlHoleAddAllocation);
8745 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8748 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8754 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8757 rgSCHUtlUlHoleNew(db, alloc);
8763 /***********************************************************
8765 * Func : rgSCHUtlUlAllocRelease
8767 * Desc : Releases an uplink allocation, only take alloc ptr
8775 **********************************************************/
8777 PUBLIC Void rgSCHUtlUlAllocRelease
8782 PUBLIC Void rgSCHUtlUlAllocRelease(alloc)
8783 RgSchUlAlloc *alloc;
8786 RgSchUlAllocDb *allocDb = alloc->allocDbRef;
8787 RgSchUlAlloc *prv = alloc->prv;
8788 RgSchUlAlloc *nxt = alloc->nxt;
8789 TRC2(rgSCHUtlUlAllocRelease);
8792 alloc->raCb = NULLP;
8793 alloc->isAdaptive = FALSE;
8798 if (nxt) /* general case: this allocation lies btw two */
8805 allocDb->first = nxt;
8812 rgSCHUtlUlHoleAddAllocation(alloc);
8813 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8819 /***********************************************************
8821 * Func : rgSCHUtlUlAllocRls
8823 * Desc : Releases an uplink allocation
8831 **********************************************************/
8833 PUBLIC Void rgSCHUtlUlAllocRls
8839 PUBLIC Void rgSCHUtlUlAllocRls(sf, alloc)
8841 RgSchUlAlloc *alloc;
8844 RgSchUlAllocDb *allocDb = sf->allocDb;
8845 RgSchUlAlloc *prv = alloc->prv;
8846 RgSchUlAlloc *nxt = alloc->nxt;
8847 TRC2(rgSCHUtlUlAllocRls);
8850 alloc->raCb = NULLP;
8851 alloc->isAdaptive = FALSE;
8858 if (nxt) /* general case: this allocation lies btw two */
8865 allocDb->first = nxt;
8872 rgSCHUtlUlHoleAddAlloc(sf, alloc);
8873 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8878 printf("\nError: allocDb->count is ZERO ====\n");
8881 //printf("\nallocDb->count:%u\n",allocDb->count);
8886 /***********************************************************
8888 * Func : rgSCHUtlUlHoleFirst
8890 * Desc : Get first (largest) hole
8892 * Ret : RgSchUlHole *
8898 **********************************************************/
8900 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst
8905 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst(sf)
8909 TRC2(rgSCHUtlUlHoleFirst);
8910 RETVALUE(sf->holeDb->first);
8913 /***********************************************************
8915 * Func : rgSCHUtlUlHoleNxt
8917 * Desc : Get next largest hole
8919 * Ret : RgSchUlHole *
8925 **********************************************************/
8927 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt
8933 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole)
8938 TRC2(rgSCHUtlUlHoleNxt);
8940 RETVALUE(hole->nxt);
8943 /***********************************************************
8945 * Func : rgSCHUtlUlHoleAddAlloc
8947 * Desc : On freeing an alloc, add to hole
8955 **********************************************************/
8957 PUBLIC Void rgSCHUtlUlHoleAddAlloc
8963 PUBLIC Void rgSCHUtlUlHoleAddAlloc(sf, alloc)
8965 RgSchUlAlloc *alloc;
8968 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8969 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8970 * The excessive branching is meant to utilise the knowledge of whether prv
8971 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8972 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8973 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8974 RgSchUlHoleDb *db = sf->holeDb;
8975 RgSchUlHole *prv = alloc->prvHole;
8976 RgSchUlHole *nxt = alloc->nxtHole;
8977 TRC2(rgSCHUtlUlHoleAddAlloc);
8983 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8986 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8992 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8995 rgSCHUtlUlHoleNew(db, alloc);
8998 /* increment the number of subbands getting freed to total available list */
8999 sf->availSubbands += alloc->numSb;
9004 /***********************************************************
9006 * Func : rgSCHUtlUlHoleJoin
9008 * Desc : Join two holes (due to alloc being deleted)
9016 **********************************************************/
9018 PUBLIC Void rgSCHUtlUlHoleJoin
9026 PUBLIC Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc)
9030 RgSchUlAlloc *alloc;
9033 TRC2(rgSCHUtlUlHoleJoin);
9034 prv->num += alloc->numSb + nxt->num;
9035 rgSCHUtlUlHoleRls(db, nxt);
9036 rgSCHUtlUlHoleIncr(db, prv);
9037 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9042 /***********************************************************
9044 * Func : rgSCHUtlUlHoleExtndRight
9046 * Desc : Extend hole due to alloc coming 'after' the hole
9055 **********************************************************/
9057 PUBLIC Void rgSCHUtlUlHoleExtndRight
9064 PUBLIC Void rgSCHUtlUlHoleExtndRight(db, prv, alloc)
9067 RgSchUlAlloc *alloc;
9070 TRC2(rgSCHUtlUlHoleExtndRight);
9071 prv->num += alloc->numSb;
9072 rgSCHUtlUlHoleIncr(db, prv);
9073 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9077 /***********************************************************
9079 * Func : rgSCHUtlUlHoleExtndLeft
9081 * Desc : Extend hole due to alloc coming 'before' the hole
9090 **********************************************************/
9092 PUBLIC Void rgSCHUtlUlHoleExtndLeft
9099 PUBLIC Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc)
9102 RgSchUlAlloc *alloc;
9105 TRC2(rgSCHUtlUlHoleExtndLeft);
9106 nxt->num += alloc->numSb;
9107 nxt->start = alloc->sbStart;
9108 rgSCHUtlUlHoleIncr(db, nxt);
9109 rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
9113 /***********************************************************
9115 * Func : rgSCHUtlUlHoleNew
9117 * Desc : Create new hole due to alloc being deleted
9125 **********************************************************/
9127 PUBLIC Void rgSCHUtlUlHoleNew
9133 PUBLIC Void rgSCHUtlUlHoleNew(db, alloc)
9135 RgSchUlAlloc *alloc;
9138 RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
9139 #if (ERRCLASS & ERRCLS_DEBUG)
9140 if ( hole == NULLP )
9145 TRC2(rgSCHUtlUlHoleNew);
9146 hole->start = alloc->sbStart;
9147 hole->num = alloc->numSb;
9149 rgSCHUtlUlHoleIns(db, hole);
9150 rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
9154 /***********************************************************
9156 * Func : rgSCHUtlUlHoleUpdAllocLnks
9158 * Desc : Update alloc links in hole
9166 **********************************************************/
9168 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks
9171 RgSchUlAlloc *prvAlloc,
9172 RgSchUlAlloc *nxtAlloc
9175 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc)
9177 RgSchUlAlloc *prvAlloc;
9178 RgSchUlAlloc *nxtAlloc;
9181 TRC2(rgSCHUtlUlHoleUpdAllocLnks);
9184 prvAlloc->nxtHole = hole;
9188 nxtAlloc->prvHole = hole;
9190 hole->prvAlloc = prvAlloc;
9191 hole->nxtAlloc = nxtAlloc;
9196 /***********************************************************
9198 * Func : rgSCHUtlUlHoleIns
9200 * Desc : Insert (newly created) hole in sorted list of holes.
9201 * Searches linearly, beginning with the largest hole.
9209 **********************************************************/
9211 PUBLIC Void rgSCHUtlUlHoleIns
9217 PUBLIC Void rgSCHUtlUlHoleIns(db, hole)
9223 TRC2(rgSCHUtlUlHoleIns);
9225 if ((cur = db->first) != NULLP)
9228 if (cur->num < hole->num)
9238 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9240 if (nxt->num < hole->num)
9242 /* Insert hole: cur <-> hole <-> nxt */
9258 /* This is the first hole */
9260 hole->prv = NULLP; /* may not be needed */
9266 /***********************************************************
9268 * Func : rgSCHUtlUlHoleIncr
9270 * Desc : hole->num has increeased, reposition in sorted
9279 **********************************************************/
9281 PUBLIC Void rgSCHUtlUlHoleIncr
9287 PUBLIC Void rgSCHUtlUlHoleIncr(db, hole)
9293 TRC2(rgSCHUtlUlHoleIncr);
9295 if ((cur = hole->prv) != NULLP)
9299 if (cur->num > hole->num)
9304 /* Remove hole from current position */
9305 cur->nxt = hole->nxt;
9308 hole->nxt->prv = cur;
9311 for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
9313 if (prv->num > hole->num)
9315 /* Insert hole: prv <-> hole <-> cur */
9334 /***********************************************************
9336 * Func : rgSCHUtlUlHoleDecr
9338 * Desc : hole->num has decreeased, reposition in sorted
9347 **********************************************************/
9349 PUBLIC Void rgSCHUtlUlHoleDecr
9355 PUBLIC Void rgSCHUtlUlHoleDecr(db, hole)
9361 TRC2(rgSCHUtlUlHoleDecr);
9363 if ((cur = hole->nxt) != NULLP)
9367 if (cur->num < hole->num)
9372 /* Remove hole from current position */
9373 cur->prv = hole->prv;
9376 hole->prv->nxt = cur;
9378 else /* no prv, so cur to replace hole as first in list */
9383 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9385 if (nxt->num < hole->num)
9387 /* Insert hole: cur <-> hole <-> nxt */
9405 /***********************************************************
9407 * Func : rgSCHUtlUlHoleRls
9409 * Desc : Releases hole.
9410 * 1. Decrements hole count.
9411 * 2. Deletes hole from list.
9412 * 3. Frees hole (hole memory release).
9420 **********************************************************/
9422 PUBLIC Void rgSCHUtlUlHoleRls
9428 PUBLIC Void rgSCHUtlUlHoleRls(db, hole)
9433 RgSchUlHole *prv = hole->prv;
9434 RgSchUlHole *nxt = hole->nxt;
9435 TRC2(rgSCHUtlUlHoleRls);
9455 rgSCHUtlUlHoleMemRls(&db->mem, hole);
9460 /***********************************************************
9462 * Func : rgSCHUtlUlAllocMemInit
9464 * Desc : Initialises alloc free pool
9466 * Ret : S16 (ROK/RFAILED)
9472 **********************************************************/
9474 PUBLIC S16 rgSCHUtlUlAllocMemInit
9477 RgSchUlAllocMem *mem,
9481 PUBLIC S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs)
9483 RgSchUlAllocMem *mem;
9488 RgSchUlAlloc *allocs;
9489 TRC2(rgSCHUtlUlAllocMemInit);
9491 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
9492 maxAllocs * sizeof(*allocs));
9497 mem->allocs = allocs;
9498 mem->maxAllocs = maxAllocs;
9499 if (mem->maxAllocs == 1)
9501 allocs[0].prv = NULLP;
9502 allocs[0].nxt = NULLP;
9507 allocs[0].prv = NULLP;
9508 allocs[0].nxt = &allocs[1];
9509 for (i = 1; i < mem->maxAllocs - 1; ++i)
9511 allocs[i].prv = &allocs[i-1];
9512 allocs[i].nxt = &allocs[i+1];
9514 allocs[i].prv = &allocs[i-1];
9515 allocs[i].nxt = NULLP;
9517 mem->firstFree = &allocs[0];
9521 /***********************************************************
9523 * Func : rgSCHUtlUlAllocMemDeinit
9525 * Desc : Deinitialises alloc free pool
9533 **********************************************************/
9535 PUBLIC Void rgSCHUtlUlAllocMemDeinit
9538 RgSchUlAllocMem *mem
9541 PUBLIC Void rgSCHUtlUlAllocMemDeinit(cell, mem)
9543 RgSchUlAllocMem *mem;
9546 TRC2(rgSCHUtlUlAllocMemDeinit);
9547 /* ccpu00117052 - MOD - Passing double pointer
9548 for proper NULLP assignment*/
9549 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
9550 mem->maxAllocs * sizeof(*mem->allocs));
9552 mem->firstFree = NULLP;
9556 /***********************************************************
9558 * Func : rgSCHUtlUlHoleMemInit
9560 * Desc : Initialises hole free pool. Assumes maxHoles
9563 * Ret : S16 (ROK/RFAILED)
9569 **********************************************************/
9571 PUBLIC S16 rgSCHUtlUlHoleMemInit
9574 RgSchUlHoleMem *mem,
9576 RgSchUlHole **holeRef
9579 PUBLIC S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef)
9581 RgSchUlHoleMem *mem;
9583 RgSchUlHole **holeRef;
9588 TRC2(rgSCHUtlUlHoleMemInit);
9590 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
9591 maxHoles * sizeof(*holes));
9598 mem->maxHoles = maxHoles;
9600 /* first hole is taken up */
9601 holes[0].prv = NULLP; /* not needed */
9602 holes[0].nxt = NULLP; /* not needed */
9603 *holeRef = &holes[0];
9605 if (mem->maxHoles == 2)
9607 holes[1].prv = NULLP; /* may not be needed */
9608 holes[1].nxt = NULLP; /* may not be needed */
9613 holes[1].prv = NULLP;
9614 holes[0].nxt = &holes[1];
9615 for (i = 1; i < mem->maxHoles - 1; ++i)
9617 holes[i].prv = &holes[i-1];
9618 holes[i].nxt = &holes[i+1];
9620 holes[i].prv = &holes[i-1];
9621 holes[i].nxt = NULLP;
9623 mem->firstFree = &holes[1];
9628 /***********************************************************
9630 * Func : rgSCHUtlUlHoleMemDeinit
9632 * Desc : Deinitialises hole free pool
9640 **********************************************************/
9642 PUBLIC Void rgSCHUtlUlHoleMemDeinit
9648 PUBLIC Void rgSCHUtlUlHoleMemDeinit(cell, mem)
9650 RgSchUlHoleMem *mem;
9653 TRC2(rgSCHUtlUlHoleMemDeinit);
9654 /* ccpu00117052 - MOD - Passing double pointer
9655 for proper NULLP assignment*/
9656 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
9657 mem->maxHoles * sizeof(*mem->holes));
9659 mem->firstFree = NULLP;
9663 /***********************************************************
9665 * Func : rgSCHUtlUlAllocMemGet
9667 * Desc : Gets an 'alloc' from the free pool
9669 * Ret : RgSchUlAlloc *
9675 **********************************************************/
9677 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet
9679 RgSchUlAllocMem *mem
9682 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem)
9683 RgSchUlAllocMem *mem;
9686 RgSchUlAlloc *alloc;
9687 TRC2(rgSCHUtlUlAllocMemGet);
9689 #if (ERRCLASS & ERRCLS_DEBUG)
9690 if (mem->firstFree == NULLP)
9696 alloc = mem->firstFree;
9697 mem->firstFree = alloc->nxt;
9698 alloc->nxt = NULLP; /* probably not needed */
9699 /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
9704 /***********************************************************
9706 * Func : rgSCHUtlUlAllocMemRls
9708 * Desc : Returns an 'alloc' to the free pool
9716 **********************************************************/
9718 PUBLIC Void rgSCHUtlUlAllocMemRls
9720 RgSchUlAllocMem *mem,
9724 PUBLIC Void rgSCHUtlUlAllocMemRls(mem, alloc)
9725 RgSchUlAllocMem *mem;
9726 RgSchUlAlloc *alloc;
9729 TRC2(rgSCHUtlUlAllocMemRls);
9732 alloc->nxt = mem->firstFree;
9733 if (mem->firstFree != NULLP)
9735 mem->firstFree->prv = alloc;
9737 mem->firstFree = alloc;
9741 /***********************************************************
9743 * Func : rgSCHUtlUlHoleMemGet
9745 * Desc : Gets a 'hole' from the free pool
9747 * Ret : RgSchUlHole *
9753 **********************************************************/
9755 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet
9760 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet(mem)
9761 RgSchUlHoleMem *mem;
9765 TRC2(rgSCHUtlUlHoleMemGet);
9767 #if (ERRCLASS & ERRCLS_DEBUG)
9768 if (mem->firstFree == NULLP)
9774 hole = mem->firstFree;
9775 mem->firstFree = hole->nxt;
9776 mem->firstFree->prv = NULLP; /* may not be needed, under error class */
9777 hole->nxt = NULLP; /* probably not needed */
9778 /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
9783 /***********************************************************
9785 * Func : rgSCHUtlUlHoleMemRls
9787 * Desc : Returns a 'hole' to the free pool
9795 **********************************************************/
9797 PUBLIC Void rgSCHUtlUlHoleMemRls
9799 RgSchUlHoleMem *mem,
9803 PUBLIC Void rgSCHUtlUlHoleMemRls(mem, hole)
9804 RgSchUlHoleMem *mem;
9808 TRC2(rgSCHUtlUlHoleMemRls);
9811 hole->nxt = mem->firstFree;
9812 if (mem->firstFree != NULLP)
9814 mem->firstFree->prv = hole;
9816 mem->firstFree = hole;
9821 * @brief Get an alloc from the specified position in the BW.
9825 * Function : rgSCHUtlUlGetSpfcAlloc
9827 * - Return an alloc from the specified position in the BW.
9828 * Note: This function assumes there is always a hole
9829 * Existing which completely has the specified
9830 * allocation. The reason for such an assumption is
9831 * the function's usage as of now guarantees that there
9832 * will always be such hole. And also for efficiency.
9834 * @param[in] RgSchUlSf *sf
9835 * @param[in] U8 startSb
9836 * @param[in] U8 numSb
9837 * @return RgSchUlAlloc*
9840 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc
9847 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb)
9853 RgSchUlHole *hole, *nxtHole;
9854 RgSchUlAlloc *alloc = NULLP;
9855 TRC2(rgSCHUtlUlGetSpfcAlloc);
9857 if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
9863 nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
9864 if ((startSb >= hole->start) &&
9865 (startSb+numSb <= hole->start+hole->num))
9867 if (startSb != hole->start)
9869 /* Create a new hole to accomodate Subbands between
9870 * hole start and req alloc start */
9871 RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
9873 #if (ERRCLASS & ERRCLS_DEBUG)
9874 if ( newHole == NULLP )
9879 newHole->start = hole->start;
9880 newHole->num = startSb - hole->start;
9881 hole->start = startSb;
9882 /* [ccpu00122847]-MOD- Correctly updating the hole->num */
9883 hole->num -= newHole->num;
9884 ++(sf->holeDb->count);
9885 rgSCHUtlUlHoleIns(sf->holeDb, newHole);
9886 newHole->prvAlloc = hole->prvAlloc;
9887 if (newHole->prvAlloc)
9889 newHole->prvAlloc->nxtHole = newHole;
9891 if (numSb == hole->num)
9893 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9897 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9899 alloc->prvHole = newHole;
9900 newHole->nxtAlloc = alloc;
9902 else /* Hole start and req alloc start are same */
9904 if (numSb == hole->num)
9906 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9910 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9915 } while ((hole = nxtHole) != NULLP);
9920 * @brief Validates the qci values
9924 * Function :rgSCHUtlValidateQci
9926 * @param[in] RgSchCellCb *cellCb
9927 * @param[in] U8 numQci
9928 * @param[out] U8 *qci
9934 PRIVATE S16 rgSCHUtlValidateQci
9936 RgSchCellCb *cellCb,
9941 PRIVATE S16 rgSCHUtlValidateQci(cellCb, numQci, qci)
9942 RgSchCellCb *cellCb;
9950 TRC3(rgSCHUtlValidateQci)
9952 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
9954 qciVal = qci[qciIdx];
9955 if(qciVal == 0 || qciVal > 9)
9959 if(qciVal != cellCb->qciArray[qciVal].qci)
9966 }/* rgSCHUtlValidateQci */
9968 * @brief Validates the measurement request parameters.
9972 * Function :rgSCHUtlValidateMeasReq
9974 * @param[in] RgSchCellCb *cellCb
9975 * @param[in] LrgSchMeasReqInfo *schL2MeasInfo
9976 * @param[out] RgSchErrInfo *err
9977 * @return RgSchUlAlloc*
9980 PUBLIC S16 rgSCHUtlValidateMeasReq
9982 RgSchCellCb *cellCb,
9983 LrgSchMeasReqInfo *schL2MeasInfo,
9987 PUBLIC S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err)
9988 RgSchCellCb *cellCb;
9989 LrgSchMeasReqInfo *schL2MeasInfo;
9996 TRC3(rgSCHUtlValidateMeasReq)
9998 measType = schL2MeasInfo->measType;
10000 if((measType == 0) ||
10003 err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
10004 err->errCause = RGSCHERR_SCH_L2MEAS;
10007 if((schL2MeasInfo->timePrd !=0) &&
10008 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
10009 ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
10010 (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
10012 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10013 err->errCause = RGSCHERR_SCH_L2MEAS;
10016 if((schL2MeasInfo->timePrd !=0) &&
10017 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
10018 (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ))
10020 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10021 err->errCause = RGSCHERR_SCH_L2MEAS;
10024 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
10025 ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
10026 (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
10027 ((schL2MeasInfo->timePrd !=0)&&
10028 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
10029 (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
10031 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10032 err->errCause = RGSCHERR_SCH_L2MEAS;
10035 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
10036 ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
10037 (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
10038 ((schL2MeasInfo->timePrd !=0) &&
10039 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
10040 (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
10042 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10043 err->errCause = RGSCHERR_SCH_L2MEAS;
10046 if((schL2MeasInfo->timePrd !=0) &&
10047 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
10049 RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \
10050 (schL2MeasInfo->avgPrbQciDl.numQci));
10051 ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
10052 schL2MeasInfo->avgPrbQciDl.qci);
10055 err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
10056 err->errCause = RGSCHERR_SCH_L2MEAS;
10061 }/* rgSCHUtlValidateMeasReq */
10062 #endif /* LTE_L2_MEAS */
10063 /******* </AllocHolesMemMgmnt>: END *****/
10066 * @brief API for sending SI configuration confirm from Scheduler to RRM
10070 * Function: rgSCHUtlRgrSiCfgCfm
10072 * This API is invoked to send SI configuration confirm from Scheduler
10074 * This API fills in Pst structure and SAP Ids and invokes
10075 * config confirm API towards RRM.
10077 * @param[in] RgrCfgTransId transId
10078 * @param[in] U8 status
10084 PUBLIC S16 rgSCHUtlRgrSiCfgCfm
10088 RgrCfgTransId transId,
10092 PUBLIC S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status)
10095 RgrCfgTransId transId;
10099 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10101 TRC2(rgSCHUtlRgrSiCfgCfm)
10103 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10104 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10107 if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10108 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10109 transId, status) != ROK)
10111 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10112 "RgUiRgrSiCfgCfm Failed ");
10117 } /* rgSCHUtlRgrSiCfgCfm */
10121 * @brief API for sending Warning SI configuration confirm from
10127 * This API is invoked to send Warning SI configuration confirm
10128 * from Scheduler to RRM.
10129 * This API fills in Pst structure and SAP Ids and invokes
10130 * config confirm API towards RRM.
10132 * @param[in] RgrCfgTransId transId
10133 * @param[in] U8 status
10139 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm
10144 RgrCfgTransId transId,
10148 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status)
10152 RgrCfgTransId transId;
10156 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10158 TRC2(rgSCHUtlRgrWarningSiCfgCfm)
10160 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10161 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10164 if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10165 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10166 transId, siId, status) != ROK)
10168 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10169 "RgUiRgrSiCfgCfm Failed ");
10174 } /* rgSCHUtlRgrWarningSiCfgCfm */
10176 /***********************************************************
10178 * Func : rgSCHUtlPutSiInfo
10180 * Desc : Utility Function to deallocate SI information
10188 **********************************************************/
10190 PUBLIC Void rgSCHUtlPutSiInfo
10195 PUBLIC Void rgSCHUtlPutSiInfo(cell)
10200 U32 sizeOfSiInfo = 0;
10201 TRC2(rgSCHUtlPutSiInfo)
10202 /*Free the buffers in crntSiInfo*/
10203 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
10204 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
10206 sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
10208 for(idx=0; idx < sizeOfSiInfo; idx++)
10210 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
10213 /*Free the buffers in newSiInfo */
10214 RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
10215 RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
10217 sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
10219 for(idx=0; idx < sizeOfSiInfo; idx++)
10221 RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
10226 #endif /*RGR_SI_SCH */
10230 /***********************************************************
10232 * Func : rgSCHUtlGetDrxSchdUesInDl
10234 * Desc : Utility Function to fill the get the list of
10235 * scheduled UEs. On these UE's, drx-inactivity
10236 * timer will be started/restarted.
10245 **********************************************************/
10247 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl
10249 RgSchCellCb *cellCb,
10251 RgSchDlHqProcCb *dlHq,
10252 RgInfUeAlloc *allocInfo,
10253 CmLListCp *dlDrxInactvTmrLst,
10254 CmLListCp *dlInActvLst,
10255 CmLListCp *ulInActvLst
10258 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
10259 RgSchCellCb *cellCb;
10261 RgSchDlHqProcCb *dlHq;
10262 RgInfUeAlloc *allocInfo;
10263 CmLListCp *dlDrxInactvTmrLst;
10264 CmLListCp *dlInActvLst;
10265 CmLListCp *ulInActvLst;
10268 Bool isNewTx = FALSE;
10270 RgSchDrxDlHqProcCb *drxHq;
10271 RgSchDRXCellCb *drxCell = cellCb->drxCb;
10272 RgSchDrxUeCb *drxUe;
10274 Inst inst = cellCb->instIdx;
10276 U8 cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
10280 for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
10282 if(allocInfo->tbInfo[idx].isReTx == FALSE)
10285 /* Removing break here, since in 2 TB case if 2nd TB is proceeding with
10286 retx then drxretx timer should be stopped.*/
10290 /*Stop the DRX retransmission timer as UE scheduled for retx. Here
10291 * we stop the timer and inactivate the UE for both UL and DL.
10292 * This may result in loss of one slot for UL but this trade
10293 * off is taken to avoid the overhead of maintaining a list of UEs
10294 * to be inactivated in the next slot.*/
10295 drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
10296 drxUe = RG_SCH_DRX_GET_UE(ueCb);
10297 if(drxHq->reTxIndx != DRX_INVALID)
10299 /* This condition should never occur */
10300 if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
10302 RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]"
10303 "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
10304 drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId));
10307 drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10308 drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10310 dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10311 ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10313 for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
10315 dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
10316 ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
10319 drxUe->drxDlInactvMask |= dlInactvMask;
10320 drxUe->drxUlInactvMask |= ulInactvMask;
10322 /* if no other condition is keeping ue active,
10323 * inactivate the Ue
10325 if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
10327 /* BUG 2 : HARQ_RTT, changed for consistency */
10328 ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
10330 /* Add to DL inactive list */
10331 cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
10332 ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
10335 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
10337 /*BUG 2: HARQ_RTT changed for consistency */
10338 ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
10340 cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
10341 ueCb->ulDrxInactvLnk.node = (PTR)ueCb;
10344 /* Deleting entry from HARQ RTT queue for the same HARQ proc,
10345 * if exist. This is the special case which can happen iF UL
10346 * scheduling is done later. */
10347 if(drxHq->rttIndx != DRX_INVALID)
10349 cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
10350 &(drxHq->harqRTTEnt));
10352 drxHq->rttIndx = DRX_INVALID;
10355 cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
10356 &(drxHq->harqRetxEnt));
10357 drxHq->reTxIndx = DRX_INVALID;
10362 if(isNewTx == TRUE)
10364 if(ueCb->drxCb->raRcvd == TRUE)
10366 ueCb->drxCb->raRcvd = FALSE;
10368 /* mark the ra bit */
10369 ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10370 ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10372 }/*if(ra->rcvd) == TRUE */
10374 if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
10376 cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
10377 ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
10379 }/*if(isNewTx == TRUE) */
10382 }/* rgSCHUtlGetSchdUes*/
10384 /* ccpu00117452 - MOD - Changed macro name from
10385 RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
10386 #ifdef RGR_CQI_REPT
10388 * @brief This function fills StaInd struct
10392 * Function: rgSCHUtlFillSndStaInd
10393 * Purpose: Fills StaInd struct and sends the
10396 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10397 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10398 * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled
10399 * @param[in] U8 numCqiRept NUmber of reports to be filled
10404 PUBLIC S16 rgSCHUtlFillSndStaInd
10408 RgrStaIndInfo *staInfo,
10412 PUBLIC S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept)
10415 RgrStaIndInfo *staInfo;
10421 /* Fill StaInd for sending collated Latest N CQI rpeorts */
10422 /* Find index in the array from where Latest N
10423 reports needs to be fetched. Use this value to index in the array
10424 and copy the reports into staInfo */
10426 /* Fill the Cell Id of PCC of the UE */
10427 staInfo->cellId = ue->cell->cellId;
10428 staInfo->crnti = ue->ueId;
10430 idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
10432 cmMemcpy ((U8*)&(staInfo->ueCqiInfo.cqiRept),
10433 (U8*)&(ue->schCqiInfo.cqiRept[idxStart]),
10434 numCqiRept * sizeof(RgrUeCqiRept));
10436 staInfo->ueCqiInfo.numCqiRept = numCqiRept;
10438 ue->schCqiInfo.cqiCount = 0;
10440 /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
10441 if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
10443 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10444 "CQI reports for RNTI:%d",ue->ueId);
10450 }/* End of rgSCHUtlFillSndStaInd */
10455 * @brief API for sending STA indication from Scheduler to RRM.
10459 * Function: rgSCHUtlRgrStaInd
10461 * This API is invoked to send STA indication from Scheduler instance to RRM.
10462 * This API fills in Pst structure and RgrStaIndInfo
10463 * and calls the Sta primitive API towards RRM.
10465 * @param[in] cell RgSchCellCb
10466 * @param[in] RgrStsIndInfo *rgrSta
10472 PUBLIC S16 rgSCHUtlRgrStaInd
10475 RgrStaIndInfo *rgrSta
10478 PUBLIC S16 rgSCHUtlRgrStaInd(cell, rgrSta)
10480 RgrStaIndInfo *rgrSta;
10484 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10486 TRC2(rgSCHUtlRgrStaInd)
10489 rgrSap = cell->rgrSap;
10490 if (rgrSap->sapSta.sapState != LRG_BND)
10492 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10493 "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
10494 rgrSap->sapSta.sapState);
10497 RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
10498 cell->rgrSap->sapCfg.suId, rgrSta);
10500 } /* rgSCHUtlRgrStaInd*/
10501 #endif /* End of RGR_CQI_REPT */
10503 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
10505 * @brief Indicates MAC to release any rnti context it has.
10508 * Function : rgSCHUtlIndRntiRls2Mac
10509 * This function indicates MAC for this rnti release.
10510 * In case of ueId change it will indicate MAC
10511 * about the new rnti to be updated.
10512 * It will post a release RNTI indication to MAC.
10516 * @param[in] RgSchCellCb *cell
10517 * @param[in] CmLteRnti rnti
10518 * @param[in] Bool ueIdChng
10519 * @param[in] CmLteRnti newRnti
10524 PUBLIC Void rgSCHUtlIndRntiRls2Mac
10532 PUBLIC Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti)
10540 Inst inst = cell->instIdx;
10541 RgInfRlsRnti rntiInfo;
10543 TRC2(rgSCHUtlIndRntiRls2Mac)
10545 /* Copy the info to rntiInfo */
10546 rntiInfo.cellId = cell->cellId;
10547 rntiInfo.rnti = rnti;
10548 /* Fix : syed ueId change as part of reestablishment.
10549 * Now SCH to trigger this. CRG ueRecfg for ueId change
10551 rntiInfo.ueIdChng = ueIdChng;
10552 rntiInfo.newRnti = newRnti;
10554 rntiInfo.isUeSCellDel = FALSE;
10556 /* Invoke MAC to release the rnti */
10557 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
10558 RgSchMacRlsRnti(&pst, &rntiInfo);
10562 /* LTE_ADV_FLAG_REMOVED_START */
10564 * @brief API for sending LOAD INF indication from Scheduler to RRM.
10567 * Function: rgSCHUtlRgrLoadInfInd
10569 * This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
10570 * This API fills in Pst structure and RgrLoadInfIndInfo
10571 * and calls the Sta primitive API towards RRM.
10573 * @param[in] cell RgSchCellCb
10574 * @param[in] RgrLoadInfIndInfo *rgrLoadInf
10580 PUBLIC S16 rgSCHUtlRgrLoadInfInd
10583 RgrLoadInfIndInfo *rgrLoadInf
10586 PUBLIC S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf)
10588 RgrLoadInfIndInfo *rgrLoadInf;
10592 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10594 TRC2(rgSCHUtlRgrLoadInfInd)
10597 rgrSap = cell->rgrSap;
10598 if (rgrSap->sapSta.sapState != LRG_BND)
10600 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10601 "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
10602 rgrSap->sapSta.sapState);
10605 RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
10606 cell->rgrSap->sapCfg.suId, rgrLoadInf);
10608 } /* rgSCHUtlRgrLoadInfInd*/
10609 /* LTE_ADV_FLAG_REMOVED_END */
10611 /* MS_FIX : syed SCH to act as MASTER in maintaining
10612 * rnti related context. Trigger to rnti del/Chng at SCH
10613 * will result in a Indication to MAC to release its
10614 * RNTI context. MAC inturn indicates the context cleared
10615 * indication to SCH, upon which SCH would set this
10617 * @brief API for sending STA indication from Scheduler to RRM.
10621 * Function: rgSCHUtlRlsRnti
10623 * This API is invoked to indicate MAC to release rnti
10625 * @param[in] RgSchCellCb *cellCb
10626 * @param[in] RgSchRntiLnk *rntiLnk,
10627 * @param[in] Bool ueIdChngd,
10628 * @param[in] CmLteRnti newRnti
10633 PUBLIC Void rgSCHUtlRlsRnti
10636 RgSchRntiLnk *rntiLnk,
10641 PUBLIC Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti)
10643 RgSchRntiLnk *rntiLnk;
10649 TRC2(rgSCHUtlRlsRnti)
10652 if(cell->emtcEnable)
10654 rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
10659 /*Add to Guard Pool*/
10660 cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
10661 rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
10663 /* Fix: syed Explicitly Inidcate MAC to release RNTI */
10664 rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
10671 * @brief This function fills StaInd struct
10675 * Function: rgSCHUtlFillSndUeStaInd
10676 * Purpose: Fills StaInd struct and sends the
10679 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10680 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10681 * @param[in] U8 numCqiRept NUmber of reports to be filled
10686 PUBLIC S16 rgSCHUtlFillSndUeStaInd
10690 RgrUeStaIndInfo *ueStaInfo
10693 PUBLIC S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo)
10696 RgrUeStaIndInfo *ueStaInfo;
10700 ueStaInfo->cellId = cell->cellId;
10701 ueStaInfo->crnti = ue->ueId;
10703 /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
10704 if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
10706 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10707 "UE Sta reports CRNTI:%d",ue->ueId);
10713 }/* End of rgSCHUtlFillSndStaInd */
10718 * @brief API for sending STA indication from Scheduler to RRM.
10722 * Function: rgSCHUtlRgrStaInd
10724 * This API is invoked to send STA indication from Scheduler instance to RRM.
10725 * This API fills in Pst structure and RgrStaIndInfo
10726 * and calls the Sta primitive API towards RRM.
10728 * @param[in] cell RgSchCellCb
10729 * @param[in] RgrStsIndInfo *rgrSta
10735 PUBLIC S16 rgSCHUtlRgrUeStaInd
10738 RgrUeStaIndInfo *rgrUeSta
10741 PUBLIC S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta)
10743 RgrUeStaIndInfo *rgrUeSta;
10747 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10749 TRC2(rgSCHUtlRgrStaInd)
10752 rgrSap = cell->rgrSap;
10753 if (rgrSap->sapSta.sapState != LRG_BND)
10755 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10756 "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
10757 rgrSap->sapSta.sapState);
10760 RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
10761 cell->rgrSap->sapCfg.suId, rgrUeSta);
10763 } /* rgSCHUtlRgrStaInd*/
10767 * @brief function to report DL and UL PRB usage to RRM.
10770 * Function: rgSCHUtlUpdAvgPrbUsage
10771 * This function sends the PRB usage report to
10772 * RRM with the interval configured by RRM.
10774 * @param[in] cell *RgSchCellCb
10780 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage
10785 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage(cell)
10789 CmLteTimingInfo frm;
10790 RgmPrbRprtInd *prbRprtInd;
10793 #ifdef DBG_MAC_RRM_PRB_PRINT
10794 static U32 count = 0;
10795 const U32 reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
10800 TRC2(rgSCHUtlUpdAvgPrbUsage);
10802 frm = cell->crntTime;
10803 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
10809 if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
10811 /* Get the total number of DL and UL slots within the reporting period*/
10812 numDlSf = (cell->prbUsage.rprtPeriod *
10813 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10814 / RGSCH_NUM_SUB_FRAMES;
10815 numUlSf = (cell->prbUsage.rprtPeriod *
10816 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10817 / RGSCH_NUM_SUB_FRAMES;
10821 /* Get the total number of DL and UL slots < 10 ms interval */
10822 numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10823 numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10826 numDlSf = cell->prbUsage.rprtPeriod;
10827 numUlSf = cell->prbUsage.rprtPeriod;
10830 if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
10831 cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd,
10832 sizeof(RgmPrbRprtInd)) != ROK)
10837 cmMemset((U8 *) &prbRprtInd->stQciPrbRpts[0],
10839 (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
10841 prbRprtInd->bCellId = cell->cellId;
10845 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL;
10846 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10848 prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage =
10849 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
10850 (numDlSf * cell->bwCfg.dlTotalBw));
10851 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10852 cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
10858 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL;
10859 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10861 prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage =
10862 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
10863 (numUlSf * cell->ulAvailBw));
10864 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10865 cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
10869 #ifdef DBG_MAC_RRM_PRB_PRINT
10870 if((count % reprotForEvery20Sec) == 0 )
10872 printf("\n====================================================================");
10873 printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n");
10874 printf("======================================================================\n");
10875 printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n",
10876 prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
10877 prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
10878 prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
10879 prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
10880 prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
10881 prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
10882 prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
10883 prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
10886 RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst),
10887 cell->rgmSap->sapCfg.suId, prbRprtInd);
10895 * @brief This function resends the Ta in case of
10896 * max retx failure or DTX for the Ta transmitted
10900 * Function: rgSCHUtlReTxTa
10903 * @param[in] RgSchCellCb *cell
10904 * @param[in] RgSchUeCb *ue
10909 PUBLIC Void rgSCHUtlReTxTa
10911 RgSchCellCb *cellCb,
10915 PUBLIC Void rgSCHUtlReTxTa(cellCb, ueCb)
10916 RgSchCellCb *cellCb;
10920 TRC2(rgSCHUtlReTxTa)
10922 /* If TA Timer is running. Stop it */
10923 if (ueCb->taTmr.tmrEvnt != TMR_NONE)
10925 rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
10927 /*[ccpu00121813]-ADD-If maxretx is reached then
10928 * use outstanding TA val for scheduling again */
10929 if(ueCb->dl.taCb.outStndngTa == TRUE)
10931 ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
10932 ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
10933 ueCb->dl.taCb.outStndngTa = FALSE;
10936 /* Fix : syed TA state updation missing */
10937 ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
10938 rgSCHUtlDlTARpt(cellCb, ueCb);
10943 /* Added function for dropping Paging Message*/
10945 * @brief Handler for BO Updt received for BCCH or PCCH.
10949 * Function : rgSCHChkBoUpdate
10951 * This function shall check for BO received falls within the scheduling window or not
10954 * @param[in] RgSchCellCb *cell
10960 PRIVATE S16 rgSCHChkBoUpdate
10963 RgInfCmnBoRpt *boUpdt
10966 PRIVATE S16 rgSCHChkBoUpdate (cell, boUpdt)
10968 RgInfCmnBoRpt *boUpdt;
10972 U32 crntTimeInSubFrms = 0;
10973 U32 boUpdTimeInSubFrms = 0;
10975 TRC2(rgSCHChkBoUpdate);
10977 crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.slot +
10978 RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI
10979 so incrementing with +1 more */
10980 boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.slot;
10983 distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
10984 boUpdTimeInSubFrms - crntTimeInSubFrms : \
10985 (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
10987 if (distance > RGSCH_PCCHBCCH_WIN)
10993 }/*rgSCHChkBoUpdate*/
10998 * @brief Utility function to calculate the UL reTxIdx in TDD cfg0
11002 * Function : rgSchUtlCfg0ReTxIdx
11004 * Update the reTxIdx according to the rules mentioned
11005 * in 3GPP TS 36.213 section 8 for TDD Cfg0
11007 * @param[in] RgSchCellCb *cell
11008 * @param[in] CmLteTimingInfo phichTime
11009 * @param[in] U8 hqFdbkIdx
11013 PUBLIC U8 rgSchUtlCfg0ReTxIdx
11016 CmLteTimingInfo phichTime,
11020 PUBLIC U8 rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx)
11022 CmLteTimingInfo phichTime;
11026 U8 reTxIdx = RGSCH_INVALID_INFO;
11028 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
11030 U8 ulSF; /* UL SF in the TDD frame */
11032 TRC2(rgSchUtlCfg0ReTxIdx);
11034 ulSf = &cellUl->ulSfArr[hqFdbkIdx];
11035 ulSF = ulSf->ulSfIdx;
11037 /* Check for the UL SF 4 or 9 */
11038 if(ulSF == 9 || ulSF == 4)
11042 if(phichTime.slot == 0 || phichTime.slot == 5)
11046 /* Retx will happen according to the Pusch k table */
11047 reTxIdx = cellUl->schdIdx;
11051 /* Retx will happen at n+7 */
11052 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11053 /* Fetch the corresponding UL slot Idx in UL sf array */
11054 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11057 else if(phichTime.slot == 1 || phichTime.slot == 6)
11059 /* Retx will happen at n+7 */
11060 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11061 /* Fetch the corresponding UL slot Idx in UL sf array */
11062 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11069 * @brief Utility function to calculate total num of PRBs required to
11070 * satisfy DL BO for TM1/TM2/TM6/TM7
11074 * Function : rgSchUtlDlCalc1CwPrb
11076 * Calculate PRBs required for UE to satisfy BO in DL
11078 * Note : Total calculated PRBs will be assigned to *prbReqrd
11081 * @param[in] RgSchCellCb *cell
11082 * @param[in] RgSchUeCb *ue
11083 * @param[in] U32 bo
11084 * @param[out] U32 *prbReqrd
11088 PUBLIC Void rgSchUtlDlCalc1CwPrb
11096 PUBLIC Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd)
11103 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11104 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11108 U8 cfi = dlCell->currCfi;
11110 TRC2(rgSchUtlDlCalc1CwPrb);
11112 iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11113 eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
11115 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11116 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11117 noRes = ((U64)((bo << 3) << 10)) / (eff);
11118 /* Get the number of RBs needed for this transmission */
11119 /* Number of RBs = No of REs / No of REs per RB */
11120 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11123 } /* rgSchUtlDlCalc1CwPrb*/
11126 * @brief Utility function to calculate total num of PRBs required to
11127 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11132 * Function : rgSchUtlDlCalc2CwPrb
11134 * Calculate PRBs required for UE to satisfy BO in DL
11136 * Note : Total calculated PRBs will be assigned to *prbReqrd
11139 * @param[in] RgSchCellCb *cell
11140 * @param[in] RgSchUeCb *ue
11141 * @param[in] U32 bo
11142 * @param[out] U32 *prbReqrd
11146 PUBLIC Void rgSchUtlDlCalc2CwPrb
11154 PUBLIC Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd)
11161 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11162 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11167 U8 cfi = dlCell->currCfi;
11169 TRC2(rgSchUtlDlCalc2CwPrb);
11171 if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
11172 (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
11174 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11175 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
11177 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11178 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11179 noRes = ((U64)((bo << 3) << 10)) / (eff1);
11180 /* Get the number of RBs needed for this transmission */
11181 /* Number of RBs = No of REs / No of REs per RB */
11182 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11186 noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
11187 noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
11188 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
11189 iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
11190 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
11191 eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
11193 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11194 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11195 noRes = ((U64)((bo << 3) << 10)) / (eff1 + eff2);
11196 /* Get the number of RBs needed for this transmission */
11197 /* Number of RBs = No of REs / No of REs per RB */
11198 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11201 } /* rgSchUtlDlCalc2CwPrb */
11204 * @brief Utility function to calculate total num of PRBs required to
11205 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11209 * Function : rgSchUtlCalcTotalPrbReq
11211 * This function calls TM specific routine to calculate PRB
11214 * @param[in] RgSchCellCb *cell
11215 * @param[in] RgSchUeCb *ue
11216 * @param[in] U32 bo
11217 * @param[out] U32 *prbReqrd
11221 PUBLIC Void rgSchUtlCalcTotalPrbReq
11229 PUBLIC Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd)
11236 TRC2(rgSchUtlCalcTotalPrbReq);
11238 /* Call TM specific Prb calculation routine */
11239 (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
11242 } /* rgSchUtlCalcTotalPrbReq */
11244 /***********************************************************
11246 * Func : rgSCHUtlFetchPcqiBitSz
11249 * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
11258 **********************************************************/
11260 PRIVATE U8 rgSCHUtlFetchPcqiBitSz
11267 PRIVATE U8 rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt)
11276 RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
11278 TRC3(rgSCHUtlFetchPcqiBitSz);
11279 confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
11280 if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) &&
11281 (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
11287 ri = cqiCb->perRiVal;
11289 switch(confRepMode)
11291 case RGR_PRD_CQI_MOD10:
11297 case RGR_PRD_CQI_MOD11:
11310 else if(numTxAnt == 4)
11323 /* This is number of antenna case 1.
11324 * This is not applicable for Mode 1-1.
11325 * So setting it to invalid value */
11331 case RGR_PRD_CQI_MOD20:
11339 pcqiSz = 4 + cqiCb->label;
11344 case RGR_PRD_CQI_MOD21:
11359 else if(numTxAnt == 4)
11372 /* This might be number of antenna case 1.
11373 * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
11374 * So setting invalid value.*/
11382 pcqiSz = 4 + cqiCb->label;
11386 pcqiSz = 7 + cqiCb->label;
11401 * @brief Utility function to returns the number of subbands based on the
11406 * Function : rgSchUtlGetNumSbs
11408 * Calculate the number of PRBs
11409 * Update the subbandRequired based on the nPrbs and subband size
11411 * @param[in] RgSchCellCb *cell
11412 * @param[in] RgSchUeCb *ue
11413 * @param[in] U32 *numSbs
11417 PUBLIC U8 rgSchUtlGetNumSbs
11424 PUBLIC U8 rgSchUtlGetNumSbs (cell, ue, numSbs)
11431 //Currently hardcoding MAX prb for each UE
11432 nPrb = ue->ue5gtfCb.maxPrb;
11433 (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
11438 * @brief Utility function to insert the UE node into UE Lst based on the
11439 * number of subbands allocated for the UE for the current TTI.
11443 * Function : rgSchUtlSortInsUeLst
11445 * If subbandRequired < Min, then insert at head
11446 * Else If subbandRequired > Max, then insert at tail
11447 * Else, traverse the list and place the node at the appropriate place
11449 * @param[in] RgSchCellCb *cell
11450 * @param[in] RgSchUeCb *ue
11454 PUBLIC U8 rgSchUtlSortInsUeLst
11462 PUBLIC U8 rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired)
11470 CmLList *firstUeInLst;
11471 CmLList *lastUeInLst;
11473 RgSchCmnUlUe *ueUl;
11475 //firstUeInLst = cmLListFirst(ueLst);
11476 CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
11477 if(NULLP == firstUeInLst)
11479 /* first node to be added to the list */
11480 cmLListAdd2Tail(ueLst, node);
11484 /* Sb Required for the UE is less than the first node in the list */
11485 tempUe = (RgSchUeCb *)(firstUeInLst->node);
11486 ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
11488 if(vrbgRequired <= ueUl->vrbgRequired)
11490 cmLListInsCrnt(ueLst, (node));
11494 /* Sb Required for this UE is higher than the UEs in the list */
11495 lastUeInLst = cmLListLast(ueLst);
11496 tempUe = (RgSchUeCb *)(lastUeInLst->node);
11497 if(vrbgRequired >= ueUl->vrbgRequired)
11499 cmLListAdd2Tail(ueLst, (node));
11503 /* This UE needs to be in the middle. Search and insert the UE */
11504 ueInLst = cmLListFirst(ueLst);
11507 tempUe = (RgSchUeCb *)(ueInLst->node);
11509 if(vrbgRequired <= ueUl->vrbgRequired)
11511 cmLListInsCrnt(ueLst, (node));
11515 ueInLst = cmLListNext(ueLst);
11517 } while(NULLP != ueInLst && ueInLst != firstUeInLst);
11526 * @brief Function to Send LCG GBR register to MAC
11530 * Function: rgSCHUtlBuildNSendLcgReg
11532 * Handler for sending LCG GBR registration
11537 * Processing Steps:
11539 * @param[in] RgSchCellCb *cell
11540 * @param[in] CmLteRnti crnti
11541 * @param[in] U8 lcgId
11542 * @param[in] Bool isGbr
11547 PUBLIC S16 rgSCHUtlBuildNSendLcgReg
11555 PUBLIC S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr)
11563 RgInfLcgRegReq lcgRegReq;
11565 TRC3(rgSCHUtlBuildNSendLcgReg);
11567 cmMemset((U8*)&pst, (U8)0, sizeof(Pst));
11568 lcgRegReq.isGbr = isGbr;
11569 lcgRegReq.cellId = cell->cellId;
11570 lcgRegReq.crnti = crnti;
11571 lcgRegReq.lcgId = lcgId;
11572 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
11573 /* code Coverage portion of the test case */
11574 RgSchMacLcgReg(&pst, &lcgRegReq);
11583 * @brief Function to map RGR pucch type to TFU type
11587 * Function: rgSchUtlGetFdbkMode
11593 * Processing Steps:
11595 * @param[in] RgrSchFrmt1b3TypEnum
11596 * @return TfuAckNackMode
11600 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode
11602 RgrSchFrmt1b3TypEnum fdbkType
11605 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType)
11606 RgrSchFrmt1b3TypEnum fdbkType;
11610 TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
11612 TRC2(rgSchUtlGetFdbkMode);
11616 case RG_SCH_UCI_FORMAT_NON_CA:
11617 case RG_SCH_UCI_FORMAT1A_1B:
11619 mode = TFU_UCI_FORMAT_1A_1B;
11622 case RG_SCH_UCI_FORMAT1B_CS:
11624 mode = TFU_UCI_FORMAT_1B_CS;
11627 case RG_SCH_UCI_FORMAT3:
11629 mode = TFU_UCI_FORMAT_3;
11635 #endif /* TFU_TDD */
11636 #endif /* LTE_ADV */
11637 #endif /*TFU_UPGRADE */
11641 * @brief Send Ue SCell delete to SMAC.
11645 * Function : rgSCHUtlSndUeSCellDel2Mac
11646 * This function populates the struct RgInfRlsRnti and
11647 * get the pst for SMac and mark field isUeSCellDel to TRUE which
11648 * indicates that it is a Ue SCell delete.
11652 * @param[in] RgSchCellCb *cell
11653 * @param[in] CmLteRnti rnti
11658 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac
11664 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti)
11670 Inst inst = cell->instIdx;
11671 RgInfRlsRnti rntiInfo;
11673 TRC2(rgSCHUtlSndUeSCellDel2Mac)
11675 RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti));
11676 /* Copy the info to rntiInfo */
11677 rntiInfo.cellId = cell->cellId;
11678 rntiInfo.rnti = rnti;
11679 /* Fix : syed ueId change as part of reestablishment.
11680 * Now SCH to trigger this. CRG ueRecfg for ueId change
11682 rntiInfo.ueIdChng = FALSE;
11683 rntiInfo.newRnti = rnti;
11684 rntiInfo.isUeSCellDel = TRUE;
11685 /* Invoke MAC to release the rnti */
11686 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
11687 RgSchMacRlsRnti(&pst, &rntiInfo);
11692 * @brief Returns max TB supported by a given txMode
11696 * Function : rgSCHUtlGetMaxTbSupp
11697 * Max TB supported for TM Modes (1,2,5,6 and 7) is 1
11701 * @param[in] RgrTxMode txMode
11702 * @return U8 maxTbCount;
11706 PUBLIC U8 rgSCHUtlGetMaxTbSupp
11711 PUBLIC U8 rgSCHUtlGetMaxTbSupp(txMode)
11717 TRC2(rgSCHUtlGetMaxTbSupp);
11741 RETVALUE(maxTbCount);
11745 * @brief Send Ue SCell delete to SMAC.
11749 * Function : rgSCHTomUtlGetTrigSet
11750 * This function gets the triggerset based on cqiReq
11752 * @param[in] RgSchCellCb *cell
11753 * @param[in] RgSchUeCb ueCb
11754 * @param[in] U8 cqiReq,
11755 * @param[out] U8 *triggerSet
11761 PUBLIC Void rgSCHTomUtlGetTrigSet
11769 PRIVATE S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet)
11776 RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
11779 case RG_SCH_APCQI_SERVING_CC:
11781 /* APeriodic CQI request for Current Carrier.*/
11782 U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
11783 *triggerSet = 1 << (7 - sCellIdx);
11786 case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
11788 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
11791 case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
11793 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
11806 * @brief This function updates the value of UE specific DCI sizes
11810 * Function: rgSCHUtlUpdUeDciSize
11811 * Purpose: This function calculates and updates DCI Sizes in bits.
11813 * Invoked by: Scheduler
11815 * @param[in] RgSchCellCb *cell
11816 * @param[in] RgSchUeCb *ueCb
11817 * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI
11822 PUBLIC Void rgSCHUtlUpdUeDciSize
11829 PUBLIC Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit)
11835 U8 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11836 U8 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11837 if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
11839 dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
11840 dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
11842 if (isCsi2Bit == TRUE)
11844 dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
11848 dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
11851 /* Common CSI is always 1 bit DCI 0 */
11852 dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
11854 /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
11855 if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11857 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11859 if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11861 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11864 /* 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 */
11865 dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
11866 dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
11868 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize;
11869 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
11871 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize;
11872 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
11874 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11876 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11877 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11878 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11879 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11880 if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
11882 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
11885 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11886 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11887 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11888 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11889 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
11890 } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
11892 /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
11893 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11894 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11895 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11896 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11898 /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource
11899 * on a secondary cell without an uplink configuration associated with the secondary cell */
11900 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11901 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
11902 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11904 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11905 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11906 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11907 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11908 if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
11910 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
11913 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11914 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11915 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11916 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11917 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
11918 } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
11920 rgSCHEmtcUtlUpdUeDciSize(cell, ueCb);
11925 * @brief This function initialises the DCI Size table
11929 * Function: rgSCHUtlCalcDciSizes
11930 * Purpose: This function calculates and initialises DCI Sizes in bits.
11932 * Invoked by: Scheduler
11934 * @param[in] RgSchCellCb *cell
11939 PUBLIC Void rgSCHUtlCalcDciSizes
11944 PUBLIC Void rgSCHUtlCalcDciSizes(cell)
11950 U32 bits = 0, idx = 0;
11952 switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
11954 case TFU_DCI_FORMAT_0:
11956 /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
11958 /*-- Calculate resource block assignment bits need to be set
11959 Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
11960 bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
11961 while ((bits & 0x8000) == 0)
11968 dciSize = 1 /* DCI 0 bit indicator */ + \
11969 1 /* Frequency hoping enable bit field */ + \
11970 (U8)bits /* For frequency Hopping */ + \
11977 2 /* UL Index Config 0 or DAI Config 1-6 */
11981 cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
11983 /* If hoping flag is enabled */
11984 if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
11986 cell->dciSize.dci0HopSize = 1;
11990 cell->dciSize.dci0HopSize = 2;
11993 /* Update common non-CRNTI scrambled DCI 0/1A flag */
11994 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
11996 case TFU_DCI_FORMAT_1A:
11998 /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
12001 /* Calculate resource block assignment bits need to be set
12002 Which is ln(N(N+1)/2) */
12003 bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
12004 while ((bits & 0x8000) == 0)
12011 dciSize += 1 /* Format 1A */ + \
12012 1 /* Local or Distributed */ + \
12013 (U8)bits /* Resource block Assignment */ + \
12016 4 /* HARQ Proc Id */ +
12018 3 /* HARQ Proc Id */ +
12028 cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
12030 /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI,
12031 * and the number of information bits in format 1A is less than that of format 0,
12032 * zeros shall be appended to format 1A until the payload size equals that of format 0. */
12033 /* Compare the size with DCI 1A and DCI 0 and consider the greater one */
12034 if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
12036 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
12038 /* If the number of information bits in format 1A belongs to one of the sizes in
12039 * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
12040 dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
12041 cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
12043 case TFU_DCI_FORMAT_1:
12045 /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
12047 if (cell->bwCfg.dlTotalBw > 10)
12049 dciSize = 1; /* Resource Allocation header bit */
12052 /* Resouce allocation bits Type 0 and Type 1 */
12053 bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
12054 if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
12059 dciSize += (U8)bits /* Resource Allocation bits */ + \
12067 2 /* Redunancy Version */ + \
12076 cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
12078 cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
12081 /* If the UE is not configured to decode PDCCH with CRC
12082 * scrambled by the C-RNTI and the number of information bits in format 1
12083 * is equal to that for format 0/1A, one bit of value zero shall be appended
12085 if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
12087 cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
12090 /* If the number of information bits in format 1 belongs to one of the sizes in
12091 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until
12092 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1
12093 * and is not equal to that of format 0/1A mapped onto the same search space. */
12094 cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
12095 } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
12097 case TFU_DCI_FORMAT_2:
12099 /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
12101 if (cell->bwCfg.dlTotalBw > 10)
12103 dciSize = 1; /* Resource Allocation bit */
12106 dciSize += (U8)bits /* Resource Allocation bits */ + \
12114 1 /* CW Swap Flag */ + \
12115 5 /* MCS for TB1 */+ \
12116 1 /* NDI for TB1 */+ \
12117 2 /* RV for TB1 */ + \
12118 5 /* MCS for TB2 */+ \
12119 1 /* NDI for TB2 */+ \
12120 2 /* RV for TB2 */;
12121 if (cell->numTxAntPorts == 2)
12125 else if (cell->numTxAntPorts == 4)
12129 cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
12130 cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
12132 case TFU_DCI_FORMAT_2A:
12134 /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
12136 if (cell->bwCfg.dlTotalBw > 10)
12138 dciSize = 1; /* Resource Allocation bit */
12141 dciSize += (U8)bits /* Resource Allocation bits */ + \
12149 1 /* CW Swap Flag */ + \
12150 5 /* MCS for TB1 */+ \
12151 1 /* NDI for TB1 */+ \
12152 2 /* RV for TB1 */ + \
12153 5 /* MCS for TB2 */+ \
12154 1 /* NDI for TB2 */+ \
12155 2 /* RV for TB2 */;
12156 if (cell->numTxAntPorts == 4)
12160 cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
12161 cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
12162 rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
12164 case TFU_DCI_FORMAT_3:
12166 /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
12167 cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
12168 if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
12170 cell->dciSize.size[TFU_DCI_FORMAT_3]++;
12173 case TFU_DCI_FORMAT_3A:
12175 /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
12176 cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
12179 case TFU_DCI_FORMAT_6_0A:
12181 rgSCHEmtcGetDciFrmt60ASize(cell);
12183 case TFU_DCI_FORMAT_6_1A:
12185 rgSCHEmtcGetDciFrmt61ASize(cell);
12190 /* DCI format not supported */
12197 * @brief Handler for the CPU OvrLd related state adjustment.
12201 * Function : rgSCHUtlCpuOvrLdAdjItbsCap
12203 * Processing Steps:
12204 * - Record dl/ulTpts
12205 * - Adjust maxItbs to acheive target throughputs
12207 * @param[in] RgSchCellCb *cell
12211 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap
12216 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap(cell)
12222 TRC3(rgSCHUtlCpuOvrLdAdjItbsCap)
12224 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP |
12225 RGR_CPU_OVRLD_DL_TPT_DOWN))
12227 /* Regulate DL Tpt for CPU overload */
12228 if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
12230 tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
12231 /* Upto 0.5% drift in measured vs target tpt is ignored */
12232 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12234 cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
12239 tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
12240 /* Upto 0.5% drift in measured vs target tpt is ignored */
12241 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12243 cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
12246 #ifdef CPU_OL_DBG_PRINTS
12247 printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt,
12248 cell->thresholds.maxDlItbs);
12252 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP |
12253 RGR_CPU_OVRLD_UL_TPT_DOWN))
12255 /* Regualte DL Tpt for CPU overload */
12256 if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
12258 tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
12259 /* Upto 1% drift in measured vs target tpt is ignored */
12260 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12262 cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
12267 tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
12268 /* Upto 1% drift in measured vs target tpt is ignored */
12269 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12271 cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
12274 #ifdef CPU_OL_DBG_PRINTS
12275 printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt,
12276 cell->thresholds.maxUlItbs);
12283 * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
12287 * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12289 * Processing Steps:
12290 * - Validate the config params.
12291 * - Update numUEperTTi CPU OL related information.
12292 * - If successful, return ROK else RFAILED.
12294 * @param[in] RgSchCellCb *cell
12295 * @param[in] U8 cnrtCpuOvrLdIns
12299 PRIVATE Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12305 PRIVATE S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns)
12307 U8 crntCpuOvrLdIns;
12310 RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl);
12311 RgSchCmnCell *cellSch;
12312 U8 maxUeNewDlTxPerTti;
12313 U8 maxUeNewUlTxPerTti;
12315 #ifdef CPU_OL_DBG_PRINTS
12321 cellSch = RG_SCH_CMN_GET_CELL(cell);
12323 maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti;
12324 maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
12326 /* Calculate Maximum Decremen */
12327 maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12328 maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12330 /* Check for DL CPU Commands */
12331 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI )
12333 /* Decrement till 90% of maxUeNewDlTxPerTti */
12334 if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
12336 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12337 cpuInstr->dlNxtIndxDecNumUeTti++;
12338 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] > 1 )
12340 cpuInstr->maxUeNewTxPerTti[tmpslot]--;
12344 #ifdef CPU_OL_DBG_PRINTS
12345 printf("CPU_OL_TTI__ERROR\n");
12347 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12350 #ifdef CPU_OL_DBG_PRINTS
12351 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12353 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12354 cpuInstr->dlNxtIndxDecNumUeTti);
12356 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
12358 if ( cpuInstr->dlNxtIndxDecNumUeTti > 0)
12360 cpuInstr->dlNxtIndxDecNumUeTti--;
12361 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12362 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] < maxUeNewDlTxPerTti )
12364 cpuInstr->maxUeNewTxPerTti[tmpslot]++;
12368 #ifdef CPU_OL_DBG_PRINTS
12369 printf("CPU_OL_TTI__ERROR\n");
12371 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12374 #ifdef CPU_OL_DBG_PRINTS
12375 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12377 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12378 cpuInstr->dlNxtIndxDecNumUeTti);
12380 /* Check for UL CPU commands */
12381 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
12383 /* Decrement till 90% of maxUeNewDlTxPerTti */
12384 if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
12386 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12387 cpuInstr->ulNxtIndxDecNumUeTti++;
12388 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] > 1 )
12390 cpuInstr->maxUeNewRxPerTti[tmpslot]--;
12394 #ifdef CPU_OL_DBG_PRINTS
12395 printf("CPU_OL_TTI__ERROR\n");
12397 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12400 #ifdef CPU_OL_DBG_PRINTS
12401 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12403 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12404 cpuInstr->dlNxtIndxDecNumUeTti);
12406 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
12408 if ( cpuInstr->ulNxtIndxDecNumUeTti > 0)
12410 cpuInstr->ulNxtIndxDecNumUeTti--;
12411 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12412 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] < maxUeNewUlTxPerTti )
12414 cpuInstr->maxUeNewRxPerTti[tmpslot]++;
12418 #ifdef CPU_OL_DBG_PRINTS
12419 printf("CPU_OL_TTI__ERROR\n");
12421 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12424 #ifdef CPU_OL_DBG_PRINTS
12425 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12427 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12428 cpuInstr->dlNxtIndxDecNumUeTti);
12430 #ifdef CPU_OL_DBG_PRINTS
12431 /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
12432 printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
12433 printf("DL Sf numUePerTti:");
12434 for ( idx = 0; idx < 10 ; idx ++ )
12436 printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]);
12438 printf("\nUL Sf numUePerTti:");
12439 for ( idx = 0; idx < 10 ; idx ++ )
12441 printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]);
12447 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
12450 * @brief Handler for the CPU OvrLd related cell Recfg.
12454 * Function : rgSCHUtlResetCpuOvrLdState
12456 * Processing Steps:
12457 * - Validate the config params.
12458 * - Update CPU OL related state information.
12459 * - If successful, return ROK else RFAILED.
12461 * @param[in] RgSchCellCb *cell
12462 * @param[in] U8 cnrtCpuOvrLdIns
12468 PUBLIC S16 rgSCHUtlResetCpuOvrLdState
12474 PUBLIC S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns)
12476 U8 crntCpuOvrLdIns;
12481 RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
12484 TRC3(rgSCHUtlResetCpuOvrLdState)
12486 #ifdef CPU_OL_DBG_PRINTS
12487 printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
12489 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd");
12491 if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
12493 /* The CPU OL instruction received with RESET (0), hence reset it */
12494 #ifdef CPU_OL_DBG_PRINTS
12495 printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
12497 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD");
12498 cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
12499 /* Reset the max UL and DL itbs to 26 */
12500 cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
12501 cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
12502 /* Reset the num UE per TTI intructions */
12503 cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
12504 cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
12505 for ( idx = 0; idx < 10; idx++ )
12507 cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] =
12508 schCmnCell->dl.maxUeNewTxPerTti;
12509 cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] =
12510 schCmnCell->ul.maxUeNewTxPerTti;
12515 /* Check and Update numUEPer TTI based CPU overload instruction before
12516 * going for TP based CPU OL
12517 * TTI based intrcuctions shall be > 0xF */
12518 if ( crntCpuOvrLdIns > 0xF )
12520 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
12521 /* If need to have both TP and numUePerTti instrcution together in
12522 * one command then dont return from here */
12526 crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
12527 (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
12528 if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) &&
12529 (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
12531 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12534 crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
12535 (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
12536 if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) &&
12537 (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
12539 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12542 if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
12544 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12548 cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
12552 if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
12554 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
12555 (cell->measurements.ulTpt * 3 )/100;
12559 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
12560 (cell->measurements.ulTpt * 2 )/100;
12562 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to "
12563 "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
12564 #ifdef CPU_OL_DBG_PRINTS
12565 printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
12566 cell->measurements.ulTpt);
12572 if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
12574 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
12575 (cell->measurements.dlTpt * 1 )/100;
12579 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
12580 (cell->measurements.dlTpt * 1 )/100;
12582 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to "
12583 "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
12585 #ifdef CPU_OL_DBG_PRINTS
12586 printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
12587 cell->measurements.dlTpt);
12590 rgSCHUtlCpuOvrLdAdjItbsCap(cell);
12594 PUBLIC S16 rgSCHUtlAddToResLst
12597 RgSchIotRes *iotRes
12600 cmLListAdd2Tail(cp, &iotRes->resLnk);
12601 iotRes->resLnk.node = (PTR)iotRes;
12604 PUBLIC S16 rgSCHUtlDelFrmResLst
12607 RgSchIotRes *iotRes
12610 CmLListCp *cp = NULLP;
12611 RgSchEmtcUeInfo *emtcUe = NULLP;
12612 emtcUe = RG_GET_EMTC_UE_CB(ue);
12613 if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
12615 cp = &emtcUe->ulResLst;
12616 }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
12618 cp = &emtcUe->dlResLst;
12621 RLOG0(L_INFO, "*****restype mismatch");
12627 RLOG0(L_INFO,"****error count*****\n");
12631 cmLListDelFrm(cp, &iotRes->resLnk);
12632 iotRes->resLnk.node = NULLP;
12636 /**********************************************************************
12639 **********************************************************************/