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
241 PRIVATE U8 rgSCHUtlFetchPcqiBitSz ARGS((
248 /* sorted in ascending order of tbSz */
249 CONSTANT struct rgSchUtlBcchPcchTbSz
251 U8 rbIndex; /* RB index {2,3} */
252 U16 tbSz; /* one of the Transport block size in bits of
254 /* Corrected allocation for common channels */
256 } rgSchUtlBcchPcchTbSzTbl[44] = {
257 { 2, 32, 0 }, { 2, 56, 1 }, { 2, 72, 2 }, { 3, 88, 1 },
258 { 2, 104, 3 }, { 2, 120, 4 }, { 2, 144, 5 }, { 2, 176, 6 },
259 { 3, 208, 4 }, { 2, 224, 7 }, { 2, 256, 8 }, { 2, 296, 9 },
260 { 2, 328, 10 }, { 2, 376, 11 }, { 3, 392, 8 }, { 2, 440, 12 },
261 { 3, 456, 9 }, { 2, 488, 13 }, { 3, 504, 10 }, { 2, 552, 14 },
262 { 3, 584, 11 }, { 2, 600, 15 }, { 2, 632, 16 }, { 3, 680, 12 },
263 { 2, 696, 17 }, { 3, 744, 13 }, { 2, 776, 18 }, { 2, 840, 19 },
264 { 2, 904, 20 }, { 3, 968, 16 }, { 2, 1000, 21 }, { 2, 1064, 22 },
265 { 2, 1128, 23 }, { 3, 1160, 18 }, { 2, 1192, 24 }, { 2, 1256, 25 },
266 { 3, 1288, 19 }, { 3, 1384, 20 }, { 2, 1480, 26 }, { 3, 1608, 22 },
267 { 3, 1736, 23 }, { 3, 1800, 24 }, { 3, 1864, 25 }, { 3, 2216, 26 }
274 /* forward references */
276 PRIVATE Void rgSCHUtlUpdPrachOcc ARGS((
278 RgrTddPrachInfo *cellCfg));
281 #define RGSCH_NUM_PCFICH_REG 4
282 #define RGSCH_NUM_REG_PER_CCE 9
283 #define RGSCH_NUM_REG_PER_PHICH_GRP 3
286 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _iPhich) {\
287 (_phich)->hqFeedBack = _hqFeedBack; \
288 (_phich)->rbStart = _rbStart; \
289 (_phich)->nDmrs = _nDmrs; \
290 (_phich)->iPhich = _iPhich; \
291 (_phich)->lnk.next = NULLP; \
292 (_phich)->lnk.prev = NULLP; \
293 (_phich)->lnk.node = (PTR)(_phich); \
296 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _isForMsg3) {\
297 (_phich)->hqFeedBack = _hqFeedBack; \
298 (_phich)->rbStart = _rbStart; \
299 (_phich)->nDmrs = _nDmrs; \
300 (_phich)->isForMsg3 = _isForMsg3; \
301 (_phich)->lnk.next = NULLP; \
302 (_phich)->lnk.prev = NULLP; \
303 (_phich)->lnk.node = (PTR)(_phich); \
307 #define RGSCH_PHICH_ALLOC(_inst,_dataPtr, _size, _ret) {\
308 _ret = rgSCHUtlAllocSBuf(_inst, (Data **)&_dataPtr, _size); \
311 /* ccpu00117052 - MOD - Passing double pointer
312 for proper NULLP assignment*/
313 #define RGSCH_PHICH_FREE(_inst, _dataPtr, _size) {\
314 rgSCHUtlFreeSBuf(_inst, (Data **)(&(_dataPtr)), _size); \
318 #define RGSCH_GETBIT(a, b) ((((U8*)a)[(b)>>3] >> ((7-((b)&7)))) & 1)
324 * Desc: This function finds of the Power of x raised to n
326 * Ret: value of x raised to n
334 PUBLIC F64 rgSCHUtlPower
340 PUBLIC F64 rgSCHUtlPower(x, n)
351 RETVALUE( x * rgSCHUtlPower( x, n-1 ) );
355 RETVALUE( (1/x) * rgSCHUtlPower( x, n+1 ) );
357 } /* end of rgSCHUtlPower*/
363 * Desc: This function parses bits x to y of an array and
364 * returns the integer value out of it.
366 * Ret: integer value of z bits
374 PUBLIC U32 rgSCHUtlParse
382 PUBLIC U32 rgSCHUtlParse(buff, startPos, endPos, buffSize)
389 U8 pointToChar,pointToEnd, loop;
390 U8 size = endPos - startPos;
393 pointToEnd = (startPos)%8;
394 for ( loop=0; loop<size; loop++)
396 pointToChar = (((startPos)+loop)/8);
397 if (RGSCH_GETBIT(buff+pointToChar,pointToEnd%8)==1)
399 result=result+(rgSCHUtlPower(2,(size-loop-1)));
403 RETVALUE((U32)result);
404 } /* end of rgSCHUtlParse*/
408 * Fun: rgSCHUtlFindDist
410 * Desc: This function calculates the iterations need to cover
411 * before the valid Index can be used for next possible Reception
413 * Ret: integer value of z bits
421 PUBLIC U8 rgSCHUtlFindDist
427 PUBLIC U8 rgSCHUtlFindDist(crntTime, tempIdx)
433 /* ccpu00137113- Distance is not estimated properly if the periodicity is
434 * equal to RG_SCH_PCQI_SRS_SR_TRINS_SIZE.
436 while(crntTime<=tempIdx)
438 crntTime += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
442 } /* end of rgSCHUtlFindDist*/
447 * @brief This function checks availability of a PDCCH
451 * Function: rgSCHUtlPdcchAvail
452 * Purpose: This function checks if a particular PDCCH is in use.
453 * map field of PDCCH is used to track the CCEs arleady
454 * allocated. Each bit of map represents one CCE and the
455 * LSBit of first byte represents CCE 0.
457 * 1. Locate the set of bits that represent the PDCCH for
458 * the provided location.
459 * 2. If the value of the bits is non-zero one or many CCEs
460 * for the PDCCH are in use and hence the PDCCH is not available.
461 * 3. If pdcch is available, assign it to [out]pdcch.
462 * 4. Set all of the bits to one. There is no check performed
463 * to see if the PDCCH is available.
465 * Invoked by: scheduler
467 * @param[in] RgSchCellCb* cell
468 * @param[in] RgSchPdcchInfo* pdcchInfo
470 * @param[in] U8 aggrLvl
471 * @param[out] RgSchPdcch** pdcch
473 * -# TRUE if available
478 PUBLIC Bool rgSCHUtlPdcchAvail
481 RgSchPdcchInfo *pdcchInfo,
482 CmLteAggrLvl aggrLvl,
486 PUBLIC Bool rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, pdcch)
488 RgSchPdcchInfo *pdcchInfo;
489 CmLteAggrLvl aggrLvl;
497 Inst inst = cell->instIdx;
501 TRC2(rgSCHUtlPdcchAvail);
505 byte = &pdcchInfo->map[0];
506 initMask = (0xffff >> (16 - aggrLvl));
508 /* if N(symbol, xPDCCH) =2, then xPDCCH will be candidates in
509 * search space of index {0,1,2,3} and {8,9,..14}
511 if ((cell->cell5gtfCb.cfi == 2) && (aggrLvl == CM_LTE_AGGR_LVL2))
513 offsetStepMask = 0xc;
517 offsetStepMask = 0xc0;
520 /* Loop till the number of bytes available in the CCE map */
521 while (offset < ((pdcchInfo->nCce+ 7) >> 3))
523 byte = &pdcchInfo->map[offset];
524 /* Checking for available CCE */
525 if ((*byte & currMask) == 0)
529 /* if the number of CCEs required are not available, move to next offset */
530 if (currMask & offsetStepMask)
537 /* Move to the next available CCE index in the current byte(cce map) */
538 currMask = currMask << aggrLvl;
542 if ((offset >= ((pdcchInfo->nCce + 7) >> 3)) ||
543 ((aggrLvl == CM_LTE_AGGR_LVL16) && (offset > 0)))
548 byte = &pdcchInfo->map[offset];
550 if (cell->pdcchLst.first != NULLP)
552 *pdcch = (RgSchPdcch *)(cell->pdcchLst.first->node);
553 cmLListDelFrm(&cell->pdcchLst, cell->pdcchLst.first);
557 ret = rgSCHUtlAllocSBuf(inst, (Data **)pdcch, sizeof(RgSchPdcch));
567 /* ALL CCEs will be used in case of level 16 */
568 if (aggrLvl == CM_LTE_AGGR_LVL16)
570 *(byte+1) |= currMask;
572 (*pdcch)->aggrLvl = aggrLvl;
573 cmLListAdd2Tail(&pdcchInfo->pdcchs, &((*pdcch)->lnk));
574 (*pdcch)->lnk.node = (PTR)*pdcch;
575 (*pdcch)->nCce = aggrLvl;
576 (*pdcch)->ue = NULLP;
584 * @brief This function releases a PDCCH
588 * Function: rgSCHUtlPdcchPut
589 * Purpose: This function releases a PDCCH.
591 * 1. Locate the set of bits that represent the PDCCH for
592 * the provided location.
593 * 2. Set all of the bits to zero.
594 * 3. Release the memory of PDCCH to the cell free Q
596 * Invoked by: scheduler
598 * @param[in] RgSchPdcchInfo* pdcchInfo
600 * @param[in] U8 aggrLvl
605 PUBLIC Void rgSCHUtlPdcchPut
608 RgSchPdcchInfo *pdcchInfo,
612 PUBLIC Void rgSCHUtlPdcchPut(cell, pdcchInfo, pdcch)
614 RgSchPdcchInfo *pdcchInfo;
622 TRC2(rgSCHUtlPdcchPut);
624 switch(pdcch->aggrLvl)
626 case CM_LTE_AGGR_LVL2:
627 offset = (pdcch->nCce >> 1) & 3;
628 mask = 0x3 << (offset * 2); /*ccpu00128826 - Offset Correction */
630 case CM_LTE_AGGR_LVL4:
631 offset = (pdcch->nCce >> 2) & 1;
632 mask = 0xf << (offset * 4);/*ccpu00128826 - Offset Correction */
634 case CM_LTE_AGGR_LVL8:
637 case CM_LTE_AGGR_LVL16:
643 /* Placing common computation of byte from all the cases above here
645 byte = &pdcchInfo->map[pdcch->nCce >> 3];
647 cmLListDelFrm(&pdcchInfo->pdcchs, &pdcch->lnk);
648 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
649 pdcch->lnk.node = (PTR)pdcch;
658 * @brief This function initializes PDCCH information for frame
662 * Function: rgSCHUtlPdcchInit
663 * Purpose: This function initializes PDCCH information for
664 * a slot. It removes the list of PDCCHs allocated
665 * in the prior use of this slot structure.
667 * Invoked by: rgSCHUtlSubFrmPut
669 * @param[in] RgSchCellCb* cell
670 * @param[in] RgSubFrm* subFrm
675 PUBLIC Void rgSCHUtlPdcchInit
682 PUBLIC Void rgSCHUtlPdcchInit(cell, subFrm, nCce)
688 RgSchPdcchInfo *pdcchInfo;
690 Inst inst = cell->instIdx;
694 TRC2(rgSCHUtlPdcchInit);
696 pdcchInfo = &subFrm->pdcchInfo;
697 while(pdcchInfo->pdcchs.first != NULLP)
699 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
700 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
701 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
704 cmLListInit(&pdcchInfo->pdcchs);
707 subFrm->relPdcch = NULLP;
710 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
712 /* The bitMap array size is the number of ceiling(CCEs/8) */
713 /* If nCce received is not the same as the one stored in
714 * pdcchInfo, free the pdcchInfo map */
716 if(pdcchInfo->nCce != nCce)
720 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), cceMapSz);
722 pdcchInfo->nCce = nCce;
723 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
724 rgSCHUtlAllocSBuf(inst, (Data **)&pdcchInfo->map,
726 if (pdcchInfo->map == NULLP)
728 /* Generate log error here */
733 cmMemset(subFrm->pdcchInfo.map, 0, cceMapSz);
734 /* If nCce is not exactly same as the bitMap size(no of bits allocated
735 * to represent the Cce's, then mark the extra bits as unavailable
736 extra bits = (((pdcchInfo->nCce + 7) >> 3)*8) - pdcchInfo->nCce
737 The last byte of bit map = subFrm->pdcchInfo.map[((pdcchInfo->nCce + 7) >> 3) - 1]
738 NOTE : extra bits are most significant of the last byte eg. */
739 extraBits = (cceMapSz)*8 - pdcchInfo->nCce;
740 subFrm->pdcchInfo.map[cceMapSz - 1] |=
741 ((1 << extraBits) - 1) << (8 - extraBits);
745 /* LTE_ADV_FLAG_REMOVED_START */
747 * @brief This function frees Pool
750 * Function: rgSchSFRTotalPoolFree
752 * Invoked by: rgSchSFRTotalPoolInit
754 * @param[in] RgSchCellCb* cell
755 * @param[in] RgSubFrm* subFrm
760 PUBLIC Void rgSchSFRTotalPoolFree
762 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo,
766 PUBLIC Void rgSchSFRTotalPoolFree(sfrTotalPoolInfo, cell)
767 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo;
773 TRC2(rgSchSFRTotalPoolFree);
775 /*Deinitialise if these cc pools and ce pools are already existent*/
776 l = &sfrTotalPoolInfo->ccPool;
780 /*REMOVING Cell Centred POOLS IF ANY*/
781 n = cmLListDelFrm(l, n);
783 /* Deallocate buffer */
784 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
786 /* Deallocate buffer */
787 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
791 /*REMOVING Cell Edged POOLS IF ANY*/
792 l = &sfrTotalPoolInfo->cePool;
796 n = cmLListDelFrm(l, n);
798 /* Deallocate buffer */
799 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
801 /* Deallocate buffer */
802 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
809 * @brief This function resets temporary variables in Pool
812 * Function: rgSchSFRResetPoolVariables
814 * Invoked by: rgSCHSFRUtlTotalPoolInit
816 * @param[in] RgSchCellCb* cell
817 * @param[in] RgSubFrm* subFrm
822 PUBLIC S16 rgSchSFRTotalPoolInit
828 PRIVATE Void rgSchSFRTotalPoolInit(cell, sf)
833 /* Initialise the variables */
834 RgSchSFRPoolInfo *sfrCCPool;
835 RgSchSFRPoolInfo *sfrCEPool;
838 CmLList *temp = NULLP;
841 TRC2(rgSchSFRTotalPoolInit);
843 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
844 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = 0;
845 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = 0;
846 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = 0;
847 sf->sfrTotalPoolInfo.CC1 = FALSE;
848 sf->sfrTotalPoolInfo.CC2 = FALSE;
849 /*Initialise the CE Pools*/
850 cmLListInit (&(sf->sfrTotalPoolInfo.cePool));
852 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
855 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
856 "CE Pool memory allocation FAILED for cell");
857 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
861 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
864 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
865 "CE Pool memory allocation FAILED for cell ");
866 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
870 l = &sf->sfrTotalPoolInfo.cePool;
871 cmLListAdd2Tail(l, temp);
873 /*Initialise Bandwidth and startRB and endRB for each pool*/
876 /* Initialise the CE Pools */
877 sfrCEPool = (RgSchSFRPoolInfo*)n->node;
879 sfrCEPool->poolstartRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb;
880 sfrCEPool->poolendRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb;
881 sfrCEPool->bw = sfrCEPool->poolendRB - sfrCEPool->poolstartRB + 1;
882 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = sfrCEPool->bw;
884 sfrCEPool->bwAlloced = 0;
885 sfrCEPool->type2Start = sfrCEPool->poolstartRB;
886 sfrCEPool->type2End = RGSCH_CEIL(sfrCEPool->poolstartRB, cell->rbgSize);
887 sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1;
888 sfrCEPool->pwrHiCCRange.startRb = 0;
889 sfrCEPool->pwrHiCCRange.endRb = 0;
891 /*Initialise CC Pool*/
892 cmLListInit (&(sf->sfrTotalPoolInfo.ccPool));
894 /*Add memory and Update CCPool*/
895 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
898 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
899 "CC Pool memory allocation FAILED for cell ");
900 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
904 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
907 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
908 "CC Pool memory allocation FAILED for cell ");
909 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
913 l = &sf->sfrTotalPoolInfo.ccPool;
914 cmLListAdd2Tail(l, temp);
916 /*Initialise Bandwidth and startRB and endRB for each pool*/
917 if(sfrCEPool->poolstartRB)
920 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
922 sfrCCPool->poolstartRB = 0;
923 sfrCCPool->poolendRB = sfrCEPool->poolstartRB - 1;
924 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
925 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = sfrCCPool->bw;
926 sfrCCPool->bwAlloced = 0;
927 sfrCCPool->type2Start = 0;
928 sfrCCPool->type2End = 0;
929 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
930 sf->sfrTotalPoolInfo.CC1 = TRUE;
931 sfrCCPool->pwrHiCCRange.startRb = 0;
932 sfrCCPool->pwrHiCCRange.endRb = 0;
937 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
939 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
940 sfrCCPool->poolendRB = sf->bw - 1;
941 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
942 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
943 sfrCCPool->CCPool2Exists = TRUE;
944 sfrCCPool->bwAlloced = 0;
945 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
946 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
947 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
948 sf->sfrTotalPoolInfo.CC2 = TRUE;
949 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
950 sfrCCPool->pwrHiCCRange.startRb = 0;
951 sfrCCPool->pwrHiCCRange.endRb = 0;
954 if((sfrCEPool->poolendRB != sf->bw - 1) && (!sfrCCPool->poolstartRB))
956 /*Add memory and Update CCPool*/
957 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
960 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
961 "CC Pool memory allocation FAILED for cell ");
962 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
966 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
969 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
970 "CC Pool memory allocation FAILED for cell ");
971 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
975 cmLListAdd2Tail(l, temp);
978 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
980 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
981 sfrCCPool->poolendRB = sf->bw - 1;
982 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
983 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
984 sfrCCPool->CCPool2Exists = TRUE;
985 sfrCCPool->bwAlloced = 0;
986 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
987 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
988 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
989 sf->sfrTotalPoolInfo.CC2 = TRUE;
990 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
991 sfrCCPool->pwrHiCCRange.startRb = 0;
992 sfrCCPool->pwrHiCCRange.endRb = 0;
995 sf->sfrTotalPoolInfo.CCRetx = FALSE;
996 sf->sfrTotalPoolInfo.CERetx = FALSE;
998 sf->sfrTotalPoolInfo.ccBwFull = FALSE;
999 sf->sfrTotalPoolInfo.ceBwFull = FALSE;
1000 sf->sfrTotalPoolInfo.isUeCellEdge = FALSE;
1004 * @brief This function resets temporary variables in RNTP Prepration
1007 * Function: rgSchDSFRRntpInfoInit
1009 * Invoked by: rgSCHSFRUtlTotalPoolInit
1011 * @param[in] TknStrOSXL* rntpPtr
1012 * @param[in] RgSubFrm* subFrm
1017 PUBLIC S16 rgSchDSFRRntpInfoInit
1019 TknStrOSXL *rntpPtr,
1024 PRIVATE Void rgSchDSFRRntpInfoInit(rntpPtr, cell, bw)
1025 TknStrOSXL *rntpPtr;
1030 Inst inst = cell->instIdx;
1033 TRC2(rgSchDSFRRntpInfoInit);
1035 rntpPtr->pres = PRSNT_NODEF;
1037 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1041 /* Allocate memory for "scheduled UE" Info */
1042 if((rgSCHUtlAllocSBuf(inst, (Data**)&(rntpPtr->val),
1043 (len * sizeof(U8)))) != ROK)
1045 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
1053 * @brief This function release RNTP pattern from slot and Cell
1056 * Function: rgSchDSFRRntpInfoFree
1058 * Invoked by: rgSCHSFRUtlTotalPoolInit
1060 * @param[in] TknStrOSXL* rntpPtr
1061 * @param[in] RgSubFrm* subFrm
1066 PUBLIC S16 rgSchDSFRRntpInfoFree
1068 TknStrOSXL *rntpPtr,
1073 PRIVATE Void rgSchDSFRRntpInfoFree(rntpPtr, cell, bw)
1074 TknStrOSXL *rntpPtr;
1079 Inst inst = cell->instIdx;
1082 TRC2(rgSchDSFRRntpInfoFree);
1084 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1086 if(rntpPtr->pres == PRSNT_NODEF)
1088 rgSCHUtlFreeSBuf(inst, (Data **)(&(rntpPtr->val)),(len * sizeof(U8)));
1089 rntpPtr->pres = NOTPRSNT;
1097 * @brief This function resets temporary variables in Pool
1100 * Function: rgSchSFRResetPoolVariables
1101 * Purpose: Initialise the dynamic variables in each pool.
1102 * Reset bwAlloced, bwAssigned, type2End, type0End, type2Start
1103 * Invoked by: rgSCHSFRUtlTotalPoolReset
1105 * @param[in] RgSchCellCb* cell
1106 * @param[in] RgSchSFRPoolInfo *pool
1111 PRIVATE Void rgSchSFRResetPoolVariables
1114 RgSchSFRPoolInfo *pool
1117 PRIVATE Void rgSchSFRResetPoolVariables(cell, pool)
1119 RgSchSFRPoolInfo *pool;
1123 TRC2(rgSchSFRResetPoolVariables);
1124 pool->bwAlloced = 0;
1126 /*type0end will be the last RBG in pool with all available RBs*/
1127 pool->type0End = (((pool->poolendRB + 1)/cell->rbgSize) - 1);
1129 /*type2end will be the first RBG in pool with all available RBs*/
1130 pool->type2End = RGSCH_CEIL(pool->poolstartRB, cell->rbgSize);
1131 pool->type2Start = pool->poolstartRB;
1132 pool->bw = pool->poolendRB - pool->poolstartRB + 1;
1137 * @brief This function resets SFR Pool information for frame
1141 * Function: rgSCHSFRUtlTotalPooReset
1142 * Purpose: Update the dynamic variables in each pool as they will be modified in each slot.
1143 * Dont modify the static variables like startRB, endRB, BW
1144 * Invoked by: rgSCHUtlSubFrmPut
1146 * @param[in] RgSchCellCb* cell
1147 * @param[in] RgSchDlSf* subFrm
1152 PRIVATE Void rgSCHSFRUtlTotalPoolReset
1158 PRIVATE Void rgSCHSFRUtlTotalPoolReset(cell, subFrm)
1163 RgSchSFRTotalPoolInfo *totalPoolInfo = &subFrm->sfrTotalPoolInfo;
1164 CmLListCp *ccPool = &totalPoolInfo->ccPool;
1165 CmLListCp *cePool = &totalPoolInfo->cePool;
1166 CmLList *node = NULLP;
1167 RgSchSFRPoolInfo *tempPool = NULLP;
1169 TRC2(rgSCHSFRUtlTotalPoolReset);
1171 totalPoolInfo->ccBwFull = FALSE;
1172 totalPoolInfo->ceBwFull = FALSE;
1173 totalPoolInfo->isUeCellEdge = FALSE;
1174 totalPoolInfo->CCPool1BwAvlbl = 0;
1175 totalPoolInfo->CCPool2BwAvlbl = 0;
1176 totalPoolInfo->CEPoolBwAvlbl = 0;
1177 totalPoolInfo->CCRetx = FALSE;
1178 totalPoolInfo->CERetx = FALSE;
1180 node = ccPool->first;
1183 tempPool = (RgSchSFRPoolInfo *)(node->node);
1185 rgSchSFRResetPoolVariables(cell, tempPool);
1186 if(tempPool->poolstartRB == 0)
1187 totalPoolInfo->CCPool1BwAvlbl = tempPool->bw;
1189 totalPoolInfo->CCPool2BwAvlbl = tempPool->bw;
1192 node = cePool->first;
1195 tempPool = (RgSchSFRPoolInfo *)(node->node);
1197 rgSchSFRResetPoolVariables(cell, tempPool);
1198 totalPoolInfo->CEPoolBwAvlbl = tempPool->bw;
1203 /* LTE_ADV_FLAG_REMOVED_END */
1205 * @brief This function appends PHICH information for frame
1209 * Function: rgSCHUtlAddPhich
1210 * Purpose: This function appends PHICH information for
1215 * @param[in] RgSchCellCb* cell
1216 * @param[in] RgSubFrm* subFrm
1217 * @param[in] U8 hqFeedBack
1218 * @param[in] U8 nDmrs
1219 * @param[in] U8 rbStart
1226 PUBLIC S16 rgSCHUtlAddPhich
1229 CmLteTimingInfo frm,
1236 PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, iPhich)
1238 CmLteTimingInfo frm;
1246 PUBLIC S16 rgSCHUtlAddPhich
1249 CmLteTimingInfo frm,
1256 PUBLIC S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, isForMsg3)
1258 CmLteTimingInfo frm;
1269 Inst inst = cell->instIdx;
1270 TRC2(rgSCHUtlAddPhich);
1272 dlSf = rgSCHUtlSubFrmGet(cell, frm);
1273 RGSCH_PHICH_ALLOC(inst, phich,sizeof(RgSchPhich), ret);
1277 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, " rgSCHUtlAddPhich(): "
1278 "Allocation of RgSchPhich failed");
1282 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, iPhich);
1284 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, isForMsg3); /*SR_RACH_STATS */
1286 cmLListAdd2Tail(&dlSf->phichInfo.phichs, &phich->lnk);
1288 } /* rgSCHUtlAddPhich */
1291 * @brief This function resets PHICH information for frame
1295 * Function: rgSCHUtlPhichReset
1296 * Purpose: This function initializes PHICH information for
1297 * a slot. It removes the list of PHICHs allocated
1298 * in the prior use of this slot structure.
1300 * Invoked by: rgSCHUtlSubFrmPut
1302 * @param[in] RgSchCellCb* cell
1303 * @param[in] RgSubFrm* subFrm
1308 PRIVATE Void rgSCHUtlPhichReset
1314 PRIVATE Void rgSCHUtlPhichReset(cell, subFrm)
1319 RgSchPhichInfo *phichInfo;
1324 TRC2(rgSCHUtlPhichReset);
1326 phichInfo = &subFrm->phichInfo;
1327 while(phichInfo->phichs.first != NULLP)
1329 phich = (RgSchPhich *)phichInfo->phichs.first->node;
1330 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
1331 RGSCH_PHICH_FREE(cell->instIdx, phich, sizeof(RgSchPhich));
1333 cmLListInit(&phichInfo->phichs);
1335 } /* rgSCHUtlPhichReset */
1339 * @brief This function returns slot data structure for a cell
1343 * Function: rgSCHUtlSubFrmGet
1344 * Purpose: This function resets the slot data structure
1345 * when the slot is released
1347 * Invoked by: scheduler
1349 * @param[in] RgSubFrm subFrm
1354 PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet
1360 PUBLIC RgSchDlSf* rgSCHUtlSubFrmGet(cell, frm)
1362 CmLteTimingInfo frm;
1368 TRC2(rgSCHUtlSubFrmGet);
1371 dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
1372 //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1373 sf = cell->subFrms[dlIdx];
1375 /* Changing the idexing
1376 so that proper slot is selected */
1377 dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
1378 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1379 sf = cell->subFrms[dlIdx];
1389 * @brief This function returns slot data structure for a cell
1393 * Function: rgSCHUtlSubFrmPut
1394 * Purpose: This function resets the slot data structure
1395 * when the slot is released
1397 * Invoked by: scheduler
1399 * @param[in] RgSubFrm subFrm
1404 PUBLIC Void rgSCHUtlSubFrmPut
1410 PUBLIC Void rgSCHUtlSubFrmPut(cell, sf)
1418 TRC2(rgSCHUtlSubFrmPut);
1421 /* Release all the held PDCCH information */
1422 rgSCHUtlPdcchInit(cell, sf, sf->nCce);
1424 /* Release all the held PDCCH information */
1425 rgSCHUtlPdcchInit(cell, sf, cell->nCce);
1427 rgSCHUtlPhichReset(cell, sf);
1429 /* Reset the bw allocated. */
1432 /* Setting allocated bandwidth to SPS bandwidth for non-SPS RB allocator */
1433 sf->bwAlloced = ((cell->spsCellCfg.maxSpsDlBw +
1434 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
1435 if (sf->bwAlloced > sf->bw)
1437 sf->bwAlloced = sf->bw;
1439 sf->spsAllocdBw = 0;
1440 sf->type2Start = sf->bwAlloced;
1441 cmMemset((U8*) &sf->dlSfAllocInfo, 0, sizeof(RgSchDlSfAllocInfo));
1444 /* Fix for ccpu00123918*/
1446 /* LTE_ADV_FLAG_REMOVED_START */
1447 /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
1448 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
1450 cmMemset((U8*) sf->rntpInfo.val, 0, sf->rntpInfo.len);
1452 /* LTE_ADV_FLAG_REMOVED_END */
1455 /*[ccpu00138609]-ADD-Reset the CCCH UE counter */
1458 /* Non DLFS scheduling using Type0 RA requires the following
1459 * parameter's tracking */
1460 /* Type 2 localized allocations start from 0th RBG and onwards */
1461 /* Type 0 allocations start from last RBG and backwards*/
1465 sf->type2End = RGSCH_CEIL(sf->bwAlloced,cell->rbgSize);
1467 sf->type0End = cell->noOfRbgs - 1;
1468 /* If last RBG is of incomplete size then special handling */
1469 (sf->bw % cell->rbgSize == 0)? (sf->lstRbgDfct = 0) :
1470 (sf->lstRbgDfct = cell->rbgSize - (sf->bw % cell->rbgSize));
1471 /* This resets the allocation for BCCH and PDCCH */
1473 /* TODO we need to move this reset for emtc functions */
1474 if(!(cell->emtcEnable))
1483 sf->bcch.pdcch = NULLP;
1484 sf->pcch.pdcch = NULLP;
1486 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
1488 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
1490 for (i = 0; i < noRaRsps; i++)
1492 sf->raRsp[i].pdcch = NULLP;
1493 cmLListInit(&(sf->raRsp[i].raRspLst));
1495 /* LTE_ADV_FLAG_REMOVED_START */
1496 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
1498 rgSCHSFRUtlTotalPoolReset(cell, sf);
1500 /* LTE_ADV_FLAG_REMOVED_END */
1502 cmLListInit(&sf->n1PucchResLst);
1506 sf->isCceFailure = FALSE;
1507 sf->dlUlBothCmplt = 0;
1513 * @brief This function computes log N (32 bit Unsigned) to the base 2
1517 * Function: rgSCHUtlLog32bitNbase2
1518 * Purpose: This function computes log N (32 bit Unsigned) to the base 2.
1519 * For n= 0,1 ret = 0.
1521 * Invoked by: Scheduler
1528 PUBLIC U8 rgSCHUtlLog32bitNbase2
1533 PUBLIC U8 rgSCHUtlLog32bitNbase2(n)
1537 U32 b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
1538 U32 s[] = {1, 2, 4, 8, 16};
1542 TRC2(rgSCHUtlLog32bitNbase2)
1544 for (i=4; i >= 0; i--)
1558 * @brief This function is a wrapper to call scheduler specific API.
1562 * Function: rgSCHUtlDlRelPdcchFbk
1563 * Purpose: Calls scheduler's handler for SPS release PDCCH feedback
1568 * @param[in] RgSchCellCb *cell
1569 * @param[in] RgSchUeCb *ue
1570 * @param[in] U8 isAck
1575 PUBLIC Void rgSCHUtlDlRelPdcchFbk
1582 PUBLIC Void rgSCHUtlDlRelPdcchFbk(cell, ue, isAck)
1588 TRC2(rgSCHUtlDlRelPdcchFbk);
1589 cell->sc.apis->rgSCHDlRelPdcchFbk(cell, ue, isAck);
1596 * @brief This function is a wrapper to call scheduler specific API.
1600 * Function: rgSCHUtlDlProcAck
1601 * Purpose: Calls scheduler's handler to process Ack
1606 * @param[in] RgSchCellCb *cell
1607 * @param[in] RgSchDlHqProcCb *hqP
1612 PUBLIC Void rgSCHUtlDlProcAck
1615 RgSchDlHqProcCb *hqP
1618 PUBLIC Void rgSCHUtlDlProcAck(cell, hqP)
1620 RgSchDlHqProcCb *hqP;
1623 TRC2(rgSCHUtlDlProcAck);
1624 cell->sc.apis->rgSCHDlProcAck(cell, hqP);
1629 * @brief CRNTI CE Handler
1633 * Function : rgSCHUtlHdlCrntiCE
1635 * - Call scheduler common API
1638 * @param[in] RgSchCellCb *cell
1639 * @param[in] RgSchUeCb *ue
1640 * @param[out] RgSchErrInfo *err
1644 PUBLIC Void rgSCHUtlHdlCrntiCE
1650 PUBLIC Void rgSCHUtlHdlCrntiCE(cell, ue)
1655 TRC2(rgSCHUtlHdlCrntiCE);
1657 cell->sc.apis->rgSCHHdlCrntiCE(cell, ue);
1659 } /* rgSCHUtlHdlCrntiCE */
1660 #endif /* LTEMAC_SPS */
1662 /***********************************************************
1664 * Func : rgSCHUtlCalcTotalRegs
1666 * Desc : Calculate total REGs, given a bandwidth, CFI
1667 * and number of antennas.
1669 * Ret : Total REGs (U16)
1671 * Notes: Could optimise if bw values are limited
1672 * (taken from RRC spec) by indexing values from
1674 * Input values are not validated. CFI is assumed
1679 **********************************************************/
1681 PRIVATE U16 rgSCHUtlCalcTotalRegs
1689 PRIVATE U16 rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp)
1697 TRC2(rgSCHUtlCalcTotalRegs);
1699 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1705 /* Refer 36.211 section 6.10.1.2
1706 * For symbols 2 and 4, the REGs per RB will be based on cyclic prefix
1707 * and number of antenna ports.
1708 * For symbol 1, there are 2 REGs per RB always. Similarly symbol 3
1712 /*CR changes [ccpu00124416] - MOD*/
1715 regs = bw * RGSCH_NUM_REGS_4TH_SYM_EXT_CP;
1719 regs = bw * RGSCH_NUM_REGS_4TH_SYM_NOR_CP;
1722 regs += bw * RGSCH_NUM_REGS_3RD_SYM;
1724 /*CR changes [ccpu00124416] - MOD using number of antenna ports*/
1725 regs += (numAntna == RGSCH_NUM_ANT_PORT_FOUR) ? \
1726 (bw * RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT) : \
1727 (bw * RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT);
1728 default: /* case 1 */
1729 regs += bw * RGSCH_NUM_REGS_1ST_SYM;
1734 /***********************************************************
1736 * Func : rgSCHUtlCalcPhichRegs
1738 * Desc : Calculates number of PHICH REGs
1740 * Ret : Number of PHICH REGs (U8)
1742 * Notes: ng6 is Ng multiplied by 6
1746 **********************************************************/
1748 PRIVATE U16 rgSCHUtlCalcPhichRegs
1754 PRIVATE U16 rgSCHUtlCalcPhichRegs(bw, ng6)
1759 TRC2(rgSCHUtlCalcPhichRegs);
1760 /* ccpu00115330: Corrected the calculation for number of PHICH groups*/
1761 RETVALUE(RGSCH_CEIL((bw * ng6) ,(8 * 6)) * RGSCH_NUM_REG_PER_PHICH_GRP);
1766 * @brief Calculates total CCEs (N_cce)
1770 * Function: rgSCHUtlCalcNCce
1771 * Purpose: This function calculates and returns total CCEs for a
1772 * cell, given the following: bandwidth, Ng configuration
1773 * (multiplied by six), cfi (actual number of control
1774 * symbols), m factor for PHICH and number of antennas.
1776 * Invoked by: Scheduler
1781 * @param[in] U8 mPhich
1782 * @param[in] U8 numAntna
1783 * @param[in] Bool isEcp
1784 * @return N_cce (U8)
1788 PUBLIC U8 rgSCHUtlCalcNCce
1798 PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, mPhich, numAntna, isEcp)
1811 TRC2(rgSCHUtlCalcNCce);
1813 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1817 case RGR_NG_ONESIXTH:
1832 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1833 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1834 cceRegs = totalRegs - mPhich*phichRegs - RGSCH_NUM_PCFICH_REG;
1836 RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1841 * @brief Calculates total CCEs (N_cce)
1845 * Function: rgSCHUtlCalcNCce
1846 * Purpose: This function calculates and returns total CCEs for a
1847 * cell, given the following: bandwidth, Ng configuration
1848 * (multiplied by six), cfi (actual number of control
1849 * symbols) and number of antennas.
1851 * Invoked by: Scheduler
1856 * @param[in] U8 numAntna
1857 * @return N_cce (U8)
1861 PUBLIC U8 rgSCHUtlCalcNCce
1870 PUBLIC U8 rgSCHUtlCalcNCce(bw, ng, cfi, numAntna, isEcp)
1882 TRC2(rgSCHUtlCalcNCce);
1884 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1888 case RGR_NG_ONESIXTH:
1903 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1904 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1905 cceRegs = totalRegs - phichRegs - RGSCH_NUM_PCFICH_REG;
1907 RETVALUE((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1912 * @brief Returns PHICH info associated with an uplink
1913 * HARQ process allocation
1917 * Function: rgSCHUtlGetPhichInfo
1918 * Purpose: This function returns PHICH info associated with
1919 * an uplink HARQ process allocation. PHICH info
1920 * comprises RB start and N_dmrs.
1922 * @param[in] RgSchUlHqProcCb *hqProc
1923 * @param[out] U8 *rbStartRef
1924 * @param[out] U8 *nDmrsRef
1929 PUBLIC S16 rgSCHUtlGetPhichInfo
1931 RgSchUlHqProcCb *hqProc,
1937 PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef, iPhich)
1938 RgSchUlHqProcCb *hqProc;
1945 PUBLIC S16 rgSCHUtlGetPhichInfo
1947 RgSchUlHqProcCb *hqProc,
1952 PUBLIC S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef)
1953 RgSchUlHqProcCb *hqProc;
1962 TRC2(rgSCHUtlGetPhichInfo);
1964 if ((hqProc != NULLP) && (hqProc->alloc != NULLP))
1966 *rbStartRef = hqProc->alloc->grnt.rbStart;
1967 *nDmrsRef = hqProc->alloc->grnt.nDmrs;
1969 *iPhich = hqProc->iPhich;
1977 * @brief Returns uplink grant information required to permit
1978 * PHY to receive data
1982 * Function: rgSCHUtlAllocRcptInfo
1983 * Purpose: Given an uplink allocation, this function returns
1984 * uplink grant information which is needed by PHY to
1985 * decode data sent from UE. This information includes:
1990 * @param[in] RgSchUlAlloc *alloc
1991 * @param[out] U8 *rbStartRef
1992 * @param[out] U8 *numRbRef
1993 * @param[out] U8 *rvRef
1994 * @param[out] U16 *size
1995 * @param[out] TfuModScheme *modType
1996 * @param[out] Bool *isRtx
1997 * @param[out] U8 *nDmrs
1998 * @param[out] Bool *ndi
1999 * @param[out] U8 *hqPId
2003 PUBLIC S16 rgSCHUtlAllocRcptInfo
2005 RgSchUlAlloc *alloc,
2012 TfuModScheme *modType,
2019 PUBLIC S16 rgSCHUtlAllocRcptInfo(alloc, rnti, iMcsRef, rbStartRef, numRbRef,
2020 rvRef, size, modType, isRtx, nDmrs, ndi,
2022 RgSchUlAlloc *alloc;
2029 TfuModScheme *modType;
2036 /* Modulation order for 16qam UEs would be
2037 * min(4,modulation order in grant). Please refer to 36.213-8.6.1*/
2038 CmLteUeCategory ueCtgy;
2040 TRC2(rgSCHUtlAllocRcptInfo);
2041 #if (ERRCLASS & ERRCLS_DEBUG)
2042 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2048 if ( !alloc->forMsg3 )
2050 if ( ((alloc->ue) == NULLP) || (RG_SCH_CMN_GET_UE(alloc->ue, alloc->ue->cell) == NULLP))
2052 RLOG_ARG2(L_ERROR,DBG_CELLID,alloc->ue->cell->cellId,
2053 "Failed: ue->sch is null RNTI:%d,isRetx=%d",
2054 alloc->rnti, alloc->grnt.isRtx);
2057 ueCtgy = (RG_SCH_CMN_GET_UE_CTGY(alloc->ue));
2060 *iMcsRef = alloc->grnt.iMcs;
2061 *rbStartRef = alloc->grnt.rbStart;
2062 *numRbRef = alloc->grnt.numRb;
2063 *rvRef = rgRvTable[alloc->hqProc->rvIdx];
2064 *rnti = alloc->rnti;
2065 *size = alloc->grnt.datSz;
2066 *modType = (alloc->forMsg3)? alloc->grnt.modOdr:
2067 ((ueCtgy == CM_LTE_UE_CAT_5)?
2069 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)));
2070 *isRtx = alloc->grnt.isRtx;
2071 *nDmrs = alloc->grnt.nDmrs;
2072 *ndi = alloc->hqProc->ndi;
2073 *hqPId = alloc->hqProc->procId;
2079 * @brief Returns uplink grant information required to permit
2080 * PHY to receive data
2084 * Function: rgSCHUtlAllocRcptInfo
2085 * Purpose: Given an uplink allocation, this function returns
2086 * uplink grant information which is needed by PHY to
2087 * decode data sent from UE. This information includes:
2092 * @param[in] RgSchUlAlloc *alloc
2093 * @param[out] U8 *rbStartRef
2094 * @param[out] U8 *numRbRef
2095 * @param[out] U8 *rvRef
2096 * @param[out] U16 *size
2097 * @param[out] TfuModScheme *modType
2101 PUBLIC S16 rgSCHUtlAllocRcptInfo
2104 RgSchUlAlloc *alloc,
2105 CmLteTimingInfo *timeInfo,
2106 TfuUeUlSchRecpInfo *recpReq
2109 PUBLIC S16 rgSCHUtlAllocRcptInfo(cell, alloc, timeInfo, recpReq)
2111 RgSchUlAlloc *alloc;
2112 CmLteTimingInfo *timeInfo;
2113 TfuUeUlSchRecpInfo *recpReq;
2116 TRC2(rgSCHUtlAllocRcptInfo);
2117 #if (ERRCLASS & ERRCLS_DEBUG)
2118 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2123 recpReq->size = alloc->grnt.datSz;
2124 recpReq->rbStart = alloc->grnt.rbStart;
2125 recpReq->numRb = alloc->grnt.numRb;
2126 /* Modulation order min(4,mod in grant) for 16 qam UEs.
2127 * Please refer to 36.213-8.6.1*/
2128 #ifdef FOUR_TX_ANTENNA
2129 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2130 (/*(alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2131 alloc->grnt.modOdr: *//* Chandra:TmpFx-TM500 Cat5 with Only16QAM */
2132 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2134 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2135 ((alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2137 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2139 recpReq->nDmrs = alloc->grnt.nDmrs;
2140 recpReq->hoppingEnbld = FALSE;
2141 recpReq->hoppingBits = 0;
2142 recpReq->isRtx = alloc->grnt.isRtx;
2143 recpReq->ndi = alloc->hqProc->ndi;
2144 recpReq->rv = rgRvTable[alloc->hqProc->rvIdx];
2146 recpReq->harqProcId = alloc->hqProc->procId;
2148 recpReq->harqProcId = rgSCHCmnGetUlHqProcIdx(timeInfo, cell);
2150 /* Transmission mode is SISO till Uplink MIMO is implemented. */
2151 recpReq->txMode = 0;
2152 /* This value needs to filled in in the case of frequency hopping. */
2153 recpReq->crntTxNb = 0;
2155 recpReq->mcs = alloc->grnt.iMcs;
2157 recpReq->rbgStart = alloc->grnt.vrbgStart;
2158 recpReq->numRbg = alloc->grnt.numVrbg;
2159 recpReq->xPUSCHRange = alloc->grnt.xPUSCHRange;
2160 //TODO_SID Need to check
2161 recpReq->nAntPortLayer = 0;
2162 recpReq->SCID = alloc->grnt.SCID;
2163 recpReq->PMI = alloc->grnt.PMI;
2164 recpReq->uciWoTBFlag = alloc->grnt.uciOnxPUSCH;
2167 recpReq->beamIndex = alloc->ue->ue5gtfCb.BeamId;
2172 if (!alloc->forMsg3)
2174 if (alloc->grnt.isRtx)
2176 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulRetxOccns++;
2180 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulTxOccns++;
2181 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulSumiTbs += \
2182 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2183 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulNumiTbs ++;
2184 cell->tenbStats->sch.ulSumiTbs += \
2185 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2186 cell->tenbStats->sch.ulNumiTbs ++;
2188 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulPrbUsg += alloc->grnt.numRb;
2189 cell->tenbStats->sch.ulPrbUsage[0] += alloc->grnt.numRb;
2192 /* ccpu00117050 - DEL - nSrs setting at rgSCHUtlAllocRcptInfo */
2199 * @brief This function initialises the PRACH slot occasions
2203 * Function: rgSCHUtlUpdPrachOcc
2204 * Purpose: This function updates the PRACH slots based on
2205 * RGR configuration.
2207 * Invoked by: Scheduler
2209 * @param[in] RgSchCellCb *cell
2210 * @param[in] RgrTddPrachInfo *cellCfg
2215 PRIVATE Void rgSCHUtlUpdPrachOcc
2218 RgrTddPrachInfo *cellCfg
2221 PRIVATE Void rgSCHUtlUpdPrachOcc(cell, cellCfg)
2223 RgrTddPrachInfo *cellCfg;
2232 TRC2(rgSCHUtlUpdPrachOcc)
2234 /* In the 1st half frame */
2235 if(cellCfg->halfFrm == 0)
2240 /* In the 2nd half frame */
2246 for(idx = startIdx; idx < endIdx; idx++)
2248 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
2249 == RG_SCH_TDD_UL_slot)
2251 if(cellCfg->ulStartSfIdx == count)
2253 size = cell->rachCfg.raOccasion.size;
2254 cell->rachCfg.raOccasion.slotNum[size] = idx;
2255 cell->rachCfg.raOccasion.size++;
2265 * @brief This function initialises the PRACH occasions
2269 * Function: rgSCHUtlPrachCfgInit
2270 * Purpose: This function initialises the PRACH occasions based on
2271 * RGR configuration.
2273 * Invoked by: Scheduler
2275 * @param[in] RgSchCellCb *cell
2276 * @param[in] RgrCellCfg *cellCfg
2281 PUBLIC Void rgSCHUtlPrachCfgInit
2287 PUBLIC Void rgSCHUtlPrachCfgInit(cell, cellCfg)
2289 RgrCellCfg *cellCfg;
2296 TRC2(rgSCHUtlPrachCfgInit)
2297 if(cellCfg->prachRscInfo.numRsc <= 0)
2299 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid"
2300 "PRACH resources Configuration ");
2304 /* Update SFN occasions */
2305 cell->rachCfg.raOccasion.sfnEnum =
2306 cellCfg->prachRscInfo.prachInfo[0].sfn;
2308 cell->rachCfg.raOccasion.size = 0;
2310 /* Update slot occasions */
2311 for(idx = 0; idx < cellCfg->prachRscInfo.numRsc; idx++)
2313 if(cellCfg->prachRscInfo.prachInfo[idx].freqIdx == 0)
2315 if(cellCfg->prachRscInfo.prachInfo[idx].halfFrm == 0)
2323 if(cellCfg->prachRscInfo.prachInfo[idx].ulStartSfIdx ==
2326 subfrmIdx = cell->rachCfg.raOccasion.size;
2327 cell->rachCfg.raOccasion.slotNum[subfrmIdx] = splFrm;
2328 cell->rachCfg.raOccasion.size++;
2332 rgSCHUtlUpdPrachOcc(cell,
2333 &cellCfg->prachRscInfo.prachInfo[idx]);
2341 * @brief This function performs RGR cell initialization
2345 * Function: rgSCHUtlRgrCellCfg
2346 * Purpose: This function initialises the cell with RGR configuration
2347 * and slot related initialization.
2349 * Invoked by: Scheduler
2351 * @param[in] RgSchCellCb *cell
2352 * @param[in] RgrCellCfg *cellCfg
2353 * @param[in] RgSchErrInfo *errInfo
2358 PUBLIC S16 rgSCHUtlRgrCellCfg
2361 RgrCellCfg *cellCfg,
2362 RgSchErrInfo *errInfo
2365 PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2367 RgrCellCfg *cellCfg;
2368 RgSchErrInfo *errInfo;
2375 CmLteTimingInfo frm;
2376 U8 ulDlCfgIdx = cellCfg->ulDlCfgIdx;
2380 U16 bw; /*!< Number of RBs in the cell */
2382 TRC2(rgSCHUtlRgrCellCfg);
2384 cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo));
2386 /* ccpu00132657-MOD- Determining DLSF array size independent of DELTAS */
2387 maxDlslots = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
2388 maxslots = 2 * maxDlslots;
2389 cell->numDlSubfrms = maxslots;
2390 /* ACC-TDD <ccpu00130639> */
2391 cell->tddHqSfnCycle = -1;
2392 cell->ulDlCfgIdx = ulDlCfgIdx;
2394 /* PRACH Occasions Initialization */
2395 rgSCHUtlPrachCfgInit(cell, cellCfg);
2397 /* ccpu00132658- Moved out of below for loop since the updating rbgSize and
2398 * bw are independent of sfNum*/
2399 /* determine the RBG size and no of RBGs for the configured
2401 if (cell->bwCfg.dlTotalBw > 63)
2405 else if (cell->bwCfg.dlTotalBw > 26)
2409 else if (cell->bwCfg.dlTotalBw > 10)
2417 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2419 bw = cell->bwCfg.dlTotalBw;
2421 rgSCHUtlAllocSBuf(cell->instIdx,
2422 (Data **)&cell->subFrms, sizeof(RgSchDlSf *) * maxslots);
2423 if (cell->subFrms == NULLP)
2428 /* Create memory for each frame. */
2429 for(i = 0; i < maxslots; i++)
2431 while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
2434 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2437 rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf, sizeof(RgSchDlSf));
2442 cmMemset((U8 *)sf, 0, sizeof(*sf));
2445 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2453 /* Mark SPS bandwidth to be occupied */
2454 sf->bwAlloced = ((cellCfg->spsCfg.maxSpsDlBw +
2455 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
2456 sf->spsAllocdBw = 0;
2457 sf->type2End = sf->bwAlloced/cell->rbgSize;
2460 /* Fix for ccpu00123918*/
2462 #endif /* LTEMAC_SPS */
2463 /* Initialize the ackNakRepQ here */
2464 #ifdef RG_MAC_MEASGAP
2465 cmLListInit (&(sf->ackNakRepQ));
2467 cell->subFrms[i] = sf;
2468 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2474 /* ccpu00117052 - MOD - Passing double pointer
2475 for proper NULLP assignment*/
2476 rgSCHUtlFreeSBuf(cell->instIdx,
2477 (Data **)(&(cell->subFrms[i-1])), sizeof(RgSchDlSf));
2479 rgSCHLaaDeInitDlSfCb(cell, sf);
2482 /* ccpu00117052 - MOD - Passing double pointer
2483 for proper NULLP assignment*/
2484 rgSCHUtlFreeSBuf(cell->instIdx,
2485 (Data **)(&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2490 if (cell->sc.apis == NULLP)
2492 cell->sc.apis = &rgSchCmnApis;
2494 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2498 /* ccpu00132286- Removed deletion of sf nodes as the deletion will be
2499 * happening during CellDelete. Added return handling to provide negative
2504 /* Release the slots and thereby perform the initialization */
2505 for (i = 0; i < maxslots; i++)
2507 if((i > 0) && (i%maxDlslots == 0))
2512 frm.slot = cell->subFrms[i]->sfNum;
2513 rgSCHUtlDlRlsSubFrm(cell, frm);
2522 * @brief This function performs scheduler related cell creation
2526 * Function: rgSCHUtlRgrCellCfg
2527 * Purpose: This function creates the slots needed for the
2528 * cell. It then peforms init of the scheduler by calling
2529 * scheduler specific cell init function.
2531 * Invoked by: Scheduler
2533 * @param[in] RgSchCellCb *cell
2534 * @param[in] RgrCellCfg *cellCfg
2535 * @param[in] RgSchErrInfo *errInfo
2540 PUBLIC S16 rgSCHUtlRgrCellCfg
2543 RgrCellCfg *cellCfg,
2544 RgSchErrInfo *errInfo
2547 PUBLIC S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2549 RgrCellCfg *cellCfg;
2550 RgSchErrInfo *errInfo;
2555 CmLteTimingInfo frm;
2557 Inst inst = cell->instIdx;
2558 /* LTE_ADV_FLAG_REMOVED_START */
2560 len = (U16)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /*KW fix for LTE_ADV */
2561 /* LTE_ADV_FLAG_REMOVED_END */
2562 TRC2(rgSCHUtlRgrCellCfg);
2564 cmMemset((U8 *)&frm,0,sizeof(CmLteTimingInfo));
2566 /* determine the RBG size and no of RBGs for the configured
2568 if (cell->bwCfg.dlTotalBw > 63)
2572 else if (cell->bwCfg.dlTotalBw > 26)
2576 else if (cell->bwCfg.dlTotalBw > 10)
2584 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2585 /* Create memory for each frame. */
2586 /* Changing loop limit from
2587 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2588 for(i = 0; i < RGSCH_NUM_DL_slotS; i++)
2590 rgSCHUtlAllocSBuf(inst, (Data **)&sf, sizeof(RgSchDlSf));
2595 cmMemset((U8 *)sf, 0, sizeof(*sf));
2598 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2603 /* Doing MOD operation before assigning value of i */
2604 sf->sfNum = i % RGSCH_NUM_SUB_FRAMES;
2605 sf->bw = cell->bwCfg.dlTotalBw;
2606 /* Initialize the ackNakRepQ here */
2607 #ifdef RG_MAC_MEASGAP
2608 cmLListInit (&(sf->ackNakRepQ));
2610 cell->subFrms[i] = sf;
2611 /* LTE_ADV_FLAG_REMOVED_START */
2612 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2614 /*initialize the RNTP Buffer*/
2615 if(rgSchDSFRRntpInfoInit(&sf->rntpInfo, cell, sf->bw))
2621 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
2623 /*initialise the pools of CC and CE*/
2624 if(rgSchSFRTotalPoolInit(cell, sf))
2629 /* LTE_ADV_FLAG_REMOVED_END */
2632 /* LTE_ADV_FLAG_REMOVED_START */
2633 /* Allocate memory for "scheduled UE" Info */
2634 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2636 if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val),
2637 (len * sizeof(U8)))) != ROK)
2639 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
2642 cell->rntpAggrInfo.pres = PRSNT_NODEF;
2643 cell->rntpAggrInfo.len = len;
2645 /* LTE_ADV_FLAG_REMOVED_END */
2647 /* Changing loop limit from
2648 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2649 if (i != RGSCH_NUM_DL_slotS)
2653 /* ccpu00117052 - MOD - Passing double pointer
2654 for proper NULLP assignment*/
2655 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i-1])),
2658 rgSCHLaaDeInitDlSfCb(cell, sf);
2664 if (cell->sc.apis == NULLP)
2666 cell->sc.apis = &rgSchCmnApis;
2669 /* Release the slots and thereby perform the initialization */
2670 for (i = 0; i < RGSCH_NUM_DL_slotS; i++)
2672 if (i >= RGSCH_NUM_SUB_FRAMES)
2674 /* [ccpu00123828]-MOD-The below statement sfn += 1incorrectly modified
2675 * the value of sfn for i>=10 thru 19. Correct way is to assign
2679 frm.slot = i % RGSCH_NUM_SUB_FRAMES;
2680 rgSCHUtlDlRlsSubFrm(cell, frm);
2683 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2686 errInfo->errCause = RGSCHERR_SCH_CFG;
2690 if(cell->emtcEnable)
2692 /* TODO: Repetition framework in RGR and APP */
2693 if (rgSCHUtlEmtcResMngmtInit(
2695 RGSCH_IOT_PDSCH_POOLSZ, RGSCH_IOT_PDSCH_DELTA, cellCfg->bwCfg.dlTotalBw,
2696 RGSCH_IOT_PUSCH_POOLSZ, RGSCH_IOT_PUSCH_DELTA, RGSCH_IOT_PUSCH_MAXFREQSZ,
2697 RGSCH_IOT_PUCCH_POOLSZ, RGSCH_IOT_PUCCH_DELTA, RGSCH_IOT_PUCCH_MAXFREQSZ) != ROK)
2699 errInfo->errCause = RGSCHERR_SCH_CFG;
2711 * @brief This function performs the cell reconfiguration at RGR interface
2715 * Function: rgSCHUtlRgrCellRecfg
2716 * Purpose: This function updates the reconfigurable parameters
2717 * on the cell control block for the scheduler.
2719 * Invoked by: Scheduler
2721 * @param[in] RgSchCellCb *cell
2722 * @param[in] RgrCellCfg *cellCfg
2723 * @param[in] RgSchErrInfo *errInfo
2728 PUBLIC S16 rgSCHUtlRgrCellRecfg
2731 RgrCellRecfg *recfg,
2735 PUBLIC S16 rgSCHUtlRgrCellRecfg(cell, recfg, err)
2737 RgrCellRecfg *recfg;
2741 TRC2(rgSCHUtlRgrCellRecfg);
2742 RETVALUE(cell->sc.apis->rgSCHRgrCellRecfg(cell, recfg, err));
2748 * @brief This function returns the Y value of UE for a sub frame
2752 * Function: rgSCHUtlFreeCell
2753 * Purpose: This function updates the value of Y stored in the
2754 * UE control block. It uses the previously computed
2755 * value for computing for this slot.
2757 * Invoked by: Scheduler
2759 * @param[in] RgSchCellCb *cell
2764 PUBLIC S16 rgSCHUtlFreeCell
2769 PUBLIC S16 rgSCHUtlFreeCell(cell)
2776 RgSchPdcchInfo *pdcchInfo;
2777 RgSchPhichInfo *phichInfo;
2779 Inst inst = cell->instIdx;
2782 RgSchRaReqInfo *raReqInfo;
2785 TRC2(rgSCHUtlFreeCell);
2788 maxslots = cell->numDlSubfrms;
2790 maxslots = RGSCH_NUM_DL_slotS;
2794 /* Invoke the index for scheduler, cell deletion */
2795 cell->sc.apis->rgSCHFreeCell(cell);
2797 /* Release the slots allocated */
2798 for (i = 0; i < maxslots; i++)
2801 rgSCHLaaDeInitDlSfCb(cell, cell->subFrms[i]);
2803 pdcchInfo = &cell->subFrms[i]->pdcchInfo;
2804 /* ccpu00117052 - MOD - Passing double pointer
2805 for proper NULLP assignment*/
2806 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)),
2807 (pdcchInfo->nCce + 7) >> 3);
2808 while (pdcchInfo->pdcchs.first != NULLP)
2810 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
2811 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
2812 /* ccpu00117052 - MOD - Passing double pointer
2813 for proper NULLP assignment*/
2814 rgSCHUtlFreeSBuf(inst, (Data **)&pdcch, sizeof(RgSchPdcch));
2817 phichInfo = &cell->subFrms[i]->phichInfo;
2818 while(phichInfo->phichs.first != NULLP)
2820 phich = (RgSchPhich *)phichInfo->phichs.first->node;
2821 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
2822 RGSCH_PHICH_FREE(inst, phich, sizeof(RgSchPhich));
2825 /* LTE_ADV_FLAG_REMOVED_START */
2826 /*releasing SFR pool entries*/
2827 rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell);
2829 /*releasing dsfr rntp pattern info*/
2830 rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell,
2831 cell->bwCfg.dlTotalBw);
2832 /* LTE_ADV_FLAG_REMOVED_END */
2834 /* ccpu00117052 - MOD - Passing double pointer
2835 for proper NULLP assignment*/
2836 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i])), sizeof(RgSchDlSf));
2839 /* Release the slot pointers */
2840 /* ccpu00117052 - MOD - Passing double pointer
2841 for proper NULLP assignment*/
2842 rgSCHUtlFreeSBuf(inst,
2843 (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2845 for(idx=0; idx < cell->raInfo.lstSize; idx++)
2847 lst = &cell->raInfo.raReqLst[idx];
2848 while (lst->first != NULLP)
2850 raReqInfo = (RgSchRaReqInfo *)lst->first->node;
2851 cmLListDelFrm(lst, &raReqInfo->raReqLstEnt);
2852 /* ccpu00117052 - MOD - Passing double pointer
2853 for proper NULLP assignment*/
2854 rgSCHUtlFreeSBuf(inst,(Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
2857 /* ccpu00117052 - MOD - Passing double pointer
2858 for proper NULLP assignment*/
2859 rgSCHUtlFreeSBuf(inst,
2860 (Data **)(&(cell->raInfo.raReqLst)),
2861 sizeof(CmLListCp) * (cell->raInfo.lstSize));
2864 /* Release allocated pdcchs */
2865 lst = &cell->pdcchLst;
2866 while (lst->first != NULLP)
2868 pdcch = (RgSchPdcch *)lst->first->node;
2869 cmLListDelFrm(lst, &pdcch->lnk);
2871 if(cell->emtcEnable)
2873 rgSCHEmtcPdcchFree(cell, pdcch);
2874 rgSCHUtlEmtcResMngmtDeinit(cell);
2877 /* ccpu00117052 - MOD - Passing double pointer
2878 for proper NULLP assignment*/
2879 rgSCHUtlFreeSBuf(inst,(Data **)&pdcch, sizeof(RgSchPdcch));
2882 rgSCHLaaFreeLists(cell);
2885 /* LTE_ADV_FLAG_REMOVED_START */
2886 /* releasing RNTP Aggregation Info from CellCb*/
2887 rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw);
2888 /* LTE_ADV_FLAG_REMOVED_END */
2895 * @brief This function adds the UE to scheduler
2899 * Function: rgSCHUtlRgrUeCfg
2900 * Purpose: This function performs addition of UE to scheduler
2901 * 1. First, it updates the Y table in the UE
2902 * 2. Then, it calls the scheduler's handler for UE addition
2904 * Invoked by: Scheduler
2906 * @param[in] RgSchCellCb *cell
2907 * @param[in] RgSchUeCb *ue
2908 * @param[in] RgrUeCfg *cfg
2909 * @param[in] RgSchErrInfo *err
2914 PUBLIC S16 rgSCHUtlRgrUeCfg
2922 PUBLIC S16 rgSCHUtlRgrUeCfg(cell, ue, cfg, err)
2929 TRC2(rgSCHUtlRgrUeCfg);
2931 /* Assign TM 1 as UE's default TM */
2932 ue->mimoInfo.txMode = RGR_UE_TM_1;
2933 ue->txModeTransCmplt = TRUE;
2934 cmInitTimers(&ue->txModeTransTmr, 1);
2935 if (cfg->txMode.pres == PRSNT_NODEF)
2937 /* DL MU-MIMO not supported */
2938 if (cfg->txMode.txModeEnum == RGR_UE_TM_5)
2940 err->errCause = RGSCHERR_SCH_CFG;
2943 ue->mimoInfo.txMode = cfg->txMode.txModeEnum;
2945 ue->ul.ulTxAntSel = cfg->ulTxAntSel;
2946 ue->mimoInfo.cdbkSbstRstrctn = cfg->ueCodeBookRstCfg;
2948 ue->ueCatEnum = cfg->ueCatEnum;
2949 if ((cfg->puschDedCfg.bACKIdx > 15) ||
2950 (cfg->puschDedCfg.bCQIIdx > 15) ||
2951 (cfg->puschDedCfg.bRIIdx > 15))
2953 err->errCause = RGSCHERR_SCH_CFG;
2956 ue->ul.betaHqOffst = cfg->puschDedCfg.bACKIdx;
2957 ue->ul.betaCqiOffst = cfg->puschDedCfg.bCQIIdx;
2958 ue->ul.betaRiOffst = cfg->puschDedCfg.bRIIdx;
2960 ue->csgMmbrSta = cfg->csgMmbrSta;
2962 cmMemset((U8 *)&ue->pfsStats, 0, sizeof(RgSchPfsStats));
2964 /* Call the handler of the scheduler based on cell configuration */
2965 RETVALUE(cell->sc.apis->rgSCHRgrUeCfg(cell, ue, cfg, err));
2967 /* Start : LTEMAC_2.1_DEV_CFG */
2970 * @brief This function adds a service to scheduler
2974 * Function: rgSCHUtlRgrLcCfg
2975 * Purpose: This function performs addition of service to scheduler
2976 * The addition is performed for each direction based
2977 * the direction field of the configuration
2979 * Invoked by: Scheduler
2981 * @param[in] RgSchCellCb *cell
2982 * @param[in] RgSchUeCb *ue
2983 * @param[in] RgSchDlLcCb *dlLc
2984 * @param[in] RgrLchCfg *cfg
2985 * @param[in] RgSchErrInfo *err
2990 PUBLIC S16 rgSCHUtlRgrLcCfg
2996 RgSchErrInfo *errInfo
2999 PUBLIC S16 rgSCHUtlRgrLcCfg(cell, ue, dlLc, cfg, errInfo)
3004 RgSchErrInfo *errInfo;
3007 TRC2(rgSCHUtlRgrLcCfg);
3008 RETVALUE(cell->sc.apis->rgSCHRgrLchCfg(cell, ue, dlLc, cfg, errInfo));
3013 * @brief This function modifies a service to scheduler
3017 * Function: rgSCHUtlRgrLcRecfg
3018 * Purpose: This function performs modification of a service in
3019 * scheduler. The modification is performed for each direction
3020 * based the direction field of the configuration
3022 * Invoked by: Scheduler
3024 * @param[in] RgSchCellCb *cell
3025 * @param[in] RgSchUeCb *ue
3026 * @param[in] RgSchDlLcCb *dlLc
3027 * @param[in] RgrLchRecfg *recfg
3028 * @param[in] RgSchErrInfo *err
3033 PUBLIC S16 rgSCHUtlRgrLcRecfg
3042 PUBLIC S16 rgSCHUtlRgrLcRecfg(cell, ue, dlLc, recfg, err)
3050 TRC2(rgSCHUtlRgrLcRecfg);
3051 RETVALUE(cell->sc.apis->rgSCHRgrLchRecfg(cell, ue, dlLc, recfg, err));
3055 * @brief This function deletes a Lc in scheduler
3059 * Function: rgSCHUtlRgrLcDel
3060 * Purpose: This function performs deletion of Lc in scheduler
3062 * Invoked by: Scheduler
3064 * @param[in] RgSchCellCb *cell
3065 * @param[in] RgSchUeCb *ue
3066 * @param[in] CmLteLcId lcId
3067 * @param[in] U8 lcgId
3072 PUBLIC S16 rgSCHUtlRgrLcDel
3080 PUBLIC S16 rgSCHUtlRgrLcDel(cell, ue, lcId, lcgId)
3087 TRC2(rgSCHUtlRgrLcDel);
3088 cell->sc.apis->rgSCHRgrLchDel(cell, ue, lcId, lcgId);
3091 } /* rgSCHUtlRgrLcDel */
3094 * @brief This function adds a service to scheduler
3098 * Function: rgSCHUtlRgrLcgCfg
3099 * Purpose: This function performs addition of service to scheduler
3100 * The addition is performed for each direction based
3101 * the direction field of the configuration
3103 * Invoked by: Scheduler
3105 * @param[in] RgSchCellCb *cell
3106 * @param[in] RgSchUeCb *ue
3107 * @param[in] RgrLchCfg *cfg
3108 * @param[in] RgSchErrInfo *err
3113 PUBLIC S16 rgSCHUtlRgrLcgCfg
3118 RgSchErrInfo *errInfo
3121 PUBLIC S16 rgSCHUtlRgrLcgCfg(cell, ue, cfg, errInfo)
3125 RgSchErrInfo *errInfo;
3128 TRC2(rgSCHUtlRgrLcgCfg);
3129 RETVALUE(cell->sc.apis->rgSCHRgrLcgCfg(cell, ue, &(ue->ul.lcgArr[cfg->ulInfo.lcgId]), cfg, errInfo));
3134 * @brief This function modifies a service to scheduler
3138 * Function: rgSCHUtlRgrLcgRecfg
3139 * Purpose: This function performs modification of a service in
3140 * scheduler. The modification is performed for each direction
3141 * based the direction field of the configuration
3143 * Invoked by: Scheduler
3145 * @param[in] RgSchCellCb *cell
3146 * @param[in] RgSchUeCb *ue
3147 * @param[in] RgrLcgRecfg *recfg
3148 * @param[in] RgSchErrInfo *err
3153 PUBLIC S16 rgSCHUtlRgrLcgRecfg
3161 PUBLIC S16 rgSCHUtlRgrLcgRecfg(cell, ue, recfg, err)
3168 TRC2(rgSCHUtlRgrLcgRecfg);
3169 RETVALUE(cell->sc.apis->rgSCHRgrLcgRecfg(cell, ue, &(ue->ul.lcgArr[recfg->ulRecfg.lcgId]), recfg, err));
3170 } /* rgSCHUtlRgrLcRecfg */
3173 * @brief This function modifies a service to scheduler
3177 * Function: rgSCHUtlRgrLcgDel
3178 * Purpose: This function performs modification of a service in
3179 * scheduler. The modification is performed for each direction
3180 * based the direction field of the configuration
3182 * Invoked by: Scheduler
3184 * @param[in] RgSchCellCb *cell
3185 * @param[in] RgSchUeCb *ue
3186 * @param[in] RgrDel *lcDelInfo
3191 PUBLIC Void rgSCHUtlRgrLcgDel
3198 PUBLIC Void rgSCHUtlRgrLcgDel(cell, ue, lcgId)
3204 TRC2(rgSCHUtlRgrLcgDel);
3205 cell->sc.apis->rgSCHFreeLcg(cell, ue, &ue->ul.lcgArr[lcgId]);
3207 /* Stack Crash problem for TRACE5 changes. added the return below . */
3210 } /* rgSCHUtlRgrLcgDel */
3213 /* End: LTEMAC_2.1_DEV_CFG */
3216 * @brief This function is a wrapper to call scheduler specific API.
3220 * Function: rgSCHUtlDoaInd
3221 * Purpose: Updates the DOA for the UE
3225 * @param[in] RgSchCellCb *cell
3226 * @param[in] RgSchUeCb *ue
3227 * @param[in] TfuDoaRpt *doaRpt
3232 PUBLIC Void rgSCHUtlDoaInd
3239 PUBLIC Void rgSCHUtlDoaInd(cell, ue, doaRpt)
3245 TRC2(rgSCHUtlDoaInd);
3246 ue->mimoInfo.doa.pres = PRSNT_NODEF;
3247 ue->mimoInfo.doa.val = doaRpt->doa;
3252 * @brief This function is a wrapper to call scheduler specific API.
3256 * Function: rgSCHUtlDlCqiInd
3257 * Purpose: Updates the DL CQI for the UE
3261 * @param[in] RgSchCellCb *cell
3262 * @param[in] RgSchUeCb *ue
3263 * @param[in] TfuDlCqiRpt *dlCqiRpt
3264 * @param[in] CmLteTimingInfo timingInfo
3269 PUBLIC Void rgSCHUtlDlCqiInd
3273 TfuDlCqiRpt *dlCqiRpt,
3274 CmLteTimingInfo timingInfo
3277 PUBLIC Void rgSCHUtlDlCqiInd(cell, ue, dlCqiRpt, timingInfo)
3280 TfuDlCqiRpt *dlCqiRpt;
3281 CmLteTimingInfo timingInfo;
3284 RgSchCellCb *sCellCb = NULLP;
3285 TRC2(rgSCHUtlDlCqiInd);
3286 if (dlCqiRpt->isPucchInfo)
3288 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pucchCqi.cellIdx]->cell;
3289 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3290 (Void *)&dlCqiRpt->dlCqiInfo.pucchCqi, timingInfo);
3295 for (idx = 0; idx < dlCqiRpt->dlCqiInfo.pusch.numOfCells; idx++)
3297 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx].cellIdx]->cell;
3298 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3299 (Void *)&dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx], timingInfo);
3308 * @brief This function is a wrapper to call scheduler specific API.
3312 * Function: rgSCHUtlSrsInd
3313 * Purpose: Updates the UL SRS for the UE
3317 * @param[in] RgSchCellCb *cell
3318 * @param[in] RgSchUeCb *ue
3319 * @param[in] TfuSrsRpt* srsRpt
3320 * @param[in] CmLteTimingInfo timingInfo
3325 PUBLIC Void rgSCHUtlSrsInd
3330 CmLteTimingInfo timingInfo
3333 PUBLIC Void rgSCHUtlSrsInd(cell, ue, srsRpt, timingInfo)
3337 CmLteTimingInfo timingInfo;
3340 TRC2(rgSCHUtlSrsInd);
3341 cell->sc.apis->rgSCHSrsInd(cell, ue, srsRpt, timingInfo);
3347 * @brief This function is a wrapper to call scheduler specific API.
3351 * Function: rgSCHUtlDlTARpt
3352 * Purpose: Reports PHY TA for a UE.
3356 * @param[in] RgSchCellCb *cell
3357 * @param[in] RgSchUeCb *ue
3362 PUBLIC Void rgSCHUtlDlTARpt
3368 PUBLIC Void rgSCHUtlDlTARpt(cell, ue)
3373 TRC2(rgSCHUtlDlTARpt);
3374 cell->sc.apis->rgSCHDlTARpt(cell, ue);
3380 * @brief This function is a wrapper to call scheduler specific API.
3384 * Function: rgSCHUtlDlRlsSubFrm
3385 * Purpose: Releases scheduler Information from DL SubFrm.
3389 * @param[in] RgSchCellCb *cell
3390 * @param[out] CmLteTimingInfo subFrm
3395 PUBLIC Void rgSCHUtlDlRlsSubFrm
3398 CmLteTimingInfo subFrm
3401 PUBLIC Void rgSCHUtlDlRlsSubFrm(cell, subFrm)
3403 CmLteTimingInfo subFrm;
3406 TRC2(rgSCHUtlDlRlsSubFrm);
3407 cell->sc.apis->rgSCHDlRlsSubFrm(cell, subFrm);
3413 * @brief This API is invoked to update the AperCQI trigger
3418 * Function : rgSCHUtlUpdACqiTrigWt
3419 * - If HqFdbk is ACK then add up weight corresponding
3420 * to ACK to the AcqiTrigWt.
3421 * - If HqFdbk is NACK then add up weight corresponding
3422 * to NACK to the AcqiTrigWt.
3423 * - If AcqiTrigWt crosses threshold then trigger
3424 * grant req for APERCQI to SCH.
3426 * @param[in] RgSchUeCb *ue
3427 * @param[in] U8 isAck
3432 PUBLIC Void rgSCHUtlUpdACqiTrigWt
3435 RgSchUeCellInfo *cellInfo,
3439 PUBLIC Void rgSCHUtlUpdACqiTrigWt(ue,cellInfo, isAck)
3441 RgSchUeCellInfo *cellInfo;
3450 TRC2(rgSCHUtlUpdACqiTrigWt);
3452 if (isAck == TFU_HQFDB_ACK)
3454 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_ACK_WGT;
3458 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_NACK_WGT;
3461 if (cellInfo->acqiCb.aCqiTrigWt > RG_APER_CQI_THRESHOLD_WGT)
3463 RgSchCellCb *cell = ue->cell;
3464 RgSchErrInfo unUsed;
3466 if(ue->dl.reqForCqi)
3468 /* Already one ACQI trigger procedure is going on
3469 * which is not yet satisfied. Delaying this request till
3470 * the previous is getting satisfied*/
3474 ue->dl.reqForCqi = TRUE;
3476 rgSchCmnSetCqiReqField(cellInfo,ue,&ue->dl.reqForCqi);
3477 //Reset aCqiTrigWt for all the serving cells for which we have triggered ACQI
3478 rgSCHTomUtlGetTrigSet(cell, ue, ue->dl.reqForCqi, &triggerSet);
3479 for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++)
3481 /* The Aperiodic requested for SCell index sIdx */
3482 if ((triggerSet >> (7 - sIdx)) & 0x01)
3484 /* The Aperiodic request for SCell index sIdx */
3485 ue->cellInfo[sIdx]->acqiCb.aCqiTrigWt = 0;
3490 /* Force SCH to send UL grant by indicating fake SR.
3491 * If this UE already in UL SCH Qs this SR Ind will
3493 rgSCHUtlSrRcvd(cell, ue, cell->crntTime, &unUsed);
3501 * @brief This API is invoked to indicate scheduler of a CRC indication.
3505 * Function : rgSCHUtlHdlUlTransInd
3506 * This API is invoked to indicate scheduler of a CRC indication.
3508 * @param[in] RgSchCellCb *cell
3509 * @param[in] RgSchUeCb *ue
3510 * @param[in] CmLteTimingInfo timingInfo
3515 PUBLIC Void rgSCHUtlHdlUlTransInd
3519 CmLteTimingInfo timingInfo
3522 PUBLIC Void rgSCHUtlHdlUlTransInd(cell, ue, timingInfo)
3525 CmLteTimingInfo timingInfo;
3528 TRC2(rgSCHUtlHdlUlTransInd);
3529 cell->sc.apis->rgSCHHdlUlTransInd(cell, ue, timingInfo);
3534 * @brief This API is invoked to indicate scheduler of a CRC failure.
3538 * Function : rgSCHUtlHdlCrcInd
3539 * This API is invoked to indicate CRC to scheduler.
3541 * @param[in] RgSchCellCb *cell
3542 * @param[in] RgSchUeCb *ue
3543 * @param[in] CmLteTimingInfo timingInfo
3548 PUBLIC Void rgSCHUtlHdlCrcInd
3552 CmLteTimingInfo timingInfo
3555 PUBLIC Void rgSCHUtlHdlCrcInd(cell, ue, timingInfo)
3558 CmLteTimingInfo timingInfo;
3561 TRC2(rgSCHUtlHdlCrcFail);
3562 cell->sc.apis->rgSCHUlCrcInd(cell, ue, timingInfo);
3564 } /* end of rgSCHUtlHdlCrcFailInd */
3567 * @brief This API is invoked to indicate scheduler of a CRC failure.
3571 * Function : rgSCHUtlHdlCrcFailInd
3572 * This API is invoked to indicate CRC failure to scheduler.
3574 * @param[in] RgSchCellCb *cell
3575 * @param[in] RgSchUeCb *ue
3576 * @param[in] CmLteTimingInfo timingInfo
3581 PUBLIC Void rgSCHUtlHdlCrcFailInd
3585 CmLteTimingInfo timingInfo
3588 PUBLIC Void rgSCHUtlHdlCrcFailInd(cell, ue, timingInfo)
3591 CmLteTimingInfo timingInfo;
3594 TRC2(rgSCHUtlHdlCrcFail);
3595 cell->sc.apis->rgSCHUlCrcFailInd(cell, ue, timingInfo);
3597 } /* end of rgSCHUtlHdlCrcFailInd */
3598 #endif /* LTEMAC_SPS */
3602 * @brief This function is a wrapper to call scheduler specific API.
3606 * Function: rgSCHUtlDlProcAddToRetx
3607 * Purpose: This function adds a HARQ process to retransmission
3608 * queue. This may be performed when a HARQ ack is
3611 * Invoked by: HARQ feedback processing
3613 * @param[in] RgSchCellCb* cell
3614 * @param[in] RgSchDlHqProc* hqP
3619 PUBLIC Void rgSCHUtlDlProcAddToRetx
3622 RgSchDlHqProcCb *hqP
3625 PUBLIC Void rgSCHUtlDlProcAddToRetx(cell, hqP)
3627 RgSchDlHqProcCb *hqP;
3630 TRC2(rgSCHUtlDlProcAddToRetx);
3631 cell->sc.apis->rgSCHDlProcAddToRetx(cell, hqP);
3637 * @brief This function adds a HARQ process TB to transmission
3641 * Function: rgSCHUtlDlHqPTbAddToTx
3642 * Purpose: This function a HarqProcess TB to the slot
3645 * Invoked by: Scheduler
3647 * @param[in] RgSubFrm* subFrm
3648 * @param[in] RgDlHqProc* hqP
3649 * @param[in] U8 tbIdx
3654 PUBLIC Void rgSCHUtlDlHqPTbAddToTx
3657 RgSchDlHqProcCb *hqP,
3661 PUBLIC Void rgSCHUtlDlHqPTbAddToTx(subFrm, hqP, tbIdx)
3663 RgSchDlHqProcCb *hqP;
3667 RgSchUeCb *ue = NULLP;
3668 RgSchCellCb *cell = hqP->hqE->cell;
3670 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3671 /* ue->cell will always hold PCell information */
3672 if (NULLP == hqP->hqPSfLnk.node)
3677 if(NULLP == ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node)
3679 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)ue;
3680 cmLListAdd2Tail(&cell->subFrms[subFrm->dlIdx]->ueLst,
3681 &ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3683 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].isPuschHarqRecpPres = FALSE;
3687 /* Add Hq proc in particular dlIdx List for this UE
3688 This list will be used while processing feedback*/
3689 hqP->hqPSfLnk.node = (PTR)hqP;
3690 cmLListAdd2Tail(&ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3693 extern U32 gSCellSchedCount,gPrimarySchedCount;
3694 if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue,hqP->hqE->cell))
3698 gPrimarySchedCount++;
3702 else if (hqP->hqE->msg4Proc == hqP)
3704 /* Msg4 will be scheduled on PCELL only hence add directly to subFrm msg4HqpList */
3705 hqP->hqPSfLnk.node = (PTR)hqP;
3706 cmLListAdd2Tail(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3713 if((ue) && (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state))
3716 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt++;
3718 /*totalTbCnt will hold the total number of TBs across all harq Proc from all
3721 hqP->subFrm = subFrm;
3730 * @brief This function removes a HARQ process TB from transmission
3734 * Function: rgSCHUtlDlHqPTbRmvFrmTx
3735 * Purpose: This function removes a HarqProcess TB to the slot
3738 * Invoked by: Scheduler
3740 * @param[in] RgSubFrm* subFrm
3741 * @param[in] RgDlHqProc* hqP
3742 * @param[in] U8 tbIdx
3743 * @param[in] Bool isRepeting
3748 PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx
3751 RgSchDlHqProcCb *hqP,
3756 PUBLIC Void rgSCHUtlDlHqPTbRmvFrmTx(subFrm, hqP, tbIdx, isRepeting)
3758 RgSchDlHqProcCb *hqP;
3763 RgSchCellCb *cell = NULLP;
3764 /* Check with TDD */
3766 (hqP->hqE->ue->ackNakRepCb.cfgRepCnt !=
3767 hqP->tbInfo[tbIdx].fbkRepCntr))
3769 cmLListDelFrm(&subFrm->ackNakRepQ,
3770 &hqP->tbInfo[tbIdx].anRepLnk[hqP->tbInfo[tbIdx].fbkRepCntr]);
3774 if (NULLP != hqP->hqPSfLnk.node)
3777 if (hqP->hqE->msg4Proc == hqP)
3779 /* Msg4 will be scheduled on PCELL only hence delete directly from subFrm msg4HqpList */
3780 cmLListDelFrm(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3784 cell = hqP->hqE->cell;
3785 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3786 /* ue->cell will always hold PCell information */
3787 cmLListDelFrm(&hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3788 if (0 == hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst.count)
3791 cmLListDelFrm(&cell->subFrms[subFrm->dlIdx]->ueLst,
3792 &hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3793 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)NULLP;
3794 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt = 0;
3797 hqP->hqPSfLnk.node = NULLP;
3799 hqP->subFrm = NULLP;
3806 * @brief Handler for accessing the existing SCellCb identified by the key
3807 * SCellId under the CellCb.
3811 * Function : rgSchUtlGetCellCb
3814 * @param[in] *cellCb
3816 * @return RgSchUeCb*
3819 PUBLIC RgSchCellCb* rgSchUtlGetCellCb
3825 PUBLIC RgSchCellCb* rgSchUtlGetCellCb(inst, cellId)
3830 RgSchCellCb *cellCb = NULLP;
3833 TRC2(rgSchUtlGetCellCb);
3835 strtCellId = rgSchCb[inst].genCfg.startCellId;
3836 cellCb = rgSchCb[inst].cells[cellId - strtCellId];
3840 } /* rgSchUtlGetCellCb */
3843 * @brief Handler for deriving the servCellidx
3847 * Function : rgSchUtlGetServCellIdx
3850 * @param[in] *cellId
3851 * @param[in] RgSchUeCb *ue
3852 * @return U8 servCellIdx
3855 PUBLIC U8 rgSchUtlGetServCellIdx
3862 PUBLIC U8 rgSchUtlGetServCellIdx(inst,cellId,ue)
3871 TRC2(rgSchUtlGetCellCb);
3873 strtCellId = rgSchCb[inst].genCfg.startCellId;
3875 servCellIdx = ue->cellIdToCellIdxMap[cellId - strtCellId];
3877 RETVALUE(servCellIdx);
3879 } /* rgSchUtlGetCellCb */
3882 * @brief Handler for validating the Cell Id received secondary Cell Addition
3886 * Function : rgSchUtlGetCellId
3889 * @param[in] *cellCb
3891 * @return RgSchUeCb*
3894 PUBLIC S16 rgSchUtlVldtCellId
3900 PUBLIC S16 rgSchUtlVldtCellId(inst, cellId)
3907 TRC2(rgSchUtlVldtCellId);
3909 strtCellId = rgSchCb[inst].genCfg.startCellId;
3910 if((cellId >= strtCellId) && ((cellId - strtCellId) < CM_LTE_MAX_CELLS))
3915 } /* rgSchUtlVldtCellId */
3919 * @brief UE reconfiguration for scheduler
3923 * Function : rgSCHUtlRgrUeRecfg
3925 * This functions updates UE specific scheduler
3926 * information upon UE reconfiguration
3928 * @param[in] RgSchCellCb *cell
3929 * @param[in] RgSchUeCb *ue
3930 * @param[int] RgrUeRecfg *ueRecfg
3931 * @param[out] RgSchErrInfo *err
3937 PUBLIC S16 rgSCHUtlRgrUeRecfg
3941 RgrUeRecfg *ueRecfg,
3945 PUBLIC S16 rgSCHUtlRgrUeRecfg(cell, ue, ueRecfg, err)
3948 RgrUeRecfg *ueRecfg;
3952 /* Changes for UE Category Reconfiguration feature addition */
3953 RgSchCmnUe *ueSch = RG_SCH_CMN_GET_UE(ue, cell);
3955 TRC2(rgSCHUtlRgrUeRecfg);
3957 /* Changes for UE Category Reconfiguration feature addition */
3958 if (ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
3960 ueSch->cmn.ueCat = ueRecfg->ueCatEnum-1;
3962 ue->ueCatEnum = ueRecfg->ueCatEnum;
3966 /* DL MU-MIMO not supported */
3967 if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
3970 if (ueRecfg->txMode.pres == PRSNT_NODEF)
3972 if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_5)
3974 err->errCause = RGSCHERR_SCH_CFG;
3978 if(ue->mimoInfo.txMode != ueRecfg->txMode.txModeEnum)
3980 /* Decremnt the previos A value for this cell */
3981 ue->f1bCsAVal -= rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode);
3982 /* Update A value with the new TM Mode */
3983 ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(ueRecfg->txMode.txModeEnum);
3986 RLOG1(L_INFO,"UeReCfg A valie is %d\n",ue->f1bCsAVal);
3989 ue->mimoInfo.txMode = ueRecfg->txMode.txModeEnum;
3993 /* [ccpu00123958]-ADD- Check for PUSCH related Reconfig from the bit mask */
3994 if(ueRecfg->ueRecfgTypes & RGR_UE_PUSCH_RECFG)
3996 /* Fix: ccpu00124012 */
3997 /* TODO:: Need to check if this is
3998 mandatory to be re-configured on UE category re-configuration */
3999 /* ue->ul.betaHqOffst = ueRecfg->puschDedCfg.bACKIdx;
4000 ue->ul.betaCqiOffst = ueRecfg->puschDedCfg.bCQIIdx;
4001 ue->ul.betaRiOffst = ueRecfg->puschDedCfg.bRIIdx;*/
4004 if (ueRecfg->ueRecfgTypes & RGR_UE_ULTXANTSEL_RECFG)
4006 ue->ul.ulTxAntSel = ueRecfg->ulTxAntSel;
4008 if (ueRecfg->ueRecfgTypes & RGR_UE_CDBKSBST_RECFG)
4010 ue->mimoInfo.cdbkSbstRstrctn = ueRecfg->ueCodeBookRstRecfg;
4013 /* Commenting here to assign garbage value when it is not set in APP. */
4014 //ue->accessStratumRls = ueRecfg->accessStratumRls;
4015 RETVALUE(cell->sc.apis->rgSCHRgrUeRecfg(cell, ue, ueRecfg, err));
4016 } /* rgSCHUtlRgrUeRecfg */
4019 * @brief This function deletes a service from scheduler
4023 * Function: rgSCHUtlFreeDlLc
4024 * Purpose: This function is made available through a FP for
4025 * making scheduler aware of a service being deleted from UE
4027 * Invoked by: BO and Scheduler
4029 * @param[in] RgSchCellCb* cell
4030 * @param[in] RgSchUeCb* ue
4031 * @param[in] RgSchDlLcCb* svc
4035 PUBLIC Void rgSCHUtlFreeDlLc
4042 PUBLIC Void rgSCHUtlFreeDlLc(cell, ue, svc)
4048 TRC2(rgSCHUtlFreeDlLc);
4049 cell->sc.apis->rgSCHFreeDlLc(cell, ue, svc);
4051 /* Stack Crash problem for TRACE5 changes. added the return below . */
4057 * @brief UE deletion for scheduler
4061 * Function : rgSCHUtlFreeUe
4063 * This functions deletes all scheduler information
4064 * pertaining to a UE
4066 * @param[in] RgSchCellCb *cell
4067 * @param[in] RgSchUeCb *ue
4071 PUBLIC Void rgSCHUtlFreeUe
4077 PUBLIC Void rgSCHUtlFreeUe(cell, ue)
4082 TRC2(rgSCHUtlFreeUe);
4084 rgSCHUtlDelUeANFdbkInfo(ue,RGSCH_PCELL_INDEX);
4086 cell->sc.apis->rgSCHFreeUe(cell, ue);
4088 /* Stack Crash problem for TRACE5 changes. added the return below . */
4091 } /* rgSCHUtlFreeUe */
4094 * @brief This function updates the scheduler with service for a UE
4098 * Function: rgSCHUtlDlDedBoUpd
4099 * Purpose: This function should be called whenever there is a
4100 * change BO for a service.
4102 * Invoked by: BO and Scheduler
4104 * @param[in] RgSchCellCb* cell
4105 * @param[in] RgSchUeCb* ue
4106 * @param[in] RgSchDlLcCb* lc
4110 PUBLIC Void rgSCHUtlDlDedBoUpd
4117 PUBLIC Void rgSCHUtlDlDedBoUpd(cell, ue, lc)
4123 TRC2(rgSCHUtlDlDedBoUpd);
4124 cell->sc.apis->rgSCHDlDedBoUpd(cell, ue, lc);
4128 * @brief Record MSG3 allocation into the UE
4132 * Function : rgSCHUtlRecMsg3Alloc
4134 * This function is invoked to update record msg3 allocation information
4135 * in the UE when UE is detected for RaCb
4137 * @param[in] RgSchCellCb *cell
4138 * @param[in] RgSchUeCb *ue
4139 * @param[in] RgSchRaCb *raCb
4143 PUBLIC Void rgSCHUtlRecMsg3Alloc
4150 PUBLIC Void rgSCHUtlRecMsg3Alloc(cell, ue, raCb)
4156 TRC2(rgSCHUtlRecMsg3Alloc)
4157 cell->sc.apis->rgSCHUlRecMsg3Alloc(cell, ue, raCb);
4160 } /* rgSCHRecMsg3Alloc */
4164 * @brief Update harq process for allocation
4168 * Function : rgSCHUtlUpdUlHqProc
4170 * This function is invoked when harq process
4171 * control block is now in a new memory location
4172 * thus requiring a pointer/reference update.
4174 * @param[in] RgSchCellCb *cell
4175 * @param[in] RgSchUlHqProcCb *curProc
4176 * @param[in] RgSchUlHqProcCb *oldProc
4182 PUBLIC S16 rgSCHUtlUpdUlHqProc
4185 RgSchUlHqProcCb *curProc,
4186 RgSchUlHqProcCb *oldProc
4189 PUBLIC S16 rgSCHUtlUpdUlHqProc(cell, curProc, oldProc)
4191 RgSchUlHqProcCb *curProc;
4192 RgSchUlHqProcCb *oldProc;
4195 TRC2(rgSCHUtlUpdUlHqProc);
4196 RETVALUE(cell->sc.apis->rgSCHUpdUlHqProc(cell, curProc, oldProc));
4197 } /* rgSCHUtlUpdUlHqProc */
4200 * @brief UL grant for contention resolution
4204 * Function : rgSCHUtlContResUlGrant
4206 * Add UE to another queue specifically for CRNTI based contention
4209 * @param[in] RgSchCellCb *cell
4210 * @param[in] RgSchUeCb *ue
4211 * @param[out] RgSchErrInfo *err
4217 PUBLIC S16 rgSCHUtlContResUlGrant
4224 PUBLIC S16 rgSCHUtlContResUlGrant(cell, ue, err)
4230 TRC2(rgSCHUtlContResUlGrant);
4233 ue->isMsg4PdcchWithCrnti = TRUE;
4235 RETVALUE(cell->sc.apis->rgSCHContResUlGrant(cell, ue, err));
4236 } /* rgSCHUtlContResUlGrant */
4239 * @brief SR reception handling
4243 * Function : rgSCHUtlSrRcvd
4245 * - Handles SR reception for UE
4247 * @param[in] RgSchCellCb *cell
4248 * @param[in] RgSchUeCb *ue
4249 * @param[out] RgSchErrInfo *err
4255 PUBLIC S16 rgSCHUtlSrRcvd
4259 CmLteTimingInfo frm,
4263 PUBLIC S16 rgSCHUtlSrRcvd(cell, ue, frm, err)
4266 CmLteTimingInfo frm;
4270 TRC2(rgSCHUtlSrRcvd);
4271 RETVALUE(cell->sc.apis->rgSCHSrRcvd(cell, ue, frm, err));
4272 } /* rgSCHUtlSrRcvd */
4275 * @brief Short BSR update
4279 * Function : rgSCHUtlUpdBsrShort
4281 * This functions does requisite updates to handle short BSR reporting
4283 * @param[in] RgSchCellCb *cell
4284 * @param[in] RgSchUeCb *ue
4285 * @param[in] U8 lcgId
4287 * @param[out] RgSchErrInfo *err
4293 PUBLIC Void rgSCHUtlUpdBsrShort
4302 PUBLIC Void rgSCHUtlUpdBsrShort(cell, ue, lcgId, bsr, err)
4310 TRC2(rgSCHUtlUpdBsrShort);
4311 cell->sc.apis->rgSCHUpdBsrShort(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4313 } /* rgSCHUtlUpdBsrShort */
4317 * @brief Truncated BSR update
4321 * Function : rgSCHUtlUpdBsrTrunc
4323 * This functions does required updates to handle truncated BSR report
4326 * @param[in] RgSchCellCb *cell
4327 * @param[in] RgSchUeCb *ue
4328 * @param[in] U8 lcgId
4330 * @param[out] RgSchErrInfo *err
4336 PUBLIC Void rgSCHUtlUpdBsrTrunc
4345 PUBLIC Void rgSCHUtlUpdBsrTrunc(cell, ue, lcgId, bsr, err)
4353 TRC2(rgSCHUtlUpdBsrTrunc);
4354 cell->sc.apis->rgSCHUpdBsrTrunc(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4356 } /* rgSCHUtlUpdBsrTrunc */
4360 * @brief Long BSR update
4364 * Function : rgSCHUtlUpdBsrLong
4366 * - Update BSRs for all configured LCGs
4367 * - Update priority of LCGs if needed
4368 * - Update UE's position within/across uplink scheduling queues
4371 * @param[in] RgSchCellCb *cell
4372 * @param[in] RgSchUeCb *ue
4373 * @param[in] U8 bsr0
4374 * @param[in] U8 bsr1
4375 * @param[in] U8 bsr2
4376 * @param[in] U8 bsr3
4377 * @param[out] RgSchErrInfo *err
4383 PUBLIC Void rgSCHUtlUpdBsrLong
4394 PUBLIC Void rgSCHUtlUpdBsrLong(cell, ue, bsr0, bsr1, bsr2, bsr3, err)
4405 TRC2(rgSCHUtlUpdBsrLong);
4411 cell->sc.apis->rgSCHUpdBsrLong(cell, ue, bsArr, err);
4413 } /* rgSCHUtlUpdBsrLong */
4416 * @brief EXT PHR update
4420 * Function : rgSCHUtlUpdExtPhr
4422 * Updates extended power headroom info for a UE
4424 * @param[in] RgSchCellCb *cell
4425 * @param[in] RgSchUeCb *ue
4427 * @param[out] RgSchErrInfo *err
4433 PUBLIC S16 rgSCHUtlUpdExtPhr
4437 RgInfExtPhrCEInfo * extPhr,
4441 PUBLIC S16 rgSCHUtlUpdExtPhr(cell, ue, extPhr, err)
4444 RgInfExtPhrCEInfo * extPhr;
4448 TRC2(rgSCHUtlUpdExtPhr);
4449 RETVALUE(cell->sc.apis->rgSCHUpdExtPhr(cell, ue, extPhr, err));
4450 } /* rgSCHUtlUpdExtPhr */
4459 * Function : rgSCHUtlUpdPhr
4461 * Updates power headroom info for a UE
4463 * @param[in] RgSchCellCb *cell
4464 * @param[in] RgSchUeCb *ue
4466 * @param[out] RgSchErrInfo *err
4472 PUBLIC S16 rgSCHUtlUpdPhr
4480 PUBLIC S16 rgSCHUtlUpdPhr(cell, ue, phr, err)
4487 TRC2(rgSCHUtlUpdPhr);
4488 RETVALUE(cell->sc.apis->rgSCHUpdPhr(cell, ue, phr, err));
4489 } /* rgSCHUtlUpdPhr */
4493 * @brief Indication of UL CQI
4497 * Function : rgSCHUtlUlCqiInd
4499 * - Updates uplink CQI information for the UE. Computes and
4500 * stores the lowest CQI of CQIs reported in all subbands
4502 * @param[in] RgSchCellCb *cell
4503 * @param[in] RgSchUeCb *ue
4504 * @param[in] TfuUlCqiRpt *ulCqiInfo
4508 PUBLIC Void rgSCHUtlUlCqiInd
4512 TfuUlCqiRpt *ulCqiInfo
4515 PUBLIC Void rgSCHUtlUlCqiInd(cell, ue, ulCqiInfo)
4518 TfuUlCqiRpt *ulCqiInfo;
4521 TRC2(rgSCHUtlUlCqiInd);
4522 cell->sc.apis->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
4524 } /* rgSCHUtlUlCqiInd */
4527 * @brief Indication of PUCCH power adjustment
4531 * Function : rgSCHUtlPucchDeltaPwrInd
4533 * - Updates uplink CQI information for the UE. Computes and
4534 * stores the lowest CQI of CQIs reported in all subbands
4536 * @param[in] RgSchCellCb *cell
4537 * @param[in] RgSchUeCb *ue
4538 * @param[in] U8 delta
4542 PUBLIC Void rgSCHUtlPucchDeltaPwrInd
4549 PUBLIC Void rgSCHUtlPucchDeltaPwrInd(cell, ue, delta)
4555 TRC2(rgSCHUtlPucchDeltaPwrInd);
4556 cell->sc.apis->rgSCHPucchDeltaPwrInd(cell, ue, delta);
4558 } /* rgSCHUtlPucchDeltaPwrInd */
4560 /* Start: LTEMAC_2.1_DEV_CFG */
4562 * @brief Ue Reset Request
4566 * Function : rgSCHUtlUeReset
4569 * @param[in] RgSchCellCb *cell
4570 * @param[in] RgSchUeCb *ue
4574 PUBLIC Void rgSCHUtlUeReset
4580 PUBLIC Void rgSCHUtlUeReset(cell, ue)
4585 TRC2(rgSCHUtlUeReset);
4587 cell->sc.apis->rgSCHUeReset(cell, ue);
4589 } /* rgSCHUtlUeReset */
4590 /* End: LTEMAC_2.1_DEV_CFG */
4593 * @brief Returns HARQ proc for which data expected now
4597 * Function: rgSCHUtlUlHqProcForUe
4598 * Purpose: This function returns the harq process for
4599 * which data is expected in the current slot.
4600 * It does not validate if the HARQ process
4601 * has an allocation.
4605 * @param[in] RgSchCellCb *cell
4606 * @param[in] CmLteTimingInfo frm
4607 * @param[in] RgSchUeCb *ue
4608 * @param[out] RgSchUlHqProcCb **procRef
4612 PUBLIC Void rgSCHUtlUlHqProcForUe
4615 CmLteTimingInfo frm,
4617 RgSchUlHqProcCb **procRef
4620 PUBLIC Void rgSCHUtlUlHqProcForUe(cell, frm, ue, procRef)
4622 CmLteTimingInfo frm;
4624 RgSchUlHqProcCb **procRef;
4627 TRC2(rgSCHUtlUlHqProcForUe);
4628 cell->sc.apis->rgSCHUlHqProcForUe(cell, frm, ue, procRef);
4630 /* Stack Crash problems for TRACE5 changes. added the return below */
4636 * @brief Returns first uplink allocation to send reception
4641 * Function: rgSCHUtlFirstRcptnReq(cell)
4642 * Purpose: This function returns the first uplink allocation
4643 * (or NULLP if there is none) in the slot
4644 * in which is expected to prepare and send reception
4649 * @param[in] RgSchCellCb *cell
4650 * @return RgSchUlAlloc*
4653 PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq
4658 PUBLIC RgSchUlAlloc *rgSCHUtlFirstRcptnReq(cell)
4662 TRC2(rgSCHUtlFirstRcptnReq);
4663 RETVALUE(cell->sc.apis->rgSCHFirstRcptnReq(cell));
4667 * @brief Returns first uplink allocation to send reception
4672 * Function: rgSCHUtlNextRcptnReq(cell)
4673 * Purpose: This function returns the next uplink allocation
4674 * (or NULLP if there is none) in the slot
4675 * in which is expected to prepare and send reception
4680 * @param[in] RgSchCellCb *cell
4681 * @return RgSchUlAlloc*
4684 PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq
4690 PUBLIC RgSchUlAlloc *rgSCHUtlNextRcptnReq(cell, alloc)
4692 RgSchUlAlloc *alloc;
4695 TRC2(rgSCHUtlNextRcptnReq);
4696 RETVALUE(cell->sc.apis->rgSCHNextRcptnReq(cell, alloc));
4700 * @brief Returns first uplink allocation to send HARQ feedback
4705 * Function: rgSCHUtlFirstHqFdbkAlloc
4706 * Purpose: This function returns the first uplink allocation
4707 * (or NULLP if there is none) in the slot
4708 * in which it is expected to prepare and send HARQ
4713 * @param[in] RgSchCellCb *cell
4715 * @return RgSchUlAlloc*
4718 PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc
4724 PUBLIC RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc(cell, idx)
4729 TRC2(rgSCHUtlFirstHqFdbkAlloc);
4730 RETVALUE(cell->sc.apis->rgSCHFirstHqFdbkAlloc(cell, idx));
4735 * @brief Returns next allocation to send HARQ feedback for
4739 * Function: rgSCHUtlNextHqFdbkAlloc(cell)
4740 * Purpose: This function returns the next uplink allocation
4741 * (or NULLP if there is none) in the slot
4742 * for which HARQ feedback needs to be sent.
4746 * @param[in] RgSchCellCb *cell
4747 * @return RgSchUlAlloc*
4750 PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc
4753 RgSchUlAlloc *alloc,
4757 PUBLIC RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc(cell, alloc, idx)
4759 RgSchUlAlloc *alloc;
4763 TRC2(rgSCHUtlNextHqFdbkAlloc);
4764 RETVALUE(cell->sc.apis->rgSCHNextHqFdbkAlloc(cell, alloc, idx));
4767 /***********************************
4768 ***********************************/
4770 * @brief This API is invoked to send TFU SAP bind request to PHY.
4774 * Function : rgSCHUtlTfuBndReq
4776 * This API is invoked to send TFU SAP bind request to PHY from scheduler
4777 * isntance. It fills in the Pst structure, spId and suId values and
4778 * invokes bind request primitive at TFU.
4780 * @param[in] Inst instId
4781 * @param[in] SuId suId
4782 * @param[in] SpId spId
4788 PUBLIC S16 rgSCHUtlTfuBndReq
4795 PUBLIC S16 rgSCHUtlTfuBndReq(instId, suId, spId)
4802 RgSchLowSapCb *tfuSap;
4804 TRC2(rgSCHUtlTfuBndReq);
4806 /* Get the lower SAP control block from the layer control block. */
4807 tfuSap = &(rgSchCb[instId].tfuSap[suId]);
4808 (Void)cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
4809 if((ret = RgLiTfuSchBndReq (&pst, suId, spId)) != ROK)
4811 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlTfuBndReq() Call to RgLiTfuBndReq()"
4815 } /* rgSCHUtlTfuBndReq */
4818 * @brief This API is invoked to send TFU SAP unbind request to PHY.
4822 * Function : rgSCHUtlTfuUBndReq
4823 * This API is invoked to send TFU SAP unbind request to PHY from Scheduler
4824 * isntance. It fills in the Pst structure and spId value and invokes
4825 * unbind request primitive at TFU.
4827 * @param[in] SpId spId
4833 PUBLIC S16 rgSCHUtlTfuUBndReq
4836 RgSchLowSapCfgInfo sapCfg,
4840 PUBLIC S16 rgSCHUtlTfuUBndReq(inst, sapCfg, reason)
4842 RgSchLowSapCfgInfo sapCfg;
4849 TRC2(rgSCHUtlTfuUBndReq);
4851 /* Get the lower SAP control block from the layer control block. */
4852 cmMemcpy ((U8*)&pst, (U8*)&(sapCfg.sapPst), sizeof(Pst));
4853 if((ret = RgLiTfuSchUbndReq (&pst, sapCfg.spId, reason)) != ROK)
4855 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuUBndReq() Call to"
4856 " RgLiTfuUbndReq() failed");
4860 } /* rgSCHUtlTfuUBndReq */
4862 /***********************************************************
4864 * Func : rgSCHUtlResetSfAlloc
4866 * Desc : Utility Function to Reset slot allocation information.
4875 **********************************************************/
4877 PUBLIC S16 rgSCHUtlResetSfAlloc
4879 RgInfSfAlloc *sfAlloc,
4880 Bool resetCmnLcInfo,
4884 PUBLIC S16 rgSCHUtlResetSfAlloc(sfAlloc,resetCmnLcInfo,restAlloc)
4885 RgInfSfAlloc *sfAlloc;
4886 Bool resetCmnLcInfo;
4890 TRC2(rgSCHUtlResetSfAlloc);
4891 if(TRUE == restAlloc)
4893 if(sfAlloc->ueInfo.numUes)
4895 cmMemset((U8 *)sfAlloc->ueInfo.allocInfo,0x00,
4896 (sizeof(RgInfUeAlloc)*sfAlloc->ueInfo.numUes));
4898 sfAlloc->ueInfo.numUes = 0;
4899 sfAlloc->rarInfo.numRaRntis = 0;
4900 sfAlloc->flowCntrlInfo.numUes = 0;
4902 if(TRUE == resetCmnLcInfo)
4904 sfAlloc->cmnLcInfo.bitMask = 0;
4909 /***********************************************************
4911 * Func : rgSCHUtlGetRlsHqAlloc
4913 * Desc : Utility Function to Allocate slot allocation information.
4922 **********************************************************/
4924 PUBLIC S16 rgSCHUtlGetRlsHqAlloc
4929 PUBLIC S16 rgSCHUtlGetRlsHqAlloc(cell)
4934 Inst inst = cell->instIdx;
4935 TRC2(rgSCHUtlGetRlsHqAlloc);
4936 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4938 cell->rlsHqArr[idx].cellId = cell->cellId;
4940 /* Allocating with additional location, to accommodate
4941 TA scheduling along with maximum no of UEs per SF */
4943 /* Allocate memory for "scheduled UE" Info */
4944 if((rgSCHUtlAllocSBuf(inst,
4945 (Data**)&(cell->rlsHqArr[idx].ueHqInfo),
4946 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
4948 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4958 /***********************************************************
4960 * Func : rgSCHUtlPutRlsHqAlloc
4962 * Desc : Utility Function to deallocate slot allocation information.
4971 **********************************************************/
4973 PUBLIC S16 rgSCHUtlPutRlsHqAlloc
4978 PUBLIC S16 rgSCHUtlPutRlsHqAlloc(cell)
4983 Inst inst = cell->instIdx;
4984 TRC2(rgSCHUtlPutRlsHqAlloc);
4986 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4988 /* Deallocate memory for "scheduled UE" Info */
4989 if (cell->rlsHqArr[idx].ueHqInfo != NULLP)
4991 /* Freeing with additional location, to accommodate TA
4992 scheduling along with maximum no of UEs per SF */
4993 /* ccpu00117052 - MOD - Passing double pointer
4994 for proper NULLP assignment*/
4995 rgSCHUtlFreeSBuf(inst,
4996 (Data **)(&(cell->rlsHqArr[idx].ueHqInfo)),
4997 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF));
5006 /***********************************************************
5008 * Func : rgSCHUtlGetSfAlloc
5010 * Desc : Utility Function to Allocate slot allocation information.
5019 **********************************************************/
5021 PUBLIC S16 rgSCHUtlGetSfAlloc
5026 PUBLIC S16 rgSCHUtlGetSfAlloc(cell)
5032 Inst inst = cell->instIdx;
5033 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5034 TRC2(rgSCHUtlGetSfAlloc);
5037 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5039 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5042 cell->sfAllocArr[idx].cellId = cell->cellId;
5044 /* Allocating with additional location, to accommodate
5045 TA scheduling along with maximum no of UEs per SF */
5047 /* Allocate memory for "scheduled UE" Info */
5048 if((rgSCHUtlAllocSBuf(inst,
5049 (Data**)&(cell->sfAllocArr[idx].ueInfo.allocInfo),
5050 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
5052 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5057 /* Allocate memory for "scheduled RAR" Info */
5058 if((rgSCHUtlAllocSBuf(inst,
5059 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo),
5060 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF))) != ROK)
5062 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5066 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5068 if((rgSCHUtlAllocSBuf(inst,
5069 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo),
5070 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)))) != ROK)
5072 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
5081 rgSCHEmtcUtlGetSfAlloc(cell);
5088 /***********************************************************
5090 * Func : rgSCHUtlPutSfAlloc
5092 * Desc : Utility Function to deallocate slot allocation information.
5101 **********************************************************/
5103 PUBLIC S16 rgSCHUtlPutSfAlloc
5108 PUBLIC S16 rgSCHUtlPutSfAlloc(cell)
5114 Inst inst = cell->instIdx;
5115 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5116 TRC2(rgSCHUtlPutSfAlloc);
5119 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5121 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5124 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo != NULLP)
5126 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5128 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo != NULLP)
5129 /* ccpu00117052 - MOD - Passing double pointer
5130 for proper NULLP assignment*/
5131 rgSCHUtlFreeSBuf(inst,
5132 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].\
5134 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)));
5136 /* Deallocate memory for "scheduled RAR" Info */
5137 /* ccpu00117052 - MOD - Passing double pointer
5138 for proper NULLP assignment*/
5139 rgSCHUtlFreeSBuf(inst,
5140 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo)),
5141 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF));
5143 /* Deallocate memory for "scheduled UE" Info */
5144 if (cell->sfAllocArr[idx].ueInfo.allocInfo != NULLP)
5146 /* Freeing with additional location, to accommodate TA
5147 scheduling along with maximum no of UEs per SF */
5148 /* ccpu00117052 - MOD - Passing double pointer
5149 for proper NULLP assignment*/
5150 rgSCHUtlFreeSBuf(inst,
5151 (Data**)(&(cell->sfAllocArr[idx].ueInfo.allocInfo)),
5152 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF));
5157 rgSCHEmtcUtlPutSfAlloc(cell);
5163 /***********************************************************
5165 * Func : rgSCHUtlAllocSBuf
5167 * Desc : Utility Function to Allocate static buffer.
5168 * Memory allocated is assumed contiguous.
5174 * Notes: Caller doesnt need to raise the alarm in case of memory
5175 * allocation gets failed.
5179 **********************************************************/
5181 PUBLIC S16 rgSCHUtlAllocSBuf
5183 Inst inst, /* Instance of the invoking scheduler */
5184 Data **pData, /* Pointer of the data to be returned */
5185 Size size /* size */
5188 PUBLIC S16 rgSCHUtlAllocSBuf(inst, pData, size)
5189 Inst inst; /* Instance of the invoking scheduler */
5190 Data **pData; /* Pointer of the data to be returned */
5191 Size size; /* size */
5194 /* Moving alarm diagnostics to available scope */
5196 TRC2(rgSCHUtlAllocSBuf)
5198 /* Initialize the param to NULLP */
5201 /* May not be necessary for data performance path */
5209 /* allocate buffer */
5210 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5211 MS_BUF_ADD_ALLOC_CALLER();
5213 if (SGetSBuf(rgSchCb[inst].rgSchInit.region, rgSchCb[inst].rgSchInit.pool,
5214 pData, size) != ROK)
5216 RgUstaDgn dgn; /* Alarm diagnostics structure */
5217 dgn.type = LRG_USTA_DGNVAL_MEM;
5218 dgn.u.mem.region = rgSchCb[inst].rgSchInit.region;
5219 dgn.u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5220 /* Send an alarm to Layer Manager */
5221 rgSCHLmmStaInd(inst, LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
5222 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
5223 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG015, 0, "Unable to Allocate Buffer");
5224 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Unable to Allocate the Buffer");
5229 /* zero out the allocated memory */
5230 cmMemset((U8 *)*pData, 0x00, size);
5234 } /* end of rgSCHUtlAllocSBuf */
5239 * Fun: rgSCHUtlFreeSBuf
5241 * Desc: The argument to rgSCHUtlFreeSBuf() is a pointer to a block
5242 * previously allocated by rgSCHUtlAllocSBuf() and size. It
5243 * deallocates the memory.
5251 PUBLIC Void rgSCHUtlFreeSBuf
5253 Inst inst, /* Instance of the invoking scheduler */
5254 Data **data, /* pointer to data */
5255 Size size /* size */
5258 PUBLIC Void rgSCHUtlFreeSBuf(inst, data, size)
5259 Inst inst; /* Instance of the invoking scheduler */
5260 Data **data; /* pointer to data */
5261 Size size; /* size */
5267 TRC2(rgSCHUtlFreeSBuf)
5269 if ((data == NULLP) || (*data == NULLP) || (size == 0))
5275 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5276 MS_BUF_ADD_CALLER();
5278 /* Deallocate buffer */
5279 ret = SPutSBuf(rgSchCb[inst].rgSchInit.region,
5280 rgSchCb[inst].rgSchInit.pool, (*data), size);
5284 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG016, (ErrVal) 0,
5285 "rgSCHUtlFreeSBuf failed.\n");
5286 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHUtlFreeSBuf failed");
5290 /* ccpu00117052 - ADD - Assigning the pointer to NULLP */
5294 } /* end of rgSCHUtlFreeSBuf */
5300 * Fun: rgSCHUtlFreeWarningSiSeg
5302 * Desc: This is used to deallocate Warning SI Seg.
5311 PUBLIC Void rgSCHUtlFreeWarningSiSeg
5318 PUBLIC Void rgSCHUtlFreeWarningSiSeg(reg, pool, siPduLst)
5321 CmLListCp *siPduLst;
5327 TRC2(rgSCHUtlFreeWarningSiSeg)
5329 while (siPduLst->first != NULLP)
5331 node = siPduLst->first;
5332 pdu = (Buffer *)node->node;
5333 cmLListDelFrm(siPduLst, node);
5334 RGSCH_FREE_MSG(pdu);
5335 SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList));
5340 } /* end of rgSCHUtlFreeWarningSiSeg */
5345 * Fun: rgSCHUtlFreeWarningSiPdu
5347 * Desc: This is used to deallocate Warning SI PDU.
5356 PUBLIC Void rgSCHUtlFreeWarningSiPdu
5361 PUBLIC Void rgSCHUtlFreeWarningSiPdu(cell)
5367 RgSchWarningSiInfo *warningSi;
5368 RgSchWarningSiPdu *warningSiPdu;
5370 TRC2(rgSCHUtlFreeWarningSiPdu)
5372 warningSi = (RgSchWarningSiInfo *) cell->siCb.\
5373 siArray[cell->siCb.siCtx.siId-1].si;
5374 /* ccpu00136659: CMAS ETWS design changes */
5375 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5381 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5382 pdu = warningSiPdu->pdu;
5383 /* ccpu00136659: CMAS ETWS design changes */
5384 cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node);
5385 RGSCH_FREE_MSG(pdu);
5386 if(warningSi->warningSiMsg.segLstCp.count == 0)
5388 /* ccpu00136659: CMAS ETWS design changes */
5389 cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP;
5390 rgSCHUtlRgrWarningSiCfgCfm(cell->instIdx,
5391 rgSchCb[cell->instIdx].rgrSap->sapCfg.spId,
5392 cell->siCb.warningSi[warningSi->idx].siId,
5393 warningSi->warningSiMsg.transId, RGR_CFG_CFM_TX_COMPLETE);
5398 } /* end of rgSCHUtlFreeWarningSiPdu */
5403 * Fun: rgSCHUtlGetWarningSiPdu
5405 * Desc: This is used to get Warning SI PDU for Scheduling.
5414 PUBLIC Buffer *rgSCHUtlGetWarningSiPdu
5419 PUBLIC Buffer *rgSCHUtlGetWarningSiPdu(cell)
5423 RgSchWarningSiInfo *warningSi;
5424 RgSchWarningSiPdu *warningSiPdu;
5428 TRC2(rgSCHUtlGetWarningSiPdu)
5430 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5431 siArray[cell->siCb.siCtx.siId-1].si;
5432 /* ccpu00136659: CMAS ETWS design changes */
5433 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5436 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5437 pdu = warningSiPdu->pdu;
5444 } /* rgSCHUtlGetWarningSiPdu */
5449 * Fun: rgSCHUtlGetMcsAndNPrb
5451 * Desc: This is used to get mcs and nPrb value.
5460 PUBLIC S16 rgSCHUtlGetMcsAndNPrb
5468 PUBLIC S16 rgSCHUtlGetMcsAndNPrb(cell, nPrb, mcs, msgLen)
5475 RgSchWarningSiInfo *warningSi;
5476 RgSchWarningSiPdu *warningSiPdu;
5479 TRC2(rgSCHUtlGetMcsAndNPrb)
5481 if(cell->siCb.siCtx.warningSiFlag == FALSE)
5483 *mcs = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].mcs;
5484 *nPrb = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].nPrb;
5485 *msgLen = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].msgLen;
5489 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5490 siArray[cell->siCb.siCtx.siId-1].si;
5491 /* ccpu00136659: CMAS ETWS design changes */
5492 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5498 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5499 *mcs = warningSiPdu->mcs;
5500 *nPrb = warningSiPdu->nPrb;
5501 *msgLen = warningSiPdu->msgLen;
5506 } /* rgSCHUtlGetMcsAndNPrb */
5510 * Fun: rgSCHUtlCalMacAndPrb
5512 * Desc: This is used to Calculate mcs and nPrb value for SIB1 and SIs.
5521 PUBLIC S16 rgSCHUtlCalMcsAndNPrb
5529 PUBLIC S16 rgSCHUtlCalMcsAndNPrb(cell, nPrb, mcs, msgLen)
5539 TRC2(rgSCHUtlCalMcsAndNPrb)
5541 /*Get the nPrb and mcs parametr values */
5542 if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8))
5544 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "msgLen does "
5545 "not match any valid TB Size");
5550 if(cfgType == RGR_SI_CFG_TYPE_SIB1 || cfgType == RGR_SI_CFG_TYPE_SIB1_PWS)
5553 if(cell->siCb.crntSiInfo.sib1Info.sib1 == NULLP)
5555 cell->siCb.crntSiInfo.sib1Info.mcs = mcs;
5556 cell->siCb.crntSiInfo.sib1Info.nPrb = nPrb;
5557 cell->siCb.crntSiInfo.sib1Info.msgLen = msgLen;
5561 cell->siCb.newSiInfo.sib1Info.mcs = mcs;
5562 cell->siCb.newSiInfo.sib1Info.nPrb= nPrb;
5563 cell->siCb.newSiInfo.sib1Info.msgLen = msgLen;
5568 if(cfgType == RGR_SI_CFG_TYPE_SI)
5570 if(cell->siCb.crntSiInfo.siInfo[siId-1].si == NULLP &&
5571 !(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD))
5573 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5574 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5575 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5579 cell->siCb.newSiInfo.siInfo[siId-1].mcs = mcs;
5580 cell->siCb.newSiInfo.siInfo[siId-1].nPrb= nPrb;
5581 cell->siCb.newSiInfo.siInfo[siId-1].msgLen = msgLen;
5585 if(cfgType == RGR_SI_CFG_TYPE_SIB8_CDMA)
5587 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5588 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5589 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5596 /***********************************************************
5598 * Func : rgSCHUtlFillDgnParams
5600 * Desc : Utility Function to Fill Diagonostic params.
5608 **********************************************************/
5610 PUBLIC Void rgSCHUtlFillDgnParams
5617 PUBLIC Void rgSCHUtlFillDgnParams(inst, dgn, dgnType)
5624 TRC2(rgSCHUtlFillDgnParams)
5628 case LRG_USTA_DGNVAL_MEM:
5629 dgn->type = (U8) LRG_USTA_DGNVAL_MEM;
5630 dgn->u.mem.region = rgSchCb[inst].rgSchInit.region;
5631 dgn->u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5639 } /* end of rgSCHUtlFillDgnParams */
5641 /***********************************************************
5643 * Func : rgSCHUtlGetPstToLyr
5645 * Desc : Utility Function to get the pst structure to post a message to MAC
5651 * Notes: This function should be called while sending a msg from
5652 * scheduler instance to MAC
5656 **********************************************************/
5658 PUBLIC Void rgSCHUtlGetPstToLyr
5665 PUBLIC Void rgSCHUtlGetPstToLyr (pst, schCb, macInst)
5671 TRC2(rgSCHUtlGetPstToLyr);
5673 /* Only the needed params are filled */
5674 pst->region = schCb->rgSchInit.region;
5675 pst->pool = schCb->rgSchInit.pool;
5676 pst->srcInst = schCb->rgSchInit.inst+SCH_INST_START;
5677 pst->srcProcId = schCb->rgSchInit.procId;
5678 pst->dstProcId = schCb->rgSchInit.procId;
5680 pst->dstInst = macInst;
5681 pst->dstEnt = ENTRG;
5682 pst->srcEnt = ENTRG;
5684 pst->prior = PRIOR0;
5686 pst->route = RTESPEC;
5689 } /* end of rgSCHUtlGetPstToLyr */
5691 /** @brief This function fills in the common lc information to be sent to MAC
5695 * Function: rgSCHUtlFillRgInfCmnLcInfo
5696 * @param RgSchDlSf *sf,
5697 * @param RgInfSfAlloc *sfAlloc,
5698 * @param CmLteLcId lcId,
5699 * @param Bool sendInd
5706 PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo
5709 RgInfSfAlloc *sfAlloc,
5714 PUBLIC S16 rgSCHUtlFillRgInfCmnLcInfo(sf, sfAlloc, lcId, sendInd)
5716 RgInfSfAlloc *sfAlloc;
5721 TRC2(rgSCHUtlFillRgInfCmnLcInfo);
5723 if((sf->bch.tbSize)&&
5724 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCH_INFO))
5727 sfAlloc->cmnLcInfo.bchInfo.lcId = lcId;
5729 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCH_INFO;
5731 else if((sf->bcch.pdcch != NULLP)&&
5732 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCCH_INFO))
5734 sfAlloc->cmnLcInfo.bcchInfo.rnti = RGSCH_SI_RNTI;
5735 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.bcchInfo.dciInfo),
5736 &(sf->bcch.pdcch->dci));
5738 sfAlloc->cmnLcInfo.bcchInfo.lcId = lcId;
5739 sfAlloc->cmnLcInfo.bcchInfo.sndStatInd = sendInd;
5741 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCCH_INFO;
5743 else if((sf->pcch.pdcch != NULLP) &&
5744 !(sfAlloc->cmnLcInfo.bitMask & RGINF_PCCH_INFO))
5746 sfAlloc->cmnLcInfo.pcchInfo.rnti = RGSCH_P_RNTI;
5747 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.pcchInfo.dciInfo),
5748 &(sf->pcch.pdcch->dci));
5749 sfAlloc->cmnLcInfo.pcchInfo.lcId = lcId;
5750 sfAlloc->cmnLcInfo.bitMask |= RGINF_PCCH_INFO;
5755 /** @brief This function fills in the RAR information to be sent to MAC
5759 * Function: rgSCHUtlFillRgInfRarInfo
5761 * @param RgSchCellCb *cell
5762 * @param RgSchDlSf *sf
5763 * @param RgInfSfAlloc *sfAlloc
5769 PUBLIC S16 rgSCHUtlFillRgInfRarInfo
5772 RgInfSfAlloc *sfAlloc,
5776 PUBLIC S16 rgSCHUtlFillRgInfRarInfo(sf, sfAlloc, cell)
5778 RgInfSfAlloc *sfAlloc;
5787 RgInfRaRntiInfo *raRntiAlloc;
5789 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5791 TRC2(rgSCHUtlFillRgInfRarInfo);
5794 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
5796 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
5799 for(idx =0; idx < noRaRsps; idx++)
5801 if (sf->raRsp[idx].pdcch == NULLP)
5803 /* No further raResp Allocations. */
5806 /* Added Dl TB count for RACH Response transmission*/
5808 cell->dlUlTbCnt.tbTransDlTotalCnt++;
5810 raRntiAlloc = &(sfAlloc->rarInfo.raRntiInfo[idx]);
5811 raRntiAlloc->raRnti = sf->raRsp[idx].raRnti;
5812 raRntiAlloc->schdTbSz = sf->raRsp[idx].tbSz;
5813 raRntiAlloc->numCrnti = 0;
5814 rgSCHUtlFillPdschDciInfo(&(raRntiAlloc->dciInfo),
5815 &(sf->raRsp[idx].pdcch->dci));
5816 /* RACHO : fill backoff indicator information */
5817 raRntiAlloc->backOffInd = sf->raRsp[idx].backOffInd;
5819 /* Fill for contention free UEs*/
5820 lnkLst = &(sf->raRsp[idx].contFreeUeLst);
5821 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5824 ue = (RgSchUeCb *)tmp->node;
5826 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = ue->ueId;
5827 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = TRUE;
5828 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = ue->ul.rarGrnt.rapId;
5829 #ifndef MAC_5GTF_UPDATE
5830 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5832 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit =
5833 ue->ul.rarGrnt.cqiReqBit;
5835 /* SHASHAHNK ADD RIV CALC */
5836 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5837 ue->ul.rarGrnt.rbStart;
5838 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5839 ue->ul.rarGrnt.numRb;
5840 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5842 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5843 ue->ul.rarGrnt.iMcsCrnt;
5844 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta = ue->ul.rarGrnt.ta;
5845 raRntiAlloc->numCrnti++;
5846 cmLListDelFrm(lnkLst, &ue->ul.rarGrnt.raRspLnk);
5847 ue->ul.rarGrnt.raRspLnk.node = (PTR)NULLP;
5849 /* Fill for contention based UEs*/
5850 lnkLst = &(sf->raRsp[idx].raRspLst);
5852 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5854 while((NULLP != tmp) && ((RgSchRaCb *)tmp->node != NULLP))
5856 raCb = (RgSchRaCb *)tmp->node;
5858 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = raCb->tmpCrnti;
5859 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = FALSE;
5860 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = raCb->rapId;
5861 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.pres = TRUE;
5862 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.val = raCb->ta.val;
5863 #ifndef MAC_5GTF_UPDATE
5864 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5866 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = FALSE;
5868 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5869 raCb->msg3Grnt.rbStart;
5870 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5871 raCb->msg3Grnt.numRb;
5872 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5874 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5875 raCb->msg3Grnt.iMcsCrnt;
5876 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.delayBit =
5877 raCb->msg3Grnt.delayBit;
5878 /* For initial attaching UEs Aperiodic CQI need not be triggered */
5879 raRntiAlloc->numCrnti++;
5880 /* Search the next node */
5881 CM_LLIST_NEXT_NODE(lnkLst, tmp);
5884 sfAlloc->rarInfo.numRaRntis = idx;
5885 /* ccpu00132314-ADD-Update the tx power allocation info
5886 TODO-Need to add a check for max tx power per symbol */
5887 sfAlloc->rarInfo.txPwrOffset = cellDl->rarTxPwrOffset;
5890 } /* end of rgSCHUtlFillRgInfRarInfo */
5892 /** @brief This function fills in the pdsch data related allocation Info
5893 * from the pdcch DCI info.
5898 * Function: rgSCHUtlFillPdschDciInfo
5901 * - Depending upon the DCI Format, fill the appropriate fields.
5903 * @param [out] TfuPdschDciInfo *pdschDci
5904 * @param [in] TfuDciInfo *pdcchDci
5910 PUBLIC S16 rgSCHUtlFillPdschDciInfo
5912 TfuPdschDciInfo *pdsch,
5913 TfuDciInfo *pdcchDci
5916 PUBLIC S16 rgSCHUtlFillPdschDciInfo(pdsch, pdcchDci)
5917 TfuPdschDciInfo *pdsch;
5918 TfuDciInfo *pdcchDci;
5921 TRC2(rgSCHUtlFillPdschDciInfo)
5926 pdsch->format = pdcchDci->dciFormat;
5927 switch(pdcchDci->dciFormat)
5929 case TFU_DCI_FORMAT_1:
5930 pdsch->u.format1AllocInfo = pdcchDci->u.format1Info.allocInfo;
5932 case TFU_DCI_FORMAT_1A:
5933 if (pdcchDci->u.format1aInfo.isPdcchOrder == FALSE)
5935 pdsch->u.format1aAllocInfo = pdcchDci->u.format1aInfo.t.pdschInfo.allocInfo;
5938 case TFU_DCI_FORMAT_1B:
5939 pdsch->u.format1bAllocInfo = pdcchDci->u.format1bInfo.allocInfo;
5941 case TFU_DCI_FORMAT_1C:
5942 pdsch->u.format1cAllocInfo = pdcchDci->u.format1cInfo;
5944 case TFU_DCI_FORMAT_1D:
5945 pdsch->u.format1dAllocInfo = pdcchDci->u.format1dInfo.allocInfo;
5947 case TFU_DCI_FORMAT_2:
5948 pdsch->u.format2AllocInfo = pdcchDci->u.format2Info.allocInfo;
5950 case TFU_DCI_FORMAT_2A:
5951 pdsch->u.format2AAllocInfo = pdcchDci->u.format2AInfo.allocInfo;
5954 case TFU_DCI_FORMAT_B1:
5955 pdsch->u.formatB1Info = pdcchDci->u.formatB1Info;
5957 case TFU_DCI_FORMAT_B2:
5958 pdsch->u.formatB2Info = pdcchDci->u.formatB2Info;
5963 ret = rgSCHEmtcUtlFillPdschDciInfo(pdsch, pdcchDci);
5975 /* LTE_ADV_FLAG_REMOVED_START */
5977 * @brief This function resets temporary variables in Pool
5980 * Function: rgSchSFRResetPoolVariables
5982 * Invoked by: rgSCHSFRUtlTotalPoolInit
5984 * @param[in] RgSchCellCb* cell
5985 * @param[in] RgSubFrm* subFrm
5990 PUBLIC Void rgSchDSFRPwrCheck
5993 Bool *isAllUePwrHigh
5996 PRIVATE Void rgSchDSFRPwrCheck(sf, isAllUePwrHigh)
5998 Bool *isAllUePwrHigh;
6002 RgSchSFRPoolInfo *sfrCCPool;
6007 TRC2(rgSchDSFRPwrCheck);
6009 l = &sf->sfrTotalPoolInfo.ccPool;
6010 n = cmLListFirst(l);
6013 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
6014 if((sfrCCPool->poolstartRB == sfrCCPool->pwrHiCCRange.startRb) &&
6015 (sfrCCPool->poolendRB == sfrCCPool->pwrHiCCRange.endRb))
6022 *isAllUePwrHigh = TRUE;
6029 /* LTE_ADV_FLAG_REMOVED_END */
6030 /***********************************************************
6032 * Func : rgSCHUtlFillRgInfTbInfo
6034 * Desc : Utility Function to fill the allocation info of each Tb
6040 * Notes: This function should be called while sending a msg from
6041 * scheduler instance to MAC
6045 **********************************************************/
6047 PRIVATE Void rgSCHUtlFillRgInfTbInfo
6049 RgSchDlHqProcCb *hqP,
6050 RgInfUeAlloc *allocInfo,
6054 PRIVATE Void rgSCHUtlFillRgInfTbInfo (hqP, allocInfo, cell)
6055 RgSchDlHqProcCb *hqP;
6056 RgInfUeAlloc *allocInfo;
6062 RgInfUeTbInfo *tbInfo;
6064 /* LTE_ADV_FLAG_REMOVED_START */
6066 PRIVATE U32 tmpCnt = 0;
6067 Bool isAllUePwrHigh = FALSE;
6069 /* LTE_ADV_FLAG_REMOVED_END */
6070 RgSchDlLcCb *dlLcCb = NULLP;
6079 CmLteTimingInfo frm;
6081 /* Get Downlink slot */
6082 frm = cell->crntTime;
6083 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
6084 sf = rgSCHUtlSubFrmGet(cell, frm);
6085 /* Setting of fillCtrlPdu flag
6086 If both P-cell and S-cell are present,
6087 make TRUE for P-cell and FALSE for all s-cells
6088 For all other cases set TRUE */
6090 if ((rgSchCb[cell->instIdx].genCfg.forceCntrlSrbBoOnPCel) &&
6091 !RG_SCH_CMN_IS_PCELL_HQP(hqP))
6093 allocInfo->fillCtrlPdu = FALSE;
6097 allocInfo->fillCtrlPdu = TRUE;
6101 allocInfo->tbStrtIdx = -1;
6105 allocInfo->tbReqInfo.sCellHqPId = 0xff;
6106 rgSCHLaaHndlFillRgInfTbInfo(cell, hqP, allocInfo);
6109 /*TODO:REEMA: Check and fill the isRetx */
6110 for(tbCnt = 0; tbCnt < 2; tbCnt++)
6112 RgSchUeCb *ue = NULLP;
6113 /*Changed as a result of CR timer*/
6114 if ((hqP->hqE->ue != NULLP)/* &&
6115 ((hqP->tbInfo[tbCnt].lchSchdData[0].lcId != 0) || \
6116 (hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF))*/)
6119 allocInfo->rnti = ue->ueId;
6120 allocInfo->doa = hqP->hqE->ue->mimoInfo.doa;
6121 allocInfo->txMode = (TfuTxMode)(hqP->hqE->ue->mimoInfo.txMode);
6122 allocInfo->puschRptUsd = hqP->hqE->ue->mimoInfo.puschFdbkVld;
6123 allocInfo->puschPmiInfo = hqP->hqE->ue->mimoInfo.puschPmiInfo;
6124 if(hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF)
6126 hqP->tbInfo[tbCnt].taSnt = TRUE;
6129 if (RG_SCH_IS_PAPRSNT(ue,hqP->hqE->cell))
6131 /*update pA value */
6132 allocInfo->pa = (RG_SCH_CMN_GET_PA(ue,hqP->hqE->cell)).val;
6136 /* LTE_ADV_FLAG_REMOVED_START */
6137 /* If ABS is enabled, calculate resource used */
6138 if((0 == tbCnt) && (RGR_ENABLE == ue->cell->lteAdvCb.absCfg.status))
6140 /* For Macro count number resource used in Non-ABS SF */
6141 if(RGR_ABS_MUTE == ue->cell->lteAdvCb.absCfg.absPatternType)
6143 if(RG_SCH_ABS_ENABLED_NONABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6145 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6146 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6149 /* For pico count number resource used in ABS SF for ABS UE */
6150 else if(RGR_ABS_TRANSMIT == ue->cell->lteAdvCb.absCfg.absPatternType)
6152 if(RG_SCH_ABS_ENABLED_ABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6154 if(TRUE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe)
6156 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6157 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6164 /*if SFR is enabled*/
6165 allocInfo->isEnbSFR = (U8)RG_SCH_CMN_IS_SFR_ENB(ue->cell); /* KW fix for LTE_ADV */
6166 if((ue->cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) &&
6167 (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == FALSE))
6169 rgSchDSFRPwrCheck(sf, &isAllUePwrHigh);
6173 allocInfo->pa = (U8)ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; /* KW fix for LTE_ADV */
6174 if(tmpCnt++ == 100000)
6176 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6177 "DSFR::ll UEs can go HIGH, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6183 if (allocInfo->isEnbSFR)
6185 /*Update pA to Plow if it is cell-centred ,else pA will be pHigh*/
6186 if (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == TRUE)
6188 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6189 if(tmpCnt++ == 100000)
6191 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6192 "SFR::UE is CELL EDGE, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6199 if(TRUE == ue->lteAdvUeCb.isCCUePHigh)
6201 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6202 ue->lteAdvUeCb.isCCUePHigh = FALSE;
6206 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pLow;
6207 if(tmpCnt++ == 100000)
6209 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6210 "SFR::UE is CELL CENTRE, PLow(%d) for UE(%d)\n",allocInfo->pa, ue->ueId);
6217 /* LTE_ADV_FLAG_REMOVED_END */
6225 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
6228 allocInfo->pdcchRnti = hqP->hqE->raCb->tmpCrnti;
6230 allocInfo->rnti = hqP->hqE->raCb->tmpCrnti;
6232 /*ccpu00132314-ADD-Use a default pA value
6234 allocInfo->pa = cellDl->msg4pAVal;
6238 /* If TB Is scheduled for this SF */
6239 if(hqP->tbInfo[tbCnt].state == HQ_TB_WAITING)
6241 if (allocInfo->tbStrtIdx == -1){
6242 allocInfo->tbStrtIdx = tbCnt;
6244 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6245 &(hqP->pdcch->dci));
6249 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6250 &(hqP->pdcch->dci));
6252 else if ((ue) && (ue->dl.spsOccPdcch.rnti == ue->spsRnti))
6254 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6255 &(ue->dl.spsOccPdcch.dci));
6257 #endif /* ifndef LTEMAC_SPS */
6262 allocInfo->pdcchRnti = hqP->pdcch->rnti;
6266 allocInfo->pdcchRnti = ue->spsRnti;
6269 tbInfo = &(allocInfo->tbInfo[tbCnt]);
6270 allocInfo->nmbOfTBs++;
6271 allocInfo->hqProcId = hqP->procId;
6272 allocInfo->tbInfo[tbCnt].schdTbSz = hqP->tbInfo[tbCnt].tbSz;
6274 tbInfo->disTb = FALSE;
6275 if(!(hqP->tbInfo[tbCnt].txCntr))
6278 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6279 rgSCHLaaSCellEnabled(cell))))
6282 hqP->tbInfo[tbCnt].txCntr++;
6284 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6286 tbInfo->schdDat[idx].lcId =\
6287 hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6288 tbInfo->schdDat[idx].numBytes =\
6289 hqP->tbInfo[tbCnt].lchSchdData[idx].schdData;
6292 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6295 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6298 RG_SCH_CMN_DL_GET_HDR_EST(dlLcCb, rlcHdrEstmt);
6299 /* Update the totalBo with the scheduled bo */
6300 (hqP->hqE->ue->totalBo <= tbInfo->schdDat[idx].numBytes - rlcHdrEstmt)?\
6301 (hqP->hqE->ue->totalBo = 0):\
6302 (hqP->hqE->ue->totalBo -= tbInfo->schdDat[idx].numBytes-rlcHdrEstmt);
6306 prbUsed = ((hqP->tbInfo[tbCnt].\
6307 lchSchdData[idx].schdData *
6308 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6309 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6310 dlLcCb->qciCb->dlPrbCount += prbUsed;
6311 if(dlLcCb->qciCb->qci > 0)
6313 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6315 #endif /* RRM_RBC_Y */
6318 //if(!(hqP->hqE->ue->pfsStats.lcStats[lcId-1].isLcCntSet))
6322 if (hqP->hqE->ue->cell == hqP->hqE->cell)
6324 idx = RGSCH_PCELL_INDEX;
6328 idx = RG_SCH_GET_SCELL_INDEX((hqP->hqE->ue), (hqP->hqE->cell));
6330 hqP->hqE->ue->pfsStats.lcStats[lcId-1].ueSchdOcc[idx]++;
6331 hqP->hqE->ue->pfsStats.lcStats[lcId-1].perRefresh[ue->pfsStats.lcStats[lcId-1].lastIdx].lcSchdOcc++;
6338 /* Added Dl TB count for SRB/DRB data transmission*/
6340 cell->dlUlTbCnt.tbTransDlTotalCnt++;
6342 tbInfo->ta.pres = hqP->tbInfo[tbCnt].schdTa.pres;
6343 tbInfo->ta.val = hqP->tbInfo[tbCnt].schdTa.val;
6345 tbInfo->sCellActCe = hqP->tbInfo[tbCnt].schdSCellActCe;
6347 tbInfo->numSchLch = hqP->tbInfo[tbCnt].numLch;
6348 if(!(hqP->tbInfo[tbCnt].numLch))
6350 tbInfo->schdDat[tbInfo->numSchLch].numBytes= hqP->tbInfo[tbCnt].tbSz;
6351 /* Fix: If only TA is scheduled, use some dummy LCID */
6352 if (tbInfo->ta.pres)
6353 tbInfo->schdDat[tbInfo->numSchLch].lcId = RG_TA_LCID;
6356 tbInfo->contResCe = hqP->tbInfo[tbCnt].contResCe;
6357 tbInfo->isReTx = FALSE;
6362 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6363 rgSCHLaaSCellEnabled(cell))))
6366 hqP->tbInfo[tbCnt].txCntr++;
6368 tbInfo->isReTx = TRUE;
6370 /* As per 36.314, harq retransmission also considered for
6371 * prb utilization calculation*/
6372 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6377 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6380 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6383 prbUsed = ((hqP->tbInfo[tbCnt].\
6384 lchSchdData[idx].schdData *
6385 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6386 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6387 if(dlLcCb->qciCb->qci > 0)
6389 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6401 rgSCHLaaResetDlHqProcCb(hqP);
6406 /***********************************************************
6408 * Func : rgSCHUtlFillRgInfUeInfo
6410 * Desc : Utility Function to fill the allocation info of Ue
6411 * : MIMO : Filling 2TB's of each UE
6416 * Notes: This function should be called while sending a msg from
6417 * scheduler instance to MAC
6421 **********************************************************/
6424 PUBLIC Void rgSCHUtlFillRgInfUeInfo
6428 CmLListCp *dlDrxInactvTmrLst,
6429 CmLListCp *dlInActvLst,
6430 CmLListCp *ulInActvLst
6433 PUBLIC Void rgSCHUtlFillRgInfUeInfo (sf,cell, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
6437 CmLListCp *dlDrxInactvTmrLst;
6438 CmLListCp *dlInActvLst;
6439 CmLListCp *ulInActvLst;
6442 RgInfSfAlloc *sfAlloc;
6443 CmLListCp *lnkLst; /* lnkLst assignment */
6446 RgSchUeCb *ue = NULLP;
6447 RgInfUeInfo *ueInfo = NULLP;
6448 RgInfUeAlloc *ueAlloc = NULLP;
6449 RgSchDlHqProcCb *hqCb = NULLP;
6451 /* Since Msg4 is sched only on PCELL, use cell arg's sfAllocArr */
6452 sfAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
6453 ueInfo = &(sfAlloc->ueInfo);
6454 ueAlloc = sfAlloc->ueInfo.allocInfo;
6456 lnkLst = &(sf->msg4HqPLst);
6457 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6460 printf("5GTF_ERROR MSG4 Consolidation\n");
6461 hqCb = (RgSchDlHqProcCb *)(tmp->node);
6462 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6464 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], cell);
6470 if((!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) && (ue->isDrxEnabled))
6472 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6473 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6479 lnkLst = &(sf->ueLst);
6480 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6483 #if defined (TENB_STATS) && defined (RG_5GTF)
6484 cell->tenbStats->sch.dl5gtfPdschCons++;
6486 ue = (RgSchUeCb *)(tmp->node);
6487 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6489 hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first;
6492 hqCb = (RgSchDlHqProcCb *)hqPNode->node;
6493 hqPNode = hqPNode->next;
6495 sfAlloc = &(hqCb->hqE->cell->sfAllocArr[hqCb->hqE->cell->crntSfIdx]);
6496 ueInfo = &(sfAlloc->ueInfo);
6497 ueAlloc = sfAlloc->ueInfo.allocInfo;
6499 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes],
6502 if(ue->isDrxEnabled)
6504 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6505 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6510 if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE)
6512 /*If remaining BO is left then increment the count*/
6516 /* Check if trigger for Activation is met or not */
6517 if(rgSCHIsActvReqd(cell, ue))
6520 /*Passing primary cell*/
6521 rgSCHSCellSelectAndActDeAct(ue->cell, ue, RGR_SCELL_ACT);
6526 /*If remaining BO is 0 then reset the count*/
6534 } /* end of rgSCHUtlFillRgInfUeInfo */
6538 /** @brief This function shall update the scheduler with the CEs and data rcvd
6542 * Function: rgSCHUtlUpdSch
6545 * - Collate the information of all the SDUs received and inform the
6546 * scheduler rgSCHDataRcvd
6547 * - Send Data indication to the higher layer with the dedicated data
6548 * (rgUIMSndDedDatInd)
6549 * - Inform scheduler with any MAC CEs if present.
6551 * @param [in] RgCellCb *cellCb
6552 * @param [in] RgUeCb *ueCb
6553 * @param [in] RgMacPdu *pdu
6554 * @param [in] RgSchErrInfo *err
6560 PUBLIC S16 rgSCHUtlUpdSch
6562 RgInfSfDatInd *subfrmInfo,
6563 RgSchCellCb *cellCb,
6569 PUBLIC S16 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err)
6570 RgInfSfDatInd *subfrmInfo;
6571 RgSchCellCb *cellCb;
6579 TRC2(rgSCHUtlUpdSch);
6582 if (RGSCH_UL_SPS_ACT_PRSENT & pdu->ceInfo.bitMask)
6584 /* SPS to be activated due to data on SPS LCG ID*/
6585 rgSCHUtlSpsActInd(cellCb, ueCb, pdu->ceInfo.spsSduSize);
6588 /* TODO : Temp Fix for crash due to UL SDU corruption*/
6589 if (RGSCH_PHR_CE_PRSNT & pdu->ceInfo.bitMask)
6592 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6593 if ((ret = rgSCHUtlUpdPhr(cellCb, ueCb, pdu->ceInfo.ces.phr, err)) != ROK)
6596 /* Note: Order of indication to Sch now is
6597 * 1st Indicate the DataInd info for each LCG's
6598 * 2nd Update the BSR reports received along with data
6599 * this is to make sure the effBsr is updated to the latest BSR
6602 cellCb->sc.apis->rgSCHUpdUeDataIndLcg(cellCb, ueCb, pdu);
6604 #ifndef MAC_5GTF_UPDATE
6605 if (RGSCH_TRUNC_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6607 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6608 /*ccpu00129922 - MOD - Deleted return value
6609 * checking since it returns void*/
6610 rgSCHUtlUpdBsrTrunc (cellCb, ueCb,
6611 (U8)(pdu->ceInfo.ces.bsr.truncBsr >> 6),
6612 (U8)(pdu->ceInfo.ces.bsr.truncBsr & 0x3F), err);
6616 if (RGSCH_SHORT_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6618 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6619 /*ccpu00129922 - MOD - Deleted return value
6620 checking since it returns void*/
6621 rgSCHUtlUpdBsrShort (cellCb, ueCb,
6622 (U8)(pdu->ceInfo.ces.bsr.shortBsr >> 6),
6623 (U8)(pdu->ceInfo.ces.bsr.shortBsr & 0x3F), err);
6627 if (RGSCH_LONG_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6629 if (RGSCH_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6632 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6633 /*ccpu00129922 - MOD - Deleted return value
6634 checking since it returns void*/
6635 rgSCHUtlUpdBsrLong (cellCb, ueCb,
6636 pdu->ceInfo.ces.bsr.longBsr.bs1,
6637 pdu->ceInfo.ces.bsr.longBsr.bs2,
6638 pdu->ceInfo.ces.bsr.longBsr.bs3,
6639 pdu->ceInfo.ces.bsr.longBsr.bs4,
6642 #ifndef MAC_5GTF_UPDATE
6649 } /* end of rgSCHUtlUpdSch */
6652 * @brief Handler for Updating Bo received in StaRsp
6656 * Function : rgSCHUtlAddUeToCcchSduLst
6658 * This function shall be invoked once it receives staRsp on CCCH
6660 * @param[in] RgSchCellCb *cell
6661 * @param[in] RgSchUeCb *ueCb
6666 PUBLIC S16 rgSCHUtlAddUeToCcchSduLst
6672 PUBLIC S16 rgSCHUtlAddUeToCcchSduLst(cell, ueCb)
6677 RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb, cell);
6678 RgSchDlHqProcCb *hqP = (RgSchDlHqProcCb *)ueDl->proc;
6679 TRC2(rgSCHUtlAddUeToCcchSduLst);
6681 /* Temp Guard: For back to back CCCH SDU BO
6682 * twice. Hence an extra guard. If already added to scheduling
6683 * queue or if scheduled and waiting for HQ FDBK, ignore */
6684 if ((ueCb->ccchSduLnk.node) ||
6685 ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
6686 ((hqP != NULLP) && (hqP->hqE->ccchSduProc))))
6688 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unexpected CCCH SDU BO",
6693 ueCb->ccchSduLnk.node = (PTR)(ueCb);
6694 cmLListAdd2Tail(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
6702 * Function : rgSCHUtlUpdtBo
6704 * This function shall be invoked once it receives staRsp on CCCH
6706 * @param[in] RgSchCellCb *cell
6707 * @param[in] RgRguCmnStaRsp *staRsp
6712 PUBLIC S16 rgSCHUtlUpdtBo
6715 RgInfCmnBoRpt *staRsp
6718 PUBLIC S16 rgSCHUtlUpdtBo(cell, staRsp)
6720 RgInfCmnBoRpt *staRsp;
6724 TRC2(rgSCHUtlUpdtBo)
6727 if ((ueCb = rgSCHDbmGetUeCb(cell, staRsp->u.rnti)) == NULLP)
6729 /* Handle Ue fetch failure */
6730 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid UEID:%d",staRsp->u.rnti);
6733 /* Update Bo in ueCb */
6734 ueCb->dlCcchInfo.bo = (U32)(staRsp->bo);
6738 rgSCHUtlAddUeToEmtcCcchSduLst(cell,ueCb);
6743 rgSCHUtlAddUeToCcchSduLst(cell, ueCb);
6747 } /* rgSCHUtlUpdtBo */
6753 * Function : rgSCHUtlHndlCcchBoUpdt
6755 * This function shall fetch the raCb with the given rnti and ask RAM to
6759 * @param[in] RgSchCellCb *cell
6760 * @param[in] RgInfCmnBoRpt *boRpt
6766 PUBLIC S16 rgSCHUtlHndlCcchBoUpdt
6769 RgInfCmnBoRpt *boRpt
6772 PUBLIC S16 rgSCHUtlHndlCcchBoUpdt(cell, boRpt)
6774 RgInfCmnBoRpt *boRpt;
6780 TRC2(rgSCHUtlHndlCcchBoUpdt);
6782 if ((raCb = rgSCHDbmGetRaCb(cell, boRpt->u.rnti)) == NULLP)
6785 /* CR timer implementation changes*/
6786 /*If no raCb, schedule ueCb, ueCb is extracted in rgSCHUtlUpdtBo*/
6787 RETVALUE(rgSCHUtlUpdtBo(cell, boRpt));
6789 /* Handle RaCb fetch failure */
6790 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6791 "Invalid RNTI:%d to fetch raCb",boRpt->u.rnti);
6798 /*Fix: If RaCb exists, then MSG4 is not completed yet*/
6799 /*Check if guard timer has expired, if not CR CE + CCCH SDU will be scheduled*/
6800 if((raCb->contResTmrLnk.node != NULLP) && \
6801 (raCb->schdLnk.node == NULLP) && (raCb->dlHqE->msg4Proc == NULLP))
6804 /*if contention resolution timer left ,Stop the Contention Resolution Guard Timer ,
6805 add in toBeSchduled list and update the Bo */
6806 if(TRUE == raCb->isEmtcRaCb)
6808 rgSCHRamEmtcUpdtBo(cell, raCb, boRpt);
6813 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
6814 raCb->contResTmrLnk.node=NULLP;
6815 rgSCHRamUpdtBo(cell, raCb, boRpt);
6820 /*Fix:Guard timer has expired */
6821 /*Update the BO in UE CB but dont add it to the scheduling list.
6822 *Should be added to the list after MSG4 completion*/
6823 if ((ueCb = rgSCHDbmGetUeCb(cell, boRpt->u.rnti)) == NULLP)
6825 /* Handle Ue fetch failure */
6826 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RNTI:%d",boRpt->u.rnti);
6829 /* Update Bo in ueCb */
6830 ueCb->dlCcchInfo.bo = (U32)(boRpt->bo);
6834 rgSCHRamUpdtBo(cell, raCb, boRpt);
6838 } /* rgSCHUtlHndlCcchBoUpdt */
6841 * @brief Validates BO received for BCCH or PCCH.
6845 * Function : rgSCHUtlGetAllwdCchTbSz
6847 * This function shall return the tbSz equal to or
6848 * the nearest greater value for a given bo.
6849 * If no such value found return -1. The nPrb value is
6854 * @param[out] U8 *nPrb
6860 PUBLIC S32 rgSCHUtlGetAllwdCchTbSz
6867 PUBLIC S32 rgSCHUtlGetAllwdCchTbSz(bo, nPrb, mcs)
6877 TRC2(rgSCHUtlGetAllwdCchTbSz);
6879 for (lt = 0, rt = 43; lt <= rt;)
6882 if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz == bo)
6884 *nPrb = rgSchUtlBcchPcchTbSzTbl[cn].rbIndex;
6885 *mcs = rgSchUtlBcchPcchTbSzTbl[cn].mcs;
6886 RETVALUE(rgSchUtlBcchPcchTbSzTbl[cn].tbSz);
6888 else if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz < bo)
6897 *nPrb = rgSchUtlBcchPcchTbSzTbl[lt].rbIndex;
6898 *mcs = rgSchUtlBcchPcchTbSzTbl[lt].mcs;
6899 RETVALUE(rgSchUtlBcchPcchTbSzTbl[lt].tbSz);
6903 * @brief Handler for BO Updt received for BCCH or PCCH.
6907 * Function : rgSCHUtlHndlBcchPcchBoUpdt
6909 * This function shall store the buffer and time to transmit in lcCb
6912 * @param[in] RgSchCellCb *cell
6913 * @param[in] RgInfCmnBoRpt *boRpt
6919 PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt
6922 RgInfCmnBoRpt *boUpdt
6925 PUBLIC S16 rgSCHUtlHndlBcchPcchBoUpdt(cell, boUpdt)
6927 RgInfCmnBoRpt *boUpdt;
6930 RgSchClcDlLcCb *dlLc;
6931 RgSchClcBoRpt *boRpt;
6932 Inst inst = cell->instIdx;
6936 TRC2(rgSCHUtlHndlBcchPcchBoUpdt);
6938 dlLc = rgSCHDbmGetBcchOnBch(cell);
6941 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6942 "No Logical Channel dlLc is NULLP for RNTI:%d LCID:%d",boUpdt->u.rnti,boUpdt->lcId);
6945 if (boUpdt->lcId != dlLc->lcId)
6947 /* Added for dropping paging Message*/
6949 if ((rgSCHChkBoUpdate(cell,boUpdt))== ROK) /* Checking if received BO falls within the window of 5120 slots*/
6951 if (rgSCHUtlGetAllwdCchTbSz(boUpdt->bo*8, &nPrb, &mcs)
6954 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"[%ld]BO: does not match any "
6955 "valid TB Size RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6958 }/*end of rgSCHChkBoUpdate*/
6964 if ((dlLc = rgSCHDbmGetCmnLcCb(cell, boUpdt->lcId)) == NULLP)
6966 /* Handle lcCb fetch failure */
6967 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6968 "LCID:%d Invalid for RNTI:%d",boUpdt->lcId,boUpdt->u.rnti);
6971 if (((rgSCHUtlAllocSBuf(inst, (Data **)(&boRpt), sizeof(RgSchClcBoRpt))) ==RFAILED) ||
6974 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, "Allocation of common bo %dreport "
6975 "failed RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6979 boRpt->bo = boUpdt->bo;
6981 boRpt->timeToTx = boUpdt->u.timeToTx;
6984 if(cell->emtcEnable)
6986 boRpt->emtcDIReason = boUpdt->emtcDIReason;
6987 boRpt->pnb = boUpdt->pnb;
6990 RG_SCH_ADD_TO_CRNT_TIME(boRpt->timeToTx,
6991 boRpt->maxTimeToTx, cell->siCfg.siWinSize)
6992 if((NULLP != dlLc) && (dlLc->si))
6994 boRpt->retxCnt = cell->siCfg.retxCnt;
7000 rgSCHDbmInsCmnLcBoRpt(dlLc, boRpt);
7003 } /* rgSCHUtlHndlBcchPcchBoUpdt */
7006 * @brief API for sending bind confirm from Scheduler instance to RRM
7010 * Function: rgSCHUtlRgrBndCfm
7012 * This API is invoked to send bind confirm from Scheduler instance to RRM.
7013 * This API fills in Pst structure and SAP Ids and invokes
7014 * bind confirm API towards RRM.
7016 * @param[in] SuId suId
7017 * @param[in] U8 status
7023 PUBLIC S16 rgSCHUtlRgrBndCfm
7030 PUBLIC S16 rgSCHUtlRgrBndCfm(instId, suId, status)
7038 TRC2(rgSCHUtlRgrBndCfm)
7041 ret = RgUiRgrBndCfm(&rgSchCb[instId].rgrSap[suId].sapCfg.sapPst, rgSchCb[instId].rgrSap[suId].sapCfg.suId, status);
7044 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrBndCfm: RgUiRgrBndCfm Failed ");
7048 } /* rgSCHUtlRgrBndCfm*/
7051 * @brief API for sending bind confirm from Scheduler instance to RRM via RGM
7056 * Function: rgSCHUtlRgmBndCfm
7058 * This API is invoked to send bind confirm from Scheduler instance to RRM.
7059 * This API fills in Pst structure and SAP Ids and invokes
7061 * @param[in] SuId suId
7062 * @param[in] U8 status
7068 PUBLIC S16 rgSCHUtlRgmBndCfm
7075 PUBLIC S16 rgSCHUtlRgmBndCfm(instId, suId, status)
7083 TRC2(rgSCHUtlRgmBndCfm)
7086 ret = RgUiRgmBndCfm(&rgSchCb[instId].rgmSap[suId].sapCfg.sapPst, rgSchCb[instId].rgmSap[suId].sapCfg.suId, status);
7089 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgmBndCfm: RgUiRgrBndCfm Failed ");
7093 } /* rgSCHUtlRgmBndCfm*/
7098 * @brief API for sending configuration confirm from Scheduler to DU APP
7102 * Function: schSendCfgCfm
7104 * This API is invoked to send configuration confirm from Scheduler to DU
7107 * @param[in] Pst pst
7108 * @param[in] RgrCfgTransId transId
7109 * @param[in] U8 status
7115 PUBLIC S16 schSendCfgCfm
7119 RgrCfgTransId transId,
7123 PUBLIC S16 schSendCfgCfm(reg, pool, transId, status)
7126 RgrCfgTransId transId;
7134 cmMemset((U8 *)(&cfmPst), 0, sizeof(Pst));
7136 cfmPst.srcEnt = (Ent)ENTDUAPP;
7137 cfmPst.srcInst = (Inst) 0;
7138 cfmPst.srcProcId = SFndProcId();
7139 cfmPst.dstEnt = (Ent)ENTRG;
7140 cfmPst.dstInst = (Inst) 0;
7141 cfmPst.dstProcId = SFndProcId();
7142 cfmPst.selector = RGR_SEL_LC;
7143 cfmPst.region = reg;
7146 if(RgUiRgrCfgCfm(&cfmPst,transId, status) != ROK)
7148 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"schSendCfgCfm: RgUiRgrCfgCfm Failed");
7149 printf("\nschSendCfgCfm: RgUiRgrCfgCfm Failed ");
7153 } /* schSendCfgCfm*/
7156 * @brief API for sending TTI indication from Scheduler to RRM.
7160 * Function: rgSCHUtlRgrTtiInd
7162 * This API is invoked to send TTI indication from Scheduler instance to RRM.
7163 * This API fills in Pst structure and RgrTtiIndInfo
7165 * @param[in] cell RgSchCellCb
7166 * @param[in] CmLteTimingInfo status
7172 PUBLIC S16 rgSCHUtlRgrTtiInd
7175 RgrTtiIndInfo *rgrTti
7178 PUBLIC S16 rgSCHUtlRgrTtiInd(cell, rgrTti)
7180 RgrTtiIndInfo *rgrTti;
7184 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
7186 extern Bool g_usettitmr;
7187 extern Void mtTmrHdlrPublic(void);
7190 TRC2(rgSCHUtlRgrTtiInd)
7193 rgrSap = cell->rgrSap;
7194 if (rgrSap->sapSta.sapState != LRG_BND)
7196 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
7197 "rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ",
7198 rgrSap->sapSta.sapState);
7201 RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst),
7202 cell->rgrSap->sapCfg.suId, rgrTti);
7210 } /* rgSCHUtlRgrTtiInd*/
7212 /** @brief This function is called by rgMacSchSfRecpInd. This function invokes the
7213 * scheduler with the information of the received Data and any Control Elements
7221 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
7223 * - If UE exists then update the Schduler with any MAC CEs if present.
7224 * - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3
7226 * @param [in] RgSchCellCb *cellCb
7227 * @param [in] RgSchUeCb *ueCb
7228 * @param [in] CmLteRnti rnti
7229 * @param [in] RgMacPdu *pdu
7230 * @param [in] RgSchErrInfo *err
7237 PUBLIC S16 rgSCHUtlProcMsg3
7239 RgInfSfDatInd *subfrmInfo,
7240 RgSchCellCb *cellCb,
7247 PUBLIC S16 rgSCHUtlProcMsg3 (subfrmInfo, cellCb, ueCb, rnti, pdu, err)
7248 RgInfSfDatInd *subfrmInfo;
7249 RgSchCellCb *cellCb;
7259 TRC2(rgSCHUtlProcMsg3)
7262 /* must have an raCb for this case */
7263 raCb = rgSCHDbmGetRaCb (cellCb, rnti);
7266 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, "RNTI:%d Received MSG3, unable to "
7271 /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that
7272 * effBsr of current case only will be considered in scheduling of ContResLst*/
7273 ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err);
7276 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Processing failed in the RAM "
7280 /* if ueCb is present */
7283 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err);
7289 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7290 * scheduler with the information of the received Data.
7294 * Function: rgSCHUtlSpsRelInd
7299 * @param [in] RgSchCellCb *cellCb
7300 * @param [in] RgSchUeCb *ueCb
7301 * @param [in] Bool *isExplRel
7308 PUBLIC S16 rgSCHUtlSpsRelInd
7310 RgSchCellCb *cellCb,
7315 PUBLIC S16 rgSCHUtlSpsRelInd (cellCb, ueCb, isExplRel)
7316 RgSchCellCb *cellCb;
7321 TRC2(rgSCHUtlSpsRelInd);
7322 cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel);
7324 } /* end of rgSCHUtlSpsRelInd */
7327 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7328 * scheduler with the information of the received Data.
7332 * Function: rgSCHUtlSpsActInd
7337 * @param [in] RgSchCellCb *cellCb
7338 * @param [in] RgSchUeCb *ueCb
7339 * @param [in] U16 spsSduSize
7346 PUBLIC S16 rgSCHUtlSpsActInd
7348 RgSchCellCb *cellCb,
7353 PUBLIC S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize)
7354 RgSchCellCb *cellCb;
7359 TRC2(rgSCHUtlSpsActInd);
7360 cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize);
7362 } /* end of rgSCHUtlSpsActInd */
7365 #endif /* LTEMAC_SPS */
7369 * @brief This API is invoked to send uplink group power control request to PHY.
7373 * Function : rgSCHUtlTfuGrpPwrCntrlReq
7375 * This API is invoked to send uplink group power control request to PHY.
7376 * It fills in the Pst structure, spId value and invokes group power
7377 * control request primitive at TFU.
7379 * @param[in] TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7385 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq
7389 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7392 PUBLIC S16 rgSCHUtlTfuGrpPwrCntrlReq(inst, sapId, grpPwrCntrlReq)
7395 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq;
7399 RgSchLowSapCb *tfuSap;
7402 TRC2(rgSCHUtlTfuGrpPwrCntrlReq);
7404 /* Get the lower SAP control block from the layer control block. */
7405 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7406 if (tfuSap->sapSta.sapState != LRG_BND)
7408 RLOG_ARG1(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7409 "rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState);
7412 cmMemcpy ((U8*)&pst, (U8*)&(tfuSap->sapCfg.sapPst), sizeof(Pst));
7413 if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK)
7415 RLOG_ARG0(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7416 "rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed");
7419 } /* rgSCHUtlTfuGrpPwrCntrlReq */
7423 * @brief This API is invoked to send Control Info to PHY.
7427 * Function : rgSCHUtlTfuCntrlReq
7429 * This API is invoked to send Control Info to PHY. It
7430 * fills in the Pst structure, spId value and invokes Cntrl
7431 * request primitive at TFU.
7433 * @param[in] TfuCntrlReqInfo *cntrlReq
7439 PUBLIC S16 rgSCHUtlTfuCntrlReq
7443 TfuCntrlReqInfo *cntrlReq
7446 PUBLIC S16 rgSCHUtlTfuCntrlReq(inst, sapId, cntrlReq)
7449 TfuCntrlReqInfo *cntrlReq;
7453 RgSchLowSapCb *tfuSap;
7455 TRC2(rgSCHUtlTfuCntrlReq)
7457 /* Get the lower SAP control block from the layer control block. */
7458 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7461 if (tfuSap->sapSta.sapState != LRG_BND)
7463 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Lower SAP not bound (%d) ",
7464 tfuSap->sapSta.sapState);
7465 RGSCH_FREE_MEM(cntrlReq);
7470 /* Using local variable for pst is unnecessary - for optimization */
7471 if((ret = RgLiTfuCntrlReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7474 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Call to RgLiTfuCntrlReq() failed");
7477 } /* rgSCHUtlTfuCntrlReq*/
7480 /* FOR ACK NACK REP */
7483 * @brief This API is invoked to tell the DL Scheduler to add the UE back into
7484 * its scheduling queues.
7488 * Function : rgSCHUtlDlActvtUe
7490 * This API is invoked from Measurement gap moduled.
7492 * @param[in] RgSchCellCb *cell
7493 * @param[in] RgSchUeCb *ueCb
7500 PUBLIC S16 rgSCHUtlDlActvtUe
7506 PUBLIC S16 rgSCHUtlDlActvtUe(cell, ue)
7511 TRC2(rgSCHUtlDlActvtUe);
7512 cell->sc.apis->rgSCHActvtDlUe(cell, ue);
7517 * @brief This API is invoked to tell the UL Scheduler to add the UE back into
7518 * its scheduling queues.
7522 * Function : rgSCHUtlUlActvtUe
7524 * This API is invoked from Measurement gap moduled.
7526 * @param[in] RgSchCellCb *cell
7527 * @param[in] RgSchUeCb *ueCb
7534 PUBLIC S16 rgSCHUtlUlActvtUe
7540 PUBLIC S16 rgSCHUtlUlActvtUe(cell, ue)
7545 TRC2(rgSCHUtlUlActvtUe);
7546 cell->sc.apis->rgSCHActvtUlUe(cell, ue);
7551 * @brief This API is invoked to send Reception Request Info to PHY.
7555 * Function : rgSCHUtlTfuRecpReq
7557 * This API is invoked to send Reception Request Info to PHY. It
7558 * fills in the Pst structure, spId value and invokes Reception
7559 * request primitive at TFU.
7561 * @param[in] TfuRecpReqInfo *recpReq
7567 PUBLIC S16 rgSCHUtlTfuRecpReq
7571 TfuRecpReqInfo *recpReq
7574 PUBLIC S16 rgSCHUtlTfuRecpReq(inst, sapId, recpReq)
7577 TfuRecpReqInfo *recpReq;
7581 RgSchLowSapCb *tfuSap;
7583 TRC2(rgSCHUtlTfuRecpReq)
7585 /* Get the lower SAP control block from the layer control block. */
7586 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7589 if (tfuSap->sapSta.sapState != LRG_BND)
7591 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Lower SAP not bound (%d) ",
7592 tfuSap->sapSta.sapState);
7593 RGSCH_FREE_MEM(recpReq);
7598 /* Using local variable for pst is unnecessary - for optimization */
7599 if((ret = RgLiTfuRecpReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7602 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Call to RgLiTfuRecpReq() failed");
7605 } /* rgSCHUtlTfuRecpReq */
7607 /** @brief This function Validates the SAP information received along with the
7608 * primitive from the lower layer.
7610 * Function: rgSCHUtlValidateTfuSap
7612 * Validates SAP information.
7613 * @param suId The SAP Id
7619 PUBLIC S16 rgSCHUtlValidateTfuSap
7625 PUBLIC S16 rgSCHUtlValidateTfuSap(inst, suId)
7630 RgSchLowSapCb *tfuSap;
7632 TRC2(rgSCHUtlValidateTfuSap)
7634 if(suId >= rgSchCb[inst].numSaps)
7636 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Incorrect SuId");
7639 tfuSap = &(rgSchCb[inst].tfuSap[suId]);
7641 /* First lets check the suId */
7642 if( suId != tfuSap->sapCfg.suId)
7644 RLOG_ARG2(L_ERROR,DBG_INSTID,inst,"Incorrect SuId. Configured (%d) Recieved (%d)",
7645 tfuSap->sapCfg.suId, suId);
7648 if (tfuSap->sapSta.sapState != LRG_BND)
7650 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"Lower SAP not enabled SuId (%d)",
7651 tfuSap->sapCfg.suId);
7655 } /* end of rgSCHUtlValidateTfuSap */
7659 * Fun: rgSCHUtlAllocEventMem
7661 * Desc: This function allocates event memory
7663 * Ret: ROK - on success
7664 * RFAILED - on failure
7672 PUBLIC S16 rgSCHUtlAllocEventMem
7679 PUBLIC S16 rgSCHUtlAllocEventMem(inst, memPtr, memSize)
7686 VOLATILE U32 startTime=0;
7688 TRC2(rgSCHUtlAllocEventMem)
7690 sMem.region = rgSchCb[inst].rgSchInit.region;
7691 sMem.pool = rgSchCb[inst].rgSchInit.pool;
7693 #if (ERRCLASS & ERRCLS_DEBUG)
7696 RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize,
7697 "rgAllocEventMem(): memSize invalid\n");
7700 #endif /* ERRCLASS & ERRCLS_DEBUG */
7702 SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
7704 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
7705 MS_BUF_ADD_ALLOC_CALLER();
7707 #ifdef TFU_ALLOC_EVENT_NO_INIT
7708 if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7710 if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7713 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed.");
7717 SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
7719 } /* end of rgSCHUtlAllocEventMem*/
7723 * Fun: rgGetEventMem
7725 * Desc: This function allocates event memory
7727 * Ret: ROK - on success
7728 * RFAILED - on failure
7736 PUBLIC S16 rgSCHUtlGetEventMem
7743 PUBLIC S16 rgSCHUtlGetEventMem(ptr, len, memCp)
7751 TRC2(rgSCHUtlGetEventMem)
7752 #ifdef TFU_ALLOC_EVENT_NO_INIT
7753 ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
7755 ret = cmGetMem(memCp, len, (Ptr *)ptr);
7758 } /* end of rgSCHUtlGetEventMem*/
7764 * @brief Handler to allocate memory for ACK/NACk feedback information
7768 * Function : rgSCHUtlAllocUeANFdbkInfo
7770 * It allocates memory for the UE related ACK NACK information.
7772 * @param[in] RgSchUeCb *ue
7776 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo
7782 PUBLIC S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx)
7789 TRC2(rgSCHUtlAllocUeANFdbkInfo);
7791 if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
7792 (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
7793 ue->cell->ackNackFdbkArrSize) != ROK)
7798 for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
7800 rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
7803 /* Set it to the first index */
7804 ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
7806 } /* rgSCHUtlAllocUeANFdbkInfo */
7809 * @brief Handler to release memory for ACK/NACk feedback information
7813 * Function : rgSCHUtlDelUeANFdbkInfo
7815 * It releases memory for the UE related ACK NACK information.
7817 * @param[in] RgSchUeCb *ue
7821 PUBLIC Void rgSCHUtlDelUeANFdbkInfo
7827 PUBLIC Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx)
7832 TRC2(rgSCHUtlDelUeANFdbkInfo);
7834 /* ccpu00117052 - MOD - Passing double pointer
7835 for proper NULLP assignment*/
7836 rgSCHUtlFreeSBuf(ue->cell->instIdx,
7837 (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
7838 ue->cell->ackNackFdbkArrSize);
7841 } /* rgSCHUtlDelUeANFdbkInfo */
7844 * @brief Handler to initialise UE ACK/NACk feedback information
7848 * Function : rgSCHUtlInitUeANFdbkInfo
7850 * It initialises UE related ACK NACK information.
7852 * @param[in] RgSchTddANInfo *anFdInfo
7856 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo
7858 RgSchTddANInfo *anFdInfo
7861 PUBLIC S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo)
7862 RgSchTddANInfo *anFdInfo;
7865 TRC2(rgSCHUtlInitUeANFdbkInfo);
7867 anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
7869 anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
7870 anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
7871 anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
7874 } /* rgSCHUtlInitUeANFdbkInfo */
7877 * @brief Handler to get UE related ACK NACK feedback information
7881 * Function : rgSCHUtlGetUeANFdbkInfo
7883 * It gets the UE related ACK NACK information based on
7884 * SFN and slot number.
7886 * @param[in] RgSchUeCb *ueCb
7887 * @param[in] CmLteTimingInfo *time
7888 * @return RgSchTddANInfo*
7891 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo
7894 CmLteTimingInfo *timeInfo,
7898 PUBLIC RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx)
7900 CmLteTimingInfo *timeInfo;
7906 TRC2(rgSCHUtlGetUeANFdbkInfo);
7908 for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
7910 if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
7911 (timeInfo->slot == ueCb->cellInfo[servCellIdx]->anInfo[idx].slot))
7913 RETVALUE(&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
7918 } /* rgSCHUtlGetUeANFdbkInfo */
7921 * @brief To get downlink slot index
7925 * Function: rgSCHUtlGetDlSfIdx
7926 * Purpose: Gets downlink slot index based on SFN and slot no
7928 * @param[in] CmLteTimingInfo *timeInfo
7929 * @param[in] RgSchCellCb *cell
7934 PUBLIC U8 rgSCHUtlGetDlSfIdx
7937 CmLteTimingInfo *timeInfo
7940 PUBLIC U8 rgSCHUtlGetDlSfIdx(cell, timeInfo)
7942 CmLteTimingInfo *timeInfo;
7946 TRC2(rgSCHUtlGetDlSfIdx);
7948 idx = RGSCH_NUM_SUB_FRAMES - \
7949 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7950 idx = ((idx * timeInfo->sfn) + \
7951 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->slot]) - 1;
7952 idx = idx % cell->numDlSubfrms;
7958 * @brief To get the next downlink slot
7962 * Function: rgSCHUtlGetNxtDlSfInfo
7963 * Purpose: Gets next downlink slot based on current DL slot
7965 * @param[in] CmLteTimingInfo curDlTime
7966 * @param[in] RgSchCellCb *cell
7967 * @param[in] RgSchDlSf *dlSf
7968 * @param[in] RgSchDlSf **nxtDlsf
7969 * @param[in] CmLteTimingInfo *nxtDlTime
7974 PUBLIC Void rgSCHUtlGetNxtDlSfInfo
7976 CmLteTimingInfo curDlTime,
7979 RgSchDlSf **nxtDlsf,
7980 CmLteTimingInfo *nxtDlTime
7983 PUBLIC Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime)
7984 CmLteTimingInfo curDlTime;
7987 RgSchDlSf **nxtDlsf;
7988 CmLteTimingInfo *nxtDlTime;
7991 U16 idx = curDlTime.slot;
7993 TRC2(rgSCHUtlGetNxtDlSfInfo);
7999 idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
8001 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
8002 != RG_SCH_TDD_DL_slot);
8003 RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
8004 *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
8005 if(dlSf->dlFdbkInfo.slot != (*nxtDlsf)->dlFdbkInfo.slot)
8014 * @brief To get the previous downlink slot
8018 * Function: rgSCHUtlGetPrevDlSfInfo
8019 * Purpose: Gets previous downlink slot based on current DL slot
8021 * @param[in] RgSchCellCb *cell
8022 * @param[in] CmLteTimingInfo curDlTime
8023 * @param[in] CmLteTimingInfo *prevDlTime
8024 * @param[in] U8 *numSubfrm
8029 PUBLIC Void rgSCHUtlGetPrevDlSfInfo
8032 CmLteTimingInfo curDlTime,
8033 CmLteTimingInfo *prevDlTime,
8037 PUBLIC Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm)
8039 CmLteTimingInfo curDlTime;
8040 CmLteTimingInfo *prevDlTime;
8044 S16 idx = curDlTime.slot;
8046 TRC2(rgSCHUtlGetPrevDlSfInfo);
8053 idx = RGSCH_NUM_SUB_FRAMES-1;
8056 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
8057 != RG_SCH_TDD_DL_slot);
8059 RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
8064 /* Added Holes Management functions for Adaptive Re transmission */
8065 /******* </AllocHolesMemMgmnt>: START *****/
8066 /***********************************************************
8068 * Func : rgSCHUtlUlSfInit
8070 * Desc : UL slot init.
8078 **********************************************************/
8080 PUBLIC S16 rgSCHUtlUlSfInit
8088 PUBLIC S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf)
8096 TRC2(rgSCHUtlUlSfInit);
8104 if(cell->ulDlCfgIdx == 0)
8106 /* Store the Uplink slot number corresponding to the idx */
8107 sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6];
8110 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
8111 sizeof(RgSchUlAllocDb));
8116 ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
8119 /* ccpu00117052 - MOD - Passing double pointer
8120 for proper NULLP assignment*/
8121 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8122 sizeof(RgSchUlAllocDb));
8125 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
8126 sizeof(RgSchUlHoleDb));
8129 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8130 /* ccpu00117052 - MOD - Passing double pointer
8131 for proper NULLP assignment*/
8132 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8133 sizeof(RgSchUlAllocDb));
8136 /* Initialize the hole with CFI 1 Pusch Bw Info */
8137 ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (U8)(maxUePerSf + 2), \
8138 0, cell->dynCfiCb.bwInfo[1].numSb);
8142 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8143 /* ccpu00117052 - MOD - Passing double pointer
8144 for proper NULLP assignment*/
8145 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8146 sizeof(RgSchUlAllocDb));
8147 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8148 sizeof(RgSchUlHoleDb));
8151 cmLListInit(&sf->reTxLst);
8153 /* Fix ccpu00120610*/
8154 sf->allocCountRef = &sf->allocDb->count;
8156 /* initialize UL available subbands for current sub-frame */
8157 sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
8159 sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
8160 sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
8161 for(index = 0; index < MAX_5GTF_BEAMS; index++)
8163 sf->sfBeamInfo[index].totVrbgAllocated = 0;
8164 sf->sfBeamInfo[index].totVrbgRequired = 0;
8165 sf->sfBeamInfo[index].vrbgStart = 0;
8173 /***********************************************************
8175 * Func : rgSCHUtlUlSfDeinit
8177 * Desc : Deinitialises a slot
8185 **********************************************************/
8187 PUBLIC Void rgSCHUtlUlSfDeinit
8193 PUBLIC Void rgSCHUtlUlSfDeinit(cell, sf)
8198 TRC2(rgSCHUtlUlSfDeinit);
8201 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8202 /* ccpu00117052 - MOD - Passing double pointer
8203 for proper NULLP assignment*/
8204 /* ccpu00117052 - MOD - Passing double pointer
8205 for proper NULLP assignment*/
8206 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8207 sizeof(RgSchUlAllocDb));
8211 rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
8212 /* ccpu00117052 - MOD - Passing double pointer
8213 for proper NULLP assignment*/
8214 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8215 sizeof(RgSchUlHoleDb));
8220 /***********************************************************
8222 * Func : rgSCHUtlUlAllocDbInit
8224 * Desc : Initialise allocation DB
8226 * Ret : S16 (ROK/RFAILED)
8232 **********************************************************/
8234 PRIVATE S16 rgSCHUtlUlAllocDbInit
8237 RgSchUlAllocDb *allocDb,
8241 PRIVATE S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs)
8243 RgSchUlAllocDb *allocDb;
8247 S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
8248 TRC2(rgSCHUtlUlAllocDbInit);
8254 allocDb->first = NULLP;
8258 /***********************************************************
8260 * Func : rgSCHUtlUlAllocDbDeinit
8262 * Desc : Deinitialises allocation DB
8263 * sent to UE, for a UE with accumulation disabled
8271 **********************************************************/
8273 PRIVATE Void rgSCHUtlUlAllocDbDeinit
8276 RgSchUlAllocDb *allocDb
8279 PRIVATE Void rgSCHUtlUlAllocDbDeinit(cell, allocDb)
8281 RgSchUlAllocDb *allocDb;
8284 TRC2(rgSCHUtlUlAllocDbDeinit);
8285 rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
8287 allocDb->first = NULLP;
8291 /***********************************************************
8293 * Func : rgSCHUtlUlHoleDbInit
8295 * Desc : Initialise hole DB
8297 * Ret : S16 (ROK/RFAILED)
8303 **********************************************************/
8305 PRIVATE S16 rgSCHUtlUlHoleDbInit
8308 RgSchUlHoleDb *holeDb,
8314 PRIVATE S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num)
8316 RgSchUlHoleDb *holeDb;
8323 RgSchUlHole *hole = NULLP;
8324 TRC2(rgSCHUtlUlHoleDbInit);
8326 ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
8332 holeDb->first = hole;
8333 hole->start = start;
8335 hole->prv = hole->nxt = NULLP;
8339 /***********************************************************
8341 * Func : rgSCHUtlUlHoleDbDeinit
8343 * Desc : Deinitialises hole DB
8351 **********************************************************/
8353 PRIVATE Void rgSCHUtlUlHoleDbDeinit
8356 RgSchUlHoleDb *holeDb
8359 PRIVATE Void rgSCHUtlUlHoleDbDeinit(cell, holeDb)
8361 RgSchUlHoleDb *holeDb;
8364 TRC2(rgSCHUtlUlHoleDbDeinit);
8365 rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
8367 holeDb->first = NULLP;
8372 /***********************************************************
8374 * Func : rgSCHUtlUlAllocGetHole
8376 * Desc : Get allocation from hole
8378 * Ret : RgSchUlAlloc *
8384 **********************************************************/
8386 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole
8393 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole)
8399 TRC2(rgSCHUtlUlAllocGetHole);
8400 if (numSb < hole->num)
8402 RETVALUE(rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
8406 RETVALUE(rgSCHUtlUlAllocGetCompHole(sf, hole));
8411 /***********************************************************
8413 * Func : rgSCHUtlUlAllocGetCompHole
8415 * Desc : Get an allocation corresponding to an entire hole
8417 * Ret : RgSchUlAlloc *
8423 **********************************************************/
8425 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole
8431 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole)
8436 RgSchUlAlloc *alloc;
8437 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8438 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8439 * updated, causing another check for prv */
8440 RgSchUlAlloc *prv = hole->prvAlloc;
8441 RgSchUlAlloc *nxt = hole->nxtAlloc;
8442 TRC2(rgSCHUtlUlAllocGetCompHole);
8446 if (hole->start == prv->nxtHole->start)
8448 prv->nxtHole = NULLP;
8450 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8454 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8457 RGSCH_NULL_CHECK( 0, alloc);
8458 alloc->prvHole = NULLP;
8459 alloc->nxtHole = NULLP;
8461 alloc->sbStart = hole->start;
8462 alloc->numSb = hole->num;
8466 nxt->prvHole = NULLP;
8469 rgSCHUtlUlHoleRls(sf->holeDb, hole);
8471 /* UL_ALLOC_CHANGES*/
8472 alloc->allocDbRef = (void*)sf->allocDb;
8473 alloc->holeDbRef = (void*)sf->holeDb;
8477 /***********************************************************
8479 * Func : rgSCHUtlUlAllocGetPartHole
8481 * Desc : Get an allocation corresponding to a part of a hole.
8482 * The initial 'numSb' part of the hole shall be taken
8483 * away for this alloc.
8485 * Ret : RgSchUlAlloc *
8491 **********************************************************/
8493 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole
8500 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)
8506 RgSchUlAlloc *alloc;
8507 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8508 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8509 * updated, causing another check for prv */
8510 RgSchUlAlloc *prv = hole->prvAlloc;
8511 TRC2(rgSCHUtlUlAllocGetPartHole);
8515 if (hole->start == prv->nxtHole->start)
8517 prv->nxtHole = NULLP;
8519 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8523 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8526 RGSCH_NULL_CHECK( 0, alloc);
8527 alloc->prvHole = NULLP;
8528 alloc->nxtHole = hole;
8529 hole->prvAlloc = alloc;
8531 alloc->sbStart = hole->start;
8532 alloc->numSb = numSb;
8533 hole->start += numSb;
8536 rgSCHUtlUlHoleDecr(sf->holeDb, hole);
8538 /* UL_ALLOC_CHANGES*/
8539 alloc->allocDbRef = (void*)sf->allocDb;
8540 alloc->holeDbRef = (void*)sf->holeDb;
8545 /***********************************************************
8547 * Func : rgSCHUtlUlAllocFirst
8549 * Desc : Get first alloc in slot
8551 * Ret : RgSchUlAlloc *
8557 **********************************************************/
8559 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst
8564 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf)
8568 TRC2(rgSCHUtlUlAllocFirst);
8569 RETVALUE(sf->allocDb->first);
8572 /***********************************************************
8574 * Func : rgSCHUtlUlAllocNxt
8576 * Desc : Get next alloc
8578 * Ret : RgSchUlAlloc *
8584 **********************************************************/
8586 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt
8592 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc)
8594 RgSchUlAlloc *alloc;
8597 TRC2(rgSCHUtlUlAllocNxt);
8599 RETVALUE(alloc->nxt);
8602 /***********************************************************
8604 * Func : rgSCHUtlUlAllocGetAdjNxt
8606 * Desc : Get alloc which is immediately after the passed one.
8607 * 1. Gets alloc from mem.
8608 * 2. Inserts alloc into list (between prv and
8609 * prv->nxt, prv is not NULLP).
8610 * 3. Increments alloc count.
8611 * Note 1: Holes are not dealt with here.
8612 * Note 2: Assumes prv to be NULL.
8614 * Ret : RgSchUlAlloc *
8620 **********************************************************/
8622 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt
8628 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv)
8633 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8634 RgSchUlAlloc *nxt = prv->nxt;
8635 TRC2(rgSCHUtlUlAllocGetAdjNxt);
8637 #if (ERRCLASS & ERRCLS_DEBUG)
8638 if ( alloc == NULLP )
8656 /***********************************************************
8658 * Func : rgSCHUtlUlAllocGetFirst
8660 * Desc : Get alloc which is to be the first one in the alloc list
8661 * 1. Gets alloc from mem.
8662 * 2. Inserts alloc as first element into list.
8663 * 3. Increments alloc count.
8664 * Note 1: Holes are not dealt with here.
8665 * Note 2: prv to necessarily NULLP.
8667 * Ret : RgSchUlAlloc *
8673 **********************************************************/
8675 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst
8680 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db)
8684 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8685 RgSchUlAlloc *nxt = db->first;
8686 TRC2(rgSCHUtlUlAllocGetFirst);
8688 #if (ERRCLASS & ERRCLS_DEBUG)
8689 if ( alloc == NULLP )
8708 /* UL_ALLOC_ENHANCEMENT */
8709 /***********************************************************
8711 * Func : rgSCHUtlUlHoleAddAllocation
8713 * Desc : On freeing an alloc, add to hole
8721 **********************************************************/
8723 PUBLIC Void rgSCHUtlUlHoleAddAllocation
8728 PUBLIC Void rgSCHUtlUlHoleAddAllocation(alloc)
8729 RgSchUlAlloc *alloc;
8732 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8733 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8734 * The excessive branching is meant to utilise the knowledge of whether prv
8735 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8736 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8737 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8738 RgSchUlHoleDb *db = alloc->holeDbRef;
8739 RgSchUlHole *prv = alloc->prvHole;
8740 RgSchUlHole *nxt = alloc->nxtHole;
8741 TRC2(rgSCHUtlUlHoleAddAllocation);
8747 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8750 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8756 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8759 rgSCHUtlUlHoleNew(db, alloc);
8765 /***********************************************************
8767 * Func : rgSCHUtlUlAllocRelease
8769 * Desc : Releases an uplink allocation, only take alloc ptr
8777 **********************************************************/
8779 PUBLIC Void rgSCHUtlUlAllocRelease
8784 PUBLIC Void rgSCHUtlUlAllocRelease(alloc)
8785 RgSchUlAlloc *alloc;
8788 RgSchUlAllocDb *allocDb = alloc->allocDbRef;
8789 RgSchUlAlloc *prv = alloc->prv;
8790 RgSchUlAlloc *nxt = alloc->nxt;
8791 TRC2(rgSCHUtlUlAllocRelease);
8794 alloc->raCb = NULLP;
8795 alloc->isAdaptive = FALSE;
8800 if (nxt) /* general case: this allocation lies btw two */
8807 allocDb->first = nxt;
8814 rgSCHUtlUlHoleAddAllocation(alloc);
8815 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8821 /***********************************************************
8823 * Func : rgSCHUtlUlAllocRls
8825 * Desc : Releases an uplink allocation
8833 **********************************************************/
8835 PUBLIC Void rgSCHUtlUlAllocRls
8841 PUBLIC Void rgSCHUtlUlAllocRls(sf, alloc)
8843 RgSchUlAlloc *alloc;
8846 RgSchUlAllocDb *allocDb = sf->allocDb;
8847 RgSchUlAlloc *prv = alloc->prv;
8848 RgSchUlAlloc *nxt = alloc->nxt;
8849 TRC2(rgSCHUtlUlAllocRls);
8852 alloc->raCb = NULLP;
8853 alloc->isAdaptive = FALSE;
8860 if (nxt) /* general case: this allocation lies btw two */
8867 allocDb->first = nxt;
8874 rgSCHUtlUlHoleAddAlloc(sf, alloc);
8875 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8880 printf("\nError: allocDb->count is ZERO ====\n");
8883 //printf("\nallocDb->count:%u\n",allocDb->count);
8888 /***********************************************************
8890 * Func : rgSCHUtlUlHoleFirst
8892 * Desc : Get first (largest) hole
8894 * Ret : RgSchUlHole *
8900 **********************************************************/
8902 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst
8907 PUBLIC RgSchUlHole *rgSCHUtlUlHoleFirst(sf)
8911 TRC2(rgSCHUtlUlHoleFirst);
8912 RETVALUE(sf->holeDb->first);
8915 /***********************************************************
8917 * Func : rgSCHUtlUlHoleNxt
8919 * Desc : Get next largest hole
8921 * Ret : RgSchUlHole *
8927 **********************************************************/
8929 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt
8935 PUBLIC RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole)
8940 TRC2(rgSCHUtlUlHoleNxt);
8942 RETVALUE(hole->nxt);
8945 /***********************************************************
8947 * Func : rgSCHUtlUlHoleAddAlloc
8949 * Desc : On freeing an alloc, add to hole
8957 **********************************************************/
8959 PUBLIC Void rgSCHUtlUlHoleAddAlloc
8965 PUBLIC Void rgSCHUtlUlHoleAddAlloc(sf, alloc)
8967 RgSchUlAlloc *alloc;
8970 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8971 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8972 * The excessive branching is meant to utilise the knowledge of whether prv
8973 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8974 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8975 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8976 RgSchUlHoleDb *db = sf->holeDb;
8977 RgSchUlHole *prv = alloc->prvHole;
8978 RgSchUlHole *nxt = alloc->nxtHole;
8979 TRC2(rgSCHUtlUlHoleAddAlloc);
8985 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8988 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8994 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8997 rgSCHUtlUlHoleNew(db, alloc);
9000 /* increment the number of subbands getting freed to total available list */
9001 sf->availSubbands += alloc->numSb;
9006 /***********************************************************
9008 * Func : rgSCHUtlUlHoleJoin
9010 * Desc : Join two holes (due to alloc being deleted)
9018 **********************************************************/
9020 PUBLIC Void rgSCHUtlUlHoleJoin
9028 PUBLIC Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc)
9032 RgSchUlAlloc *alloc;
9035 TRC2(rgSCHUtlUlHoleJoin);
9036 prv->num += alloc->numSb + nxt->num;
9037 rgSCHUtlUlHoleRls(db, nxt);
9038 rgSCHUtlUlHoleIncr(db, prv);
9039 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9044 /***********************************************************
9046 * Func : rgSCHUtlUlHoleExtndRight
9048 * Desc : Extend hole due to alloc coming 'after' the hole
9057 **********************************************************/
9059 PUBLIC Void rgSCHUtlUlHoleExtndRight
9066 PUBLIC Void rgSCHUtlUlHoleExtndRight(db, prv, alloc)
9069 RgSchUlAlloc *alloc;
9072 TRC2(rgSCHUtlUlHoleExtndRight);
9073 prv->num += alloc->numSb;
9074 rgSCHUtlUlHoleIncr(db, prv);
9075 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
9079 /***********************************************************
9081 * Func : rgSCHUtlUlHoleExtndLeft
9083 * Desc : Extend hole due to alloc coming 'before' the hole
9092 **********************************************************/
9094 PUBLIC Void rgSCHUtlUlHoleExtndLeft
9101 PUBLIC Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc)
9104 RgSchUlAlloc *alloc;
9107 TRC2(rgSCHUtlUlHoleExtndLeft);
9108 nxt->num += alloc->numSb;
9109 nxt->start = alloc->sbStart;
9110 rgSCHUtlUlHoleIncr(db, nxt);
9111 rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
9115 /***********************************************************
9117 * Func : rgSCHUtlUlHoleNew
9119 * Desc : Create new hole due to alloc being deleted
9127 **********************************************************/
9129 PUBLIC Void rgSCHUtlUlHoleNew
9135 PUBLIC Void rgSCHUtlUlHoleNew(db, alloc)
9137 RgSchUlAlloc *alloc;
9140 RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
9141 #if (ERRCLASS & ERRCLS_DEBUG)
9142 if ( hole == NULLP )
9147 TRC2(rgSCHUtlUlHoleNew);
9148 hole->start = alloc->sbStart;
9149 hole->num = alloc->numSb;
9151 rgSCHUtlUlHoleIns(db, hole);
9152 rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
9156 /***********************************************************
9158 * Func : rgSCHUtlUlHoleUpdAllocLnks
9160 * Desc : Update alloc links in hole
9168 **********************************************************/
9170 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks
9173 RgSchUlAlloc *prvAlloc,
9174 RgSchUlAlloc *nxtAlloc
9177 PUBLIC Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc)
9179 RgSchUlAlloc *prvAlloc;
9180 RgSchUlAlloc *nxtAlloc;
9183 TRC2(rgSCHUtlUlHoleUpdAllocLnks);
9186 prvAlloc->nxtHole = hole;
9190 nxtAlloc->prvHole = hole;
9192 hole->prvAlloc = prvAlloc;
9193 hole->nxtAlloc = nxtAlloc;
9198 /***********************************************************
9200 * Func : rgSCHUtlUlHoleIns
9202 * Desc : Insert (newly created) hole in sorted list of holes.
9203 * Searches linearly, beginning with the largest hole.
9211 **********************************************************/
9213 PUBLIC Void rgSCHUtlUlHoleIns
9219 PUBLIC Void rgSCHUtlUlHoleIns(db, hole)
9225 TRC2(rgSCHUtlUlHoleIns);
9227 if ((cur = db->first) != NULLP)
9230 if (cur->num < hole->num)
9240 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9242 if (nxt->num < hole->num)
9244 /* Insert hole: cur <-> hole <-> nxt */
9260 /* This is the first hole */
9262 hole->prv = NULLP; /* may not be needed */
9268 /***********************************************************
9270 * Func : rgSCHUtlUlHoleIncr
9272 * Desc : hole->num has increeased, reposition in sorted
9281 **********************************************************/
9283 PUBLIC Void rgSCHUtlUlHoleIncr
9289 PUBLIC Void rgSCHUtlUlHoleIncr(db, hole)
9295 TRC2(rgSCHUtlUlHoleIncr);
9297 if ((cur = hole->prv) != NULLP)
9301 if (cur->num > hole->num)
9306 /* Remove hole from current position */
9307 cur->nxt = hole->nxt;
9310 hole->nxt->prv = cur;
9313 for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
9315 if (prv->num > hole->num)
9317 /* Insert hole: prv <-> hole <-> cur */
9336 /***********************************************************
9338 * Func : rgSCHUtlUlHoleDecr
9340 * Desc : hole->num has decreeased, reposition in sorted
9349 **********************************************************/
9351 PUBLIC Void rgSCHUtlUlHoleDecr
9357 PUBLIC Void rgSCHUtlUlHoleDecr(db, hole)
9363 TRC2(rgSCHUtlUlHoleDecr);
9365 if ((cur = hole->nxt) != NULLP)
9369 if (cur->num < hole->num)
9374 /* Remove hole from current position */
9375 cur->prv = hole->prv;
9378 hole->prv->nxt = cur;
9380 else /* no prv, so cur to replace hole as first in list */
9385 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9387 if (nxt->num < hole->num)
9389 /* Insert hole: cur <-> hole <-> nxt */
9407 /***********************************************************
9409 * Func : rgSCHUtlUlHoleRls
9411 * Desc : Releases hole.
9412 * 1. Decrements hole count.
9413 * 2. Deletes hole from list.
9414 * 3. Frees hole (hole memory release).
9422 **********************************************************/
9424 PUBLIC Void rgSCHUtlUlHoleRls
9430 PUBLIC Void rgSCHUtlUlHoleRls(db, hole)
9435 RgSchUlHole *prv = hole->prv;
9436 RgSchUlHole *nxt = hole->nxt;
9437 TRC2(rgSCHUtlUlHoleRls);
9457 rgSCHUtlUlHoleMemRls(&db->mem, hole);
9462 /***********************************************************
9464 * Func : rgSCHUtlUlAllocMemInit
9466 * Desc : Initialises alloc free pool
9468 * Ret : S16 (ROK/RFAILED)
9474 **********************************************************/
9476 PUBLIC S16 rgSCHUtlUlAllocMemInit
9479 RgSchUlAllocMem *mem,
9483 PUBLIC S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs)
9485 RgSchUlAllocMem *mem;
9490 RgSchUlAlloc *allocs;
9491 TRC2(rgSCHUtlUlAllocMemInit);
9493 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
9494 maxAllocs * sizeof(*allocs));
9499 mem->allocs = allocs;
9500 mem->maxAllocs = maxAllocs;
9501 if (mem->maxAllocs == 1)
9503 allocs[0].prv = NULLP;
9504 allocs[0].nxt = NULLP;
9509 allocs[0].prv = NULLP;
9510 allocs[0].nxt = &allocs[1];
9511 for (i = 1; i < mem->maxAllocs - 1; ++i)
9513 allocs[i].prv = &allocs[i-1];
9514 allocs[i].nxt = &allocs[i+1];
9516 allocs[i].prv = &allocs[i-1];
9517 allocs[i].nxt = NULLP;
9519 mem->firstFree = &allocs[0];
9523 /***********************************************************
9525 * Func : rgSCHUtlUlAllocMemDeinit
9527 * Desc : Deinitialises alloc free pool
9535 **********************************************************/
9537 PUBLIC Void rgSCHUtlUlAllocMemDeinit
9540 RgSchUlAllocMem *mem
9543 PUBLIC Void rgSCHUtlUlAllocMemDeinit(cell, mem)
9545 RgSchUlAllocMem *mem;
9548 TRC2(rgSCHUtlUlAllocMemDeinit);
9549 /* ccpu00117052 - MOD - Passing double pointer
9550 for proper NULLP assignment*/
9551 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
9552 mem->maxAllocs * sizeof(*mem->allocs));
9554 mem->firstFree = NULLP;
9558 /***********************************************************
9560 * Func : rgSCHUtlUlHoleMemInit
9562 * Desc : Initialises hole free pool. Assumes maxHoles
9565 * Ret : S16 (ROK/RFAILED)
9571 **********************************************************/
9573 PUBLIC S16 rgSCHUtlUlHoleMemInit
9576 RgSchUlHoleMem *mem,
9578 RgSchUlHole **holeRef
9581 PUBLIC S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef)
9583 RgSchUlHoleMem *mem;
9585 RgSchUlHole **holeRef;
9590 TRC2(rgSCHUtlUlHoleMemInit);
9592 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
9593 maxHoles * sizeof(*holes));
9600 mem->maxHoles = maxHoles;
9602 /* first hole is taken up */
9603 holes[0].prv = NULLP; /* not needed */
9604 holes[0].nxt = NULLP; /* not needed */
9605 *holeRef = &holes[0];
9607 if (mem->maxHoles == 2)
9609 holes[1].prv = NULLP; /* may not be needed */
9610 holes[1].nxt = NULLP; /* may not be needed */
9615 holes[1].prv = NULLP;
9616 holes[0].nxt = &holes[1];
9617 for (i = 1; i < mem->maxHoles - 1; ++i)
9619 holes[i].prv = &holes[i-1];
9620 holes[i].nxt = &holes[i+1];
9622 holes[i].prv = &holes[i-1];
9623 holes[i].nxt = NULLP;
9625 mem->firstFree = &holes[1];
9630 /***********************************************************
9632 * Func : rgSCHUtlUlHoleMemDeinit
9634 * Desc : Deinitialises hole free pool
9642 **********************************************************/
9644 PUBLIC Void rgSCHUtlUlHoleMemDeinit
9650 PUBLIC Void rgSCHUtlUlHoleMemDeinit(cell, mem)
9652 RgSchUlHoleMem *mem;
9655 TRC2(rgSCHUtlUlHoleMemDeinit);
9656 /* ccpu00117052 - MOD - Passing double pointer
9657 for proper NULLP assignment*/
9658 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
9659 mem->maxHoles * sizeof(*mem->holes));
9661 mem->firstFree = NULLP;
9665 /***********************************************************
9667 * Func : rgSCHUtlUlAllocMemGet
9669 * Desc : Gets an 'alloc' from the free pool
9671 * Ret : RgSchUlAlloc *
9677 **********************************************************/
9679 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet
9681 RgSchUlAllocMem *mem
9684 PUBLIC RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem)
9685 RgSchUlAllocMem *mem;
9688 RgSchUlAlloc *alloc;
9689 TRC2(rgSCHUtlUlAllocMemGet);
9691 #if (ERRCLASS & ERRCLS_DEBUG)
9692 if (mem->firstFree == NULLP)
9698 alloc = mem->firstFree;
9699 mem->firstFree = alloc->nxt;
9700 alloc->nxt = NULLP; /* probably not needed */
9701 /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
9706 /***********************************************************
9708 * Func : rgSCHUtlUlAllocMemRls
9710 * Desc : Returns an 'alloc' to the free pool
9718 **********************************************************/
9720 PUBLIC Void rgSCHUtlUlAllocMemRls
9722 RgSchUlAllocMem *mem,
9726 PUBLIC Void rgSCHUtlUlAllocMemRls(mem, alloc)
9727 RgSchUlAllocMem *mem;
9728 RgSchUlAlloc *alloc;
9731 TRC2(rgSCHUtlUlAllocMemRls);
9734 alloc->nxt = mem->firstFree;
9735 if (mem->firstFree != NULLP)
9737 mem->firstFree->prv = alloc;
9739 mem->firstFree = alloc;
9743 /***********************************************************
9745 * Func : rgSCHUtlUlHoleMemGet
9747 * Desc : Gets a 'hole' from the free pool
9749 * Ret : RgSchUlHole *
9755 **********************************************************/
9757 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet
9762 PUBLIC RgSchUlHole *rgSCHUtlUlHoleMemGet(mem)
9763 RgSchUlHoleMem *mem;
9767 TRC2(rgSCHUtlUlHoleMemGet);
9769 #if (ERRCLASS & ERRCLS_DEBUG)
9770 if (mem->firstFree == NULLP)
9776 hole = mem->firstFree;
9777 mem->firstFree = hole->nxt;
9778 mem->firstFree->prv = NULLP; /* may not be needed, under error class */
9779 hole->nxt = NULLP; /* probably not needed */
9780 /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
9785 /***********************************************************
9787 * Func : rgSCHUtlUlHoleMemRls
9789 * Desc : Returns a 'hole' to the free pool
9797 **********************************************************/
9799 PUBLIC Void rgSCHUtlUlHoleMemRls
9801 RgSchUlHoleMem *mem,
9805 PUBLIC Void rgSCHUtlUlHoleMemRls(mem, hole)
9806 RgSchUlHoleMem *mem;
9810 TRC2(rgSCHUtlUlHoleMemRls);
9813 hole->nxt = mem->firstFree;
9814 if (mem->firstFree != NULLP)
9816 mem->firstFree->prv = hole;
9818 mem->firstFree = hole;
9823 * @brief Get an alloc from the specified position in the BW.
9827 * Function : rgSCHUtlUlGetSpfcAlloc
9829 * - Return an alloc from the specified position in the BW.
9830 * Note: This function assumes there is always a hole
9831 * Existing which completely has the specified
9832 * allocation. The reason for such an assumption is
9833 * the function's usage as of now guarantees that there
9834 * will always be such hole. And also for efficiency.
9836 * @param[in] RgSchUlSf *sf
9837 * @param[in] U8 startSb
9838 * @param[in] U8 numSb
9839 * @return RgSchUlAlloc*
9842 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc
9849 PUBLIC RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb)
9855 RgSchUlHole *hole, *nxtHole;
9856 RgSchUlAlloc *alloc = NULLP;
9857 TRC2(rgSCHUtlUlGetSpfcAlloc);
9859 if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
9865 nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
9866 if ((startSb >= hole->start) &&
9867 (startSb+numSb <= hole->start+hole->num))
9869 if (startSb != hole->start)
9871 /* Create a new hole to accomodate Subbands between
9872 * hole start and req alloc start */
9873 RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
9875 #if (ERRCLASS & ERRCLS_DEBUG)
9876 if ( newHole == NULLP )
9881 newHole->start = hole->start;
9882 newHole->num = startSb - hole->start;
9883 hole->start = startSb;
9884 /* [ccpu00122847]-MOD- Correctly updating the hole->num */
9885 hole->num -= newHole->num;
9886 ++(sf->holeDb->count);
9887 rgSCHUtlUlHoleIns(sf->holeDb, newHole);
9888 newHole->prvAlloc = hole->prvAlloc;
9889 if (newHole->prvAlloc)
9891 newHole->prvAlloc->nxtHole = newHole;
9893 if (numSb == hole->num)
9895 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9899 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9901 alloc->prvHole = newHole;
9902 newHole->nxtAlloc = alloc;
9904 else /* Hole start and req alloc start are same */
9906 if (numSb == hole->num)
9908 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9912 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9917 } while ((hole = nxtHole) != NULLP);
9922 * @brief Validates the qci values
9926 * Function :rgSCHUtlValidateQci
9928 * @param[in] RgSchCellCb *cellCb
9929 * @param[in] U8 numQci
9930 * @param[out] U8 *qci
9936 PRIVATE S16 rgSCHUtlValidateQci
9938 RgSchCellCb *cellCb,
9943 PRIVATE S16 rgSCHUtlValidateQci(cellCb, numQci, qci)
9944 RgSchCellCb *cellCb;
9952 TRC3(rgSCHUtlValidateQci)
9954 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
9956 qciVal = qci[qciIdx];
9957 if(qciVal == 0 || qciVal > 9)
9961 if(qciVal != cellCb->qciArray[qciVal].qci)
9968 }/* rgSCHUtlValidateQci */
9970 * @brief Validates the measurement request parameters.
9974 * Function :rgSCHUtlValidateMeasReq
9976 * @param[in] RgSchCellCb *cellCb
9977 * @param[in] LrgSchMeasReqInfo *schL2MeasInfo
9978 * @param[out] RgSchErrInfo *err
9979 * @return RgSchUlAlloc*
9982 PUBLIC S16 rgSCHUtlValidateMeasReq
9984 RgSchCellCb *cellCb,
9985 LrgSchMeasReqInfo *schL2MeasInfo,
9989 PUBLIC S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err)
9990 RgSchCellCb *cellCb;
9991 LrgSchMeasReqInfo *schL2MeasInfo;
9998 TRC3(rgSCHUtlValidateMeasReq)
10000 measType = schL2MeasInfo->measType;
10002 if((measType == 0) ||
10005 err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
10006 err->errCause = RGSCHERR_SCH_L2MEAS;
10009 if((schL2MeasInfo->timePrd !=0) &&
10010 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
10011 ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
10012 (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
10014 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10015 err->errCause = RGSCHERR_SCH_L2MEAS;
10018 if((schL2MeasInfo->timePrd !=0) &&
10019 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
10020 (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ))
10022 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10023 err->errCause = RGSCHERR_SCH_L2MEAS;
10026 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
10027 ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
10028 (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
10029 ((schL2MeasInfo->timePrd !=0)&&
10030 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
10031 (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
10033 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10034 err->errCause = RGSCHERR_SCH_L2MEAS;
10037 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
10038 ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
10039 (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
10040 ((schL2MeasInfo->timePrd !=0) &&
10041 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
10042 (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
10044 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
10045 err->errCause = RGSCHERR_SCH_L2MEAS;
10048 if((schL2MeasInfo->timePrd !=0) &&
10049 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
10051 RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \
10052 (schL2MeasInfo->avgPrbQciDl.numQci));
10053 ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
10054 schL2MeasInfo->avgPrbQciDl.qci);
10057 err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
10058 err->errCause = RGSCHERR_SCH_L2MEAS;
10063 }/* rgSCHUtlValidateMeasReq */
10064 #endif /* LTE_L2_MEAS */
10065 /******* </AllocHolesMemMgmnt>: END *****/
10068 * @brief API for sending SI configuration confirm from Scheduler to RRM
10072 * Function: rgSCHUtlRgrSiCfgCfm
10074 * This API is invoked to send SI configuration confirm from Scheduler
10076 * This API fills in Pst structure and SAP Ids and invokes
10077 * config confirm API towards RRM.
10079 * @param[in] RgrCfgTransId transId
10080 * @param[in] U8 status
10086 PUBLIC S16 rgSCHUtlRgrSiCfgCfm
10090 RgrCfgTransId transId,
10094 PUBLIC S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status)
10097 RgrCfgTransId transId;
10101 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10103 TRC2(rgSCHUtlRgrSiCfgCfm)
10105 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10106 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10109 if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10110 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10111 transId, status) != ROK)
10113 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10114 "RgUiRgrSiCfgCfm Failed ");
10119 } /* rgSCHUtlRgrSiCfgCfm */
10123 * @brief API for sending Warning SI configuration confirm from
10129 * This API is invoked to send Warning SI configuration confirm
10130 * from Scheduler to RRM.
10131 * This API fills in Pst structure and SAP Ids and invokes
10132 * config confirm API towards RRM.
10134 * @param[in] RgrCfgTransId transId
10135 * @param[in] U8 status
10141 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm
10146 RgrCfgTransId transId,
10150 PUBLIC S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status)
10154 RgrCfgTransId transId;
10158 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
10160 TRC2(rgSCHUtlRgrWarningSiCfgCfm)
10162 cmMemcpy((U8 *)prntTrans, (U8 *)transId.trans, RGR_CFG_TRANSID_SIZE);
10163 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
10166 if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
10167 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
10168 transId, siId, status) != ROK)
10170 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
10171 "RgUiRgrSiCfgCfm Failed ");
10176 } /* rgSCHUtlRgrWarningSiCfgCfm */
10178 /***********************************************************
10180 * Func : rgSCHUtlPutSiInfo
10182 * Desc : Utility Function to deallocate SI information
10190 **********************************************************/
10192 PUBLIC Void rgSCHUtlPutSiInfo
10197 PUBLIC Void rgSCHUtlPutSiInfo(cell)
10202 U32 sizeOfSiInfo = 0;
10203 TRC2(rgSCHUtlPutSiInfo)
10204 /*Free the buffers in crntSiInfo*/
10205 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
10206 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
10208 sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
10210 for(idx=0; idx < sizeOfSiInfo; idx++)
10212 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
10215 /*Free the buffers in newSiInfo */
10216 RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
10217 RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
10219 sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
10221 for(idx=0; idx < sizeOfSiInfo; idx++)
10223 RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
10228 #endif /*RGR_SI_SCH */
10232 /***********************************************************
10234 * Func : rgSCHUtlGetDrxSchdUesInDl
10236 * Desc : Utility Function to fill the get the list of
10237 * scheduled UEs. On these UE's, drx-inactivity
10238 * timer will be started/restarted.
10247 **********************************************************/
10249 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl
10251 RgSchCellCb *cellCb,
10253 RgSchDlHqProcCb *dlHq,
10254 RgInfUeAlloc *allocInfo,
10255 CmLListCp *dlDrxInactvTmrLst,
10256 CmLListCp *dlInActvLst,
10257 CmLListCp *ulInActvLst
10260 PUBLIC S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
10261 RgSchCellCb *cellCb;
10263 RgSchDlHqProcCb *dlHq;
10264 RgInfUeAlloc *allocInfo;
10265 CmLListCp *dlDrxInactvTmrLst;
10266 CmLListCp *dlInActvLst;
10267 CmLListCp *ulInActvLst;
10270 Bool isNewTx = FALSE;
10272 RgSchDrxDlHqProcCb *drxHq;
10273 RgSchDRXCellCb *drxCell = cellCb->drxCb;
10274 RgSchDrxUeCb *drxUe;
10276 Inst inst = cellCb->instIdx;
10278 U8 cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
10282 for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
10284 if(allocInfo->tbInfo[idx].isReTx == FALSE)
10287 /* Removing break here, since in 2 TB case if 2nd TB is proceeding with
10288 retx then drxretx timer should be stopped.*/
10292 /*Stop the DRX retransmission timer as UE scheduled for retx. Here
10293 * we stop the timer and inactivate the UE for both UL and DL.
10294 * This may result in loss of one slot for UL but this trade
10295 * off is taken to avoid the overhead of maintaining a list of UEs
10296 * to be inactivated in the next slot.*/
10297 drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
10298 drxUe = RG_SCH_DRX_GET_UE(ueCb);
10299 if(drxHq->reTxIndx != DRX_INVALID)
10301 /* This condition should never occur */
10302 if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
10304 RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]"
10305 "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
10306 drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId));
10309 drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10310 drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10312 dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10313 ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10315 for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
10317 dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
10318 ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
10321 drxUe->drxDlInactvMask |= dlInactvMask;
10322 drxUe->drxUlInactvMask |= ulInactvMask;
10324 /* if no other condition is keeping ue active,
10325 * inactivate the Ue
10327 if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
10329 /* BUG 2 : HARQ_RTT, changed for consistency */
10330 ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
10332 /* Add to DL inactive list */
10333 cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
10334 ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
10337 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
10339 /*BUG 2: HARQ_RTT changed for consistency */
10340 ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
10342 cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
10343 ueCb->ulDrxInactvLnk.node = (PTR)ueCb;
10346 /* Deleting entry from HARQ RTT queue for the same HARQ proc,
10347 * if exist. This is the special case which can happen iF UL
10348 * scheduling is done later. */
10349 if(drxHq->rttIndx != DRX_INVALID)
10351 cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
10352 &(drxHq->harqRTTEnt));
10354 drxHq->rttIndx = DRX_INVALID;
10357 cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
10358 &(drxHq->harqRetxEnt));
10359 drxHq->reTxIndx = DRX_INVALID;
10364 if(isNewTx == TRUE)
10366 if(ueCb->drxCb->raRcvd == TRUE)
10368 ueCb->drxCb->raRcvd = FALSE;
10370 /* mark the ra bit */
10371 ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10372 ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10374 }/*if(ra->rcvd) == TRUE */
10376 if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
10378 cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
10379 ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
10381 }/*if(isNewTx == TRUE) */
10384 }/* rgSCHUtlGetSchdUes*/
10386 /* ccpu00117452 - MOD - Changed macro name from
10387 RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
10388 #ifdef RGR_CQI_REPT
10390 * @brief This function fills StaInd struct
10394 * Function: rgSCHUtlFillSndStaInd
10395 * Purpose: Fills StaInd struct and sends the
10398 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10399 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10400 * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled
10401 * @param[in] U8 numCqiRept NUmber of reports to be filled
10406 PUBLIC S16 rgSCHUtlFillSndStaInd
10410 RgrStaIndInfo *staInfo,
10414 PUBLIC S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept)
10417 RgrStaIndInfo *staInfo;
10423 /* Fill StaInd for sending collated Latest N CQI rpeorts */
10424 /* Find index in the array from where Latest N
10425 reports needs to be fetched. Use this value to index in the array
10426 and copy the reports into staInfo */
10428 /* Fill the Cell Id of PCC of the UE */
10429 staInfo->cellId = ue->cell->cellId;
10430 staInfo->crnti = ue->ueId;
10432 idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
10434 cmMemcpy ((U8*)&(staInfo->ueCqiInfo.cqiRept),
10435 (U8*)&(ue->schCqiInfo.cqiRept[idxStart]),
10436 numCqiRept * sizeof(RgrUeCqiRept));
10438 staInfo->ueCqiInfo.numCqiRept = numCqiRept;
10440 ue->schCqiInfo.cqiCount = 0;
10442 /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
10443 if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
10445 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10446 "CQI reports for RNTI:%d",ue->ueId);
10452 }/* End of rgSCHUtlFillSndStaInd */
10457 * @brief API for sending STA indication from Scheduler to RRM.
10461 * Function: rgSCHUtlRgrStaInd
10463 * This API is invoked to send STA indication from Scheduler instance to RRM.
10464 * This API fills in Pst structure and RgrStaIndInfo
10465 * and calls the Sta primitive API towards RRM.
10467 * @param[in] cell RgSchCellCb
10468 * @param[in] RgrStsIndInfo *rgrSta
10474 PUBLIC S16 rgSCHUtlRgrStaInd
10477 RgrStaIndInfo *rgrSta
10480 PUBLIC S16 rgSCHUtlRgrStaInd(cell, rgrSta)
10482 RgrStaIndInfo *rgrSta;
10486 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10488 TRC2(rgSCHUtlRgrStaInd)
10491 rgrSap = cell->rgrSap;
10492 if (rgrSap->sapSta.sapState != LRG_BND)
10494 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10495 "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
10496 rgrSap->sapSta.sapState);
10499 RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
10500 cell->rgrSap->sapCfg.suId, rgrSta);
10502 } /* rgSCHUtlRgrStaInd*/
10503 #endif /* End of RGR_CQI_REPT */
10505 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
10507 * @brief Indicates MAC to release any rnti context it has.
10510 * Function : rgSCHUtlIndRntiRls2Mac
10511 * This function indicates MAC for this rnti release.
10512 * In case of ueId change it will indicate MAC
10513 * about the new rnti to be updated.
10514 * It will post a release RNTI indication to MAC.
10518 * @param[in] RgSchCellCb *cell
10519 * @param[in] CmLteRnti rnti
10520 * @param[in] Bool ueIdChng
10521 * @param[in] CmLteRnti newRnti
10526 PUBLIC Void rgSCHUtlIndRntiRls2Mac
10534 PUBLIC Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti)
10542 Inst inst = cell->instIdx;
10543 RgInfRlsRnti rntiInfo;
10545 TRC2(rgSCHUtlIndRntiRls2Mac)
10547 /* Copy the info to rntiInfo */
10548 rntiInfo.cellId = cell->cellId;
10549 rntiInfo.rnti = rnti;
10550 /* Fix : syed ueId change as part of reestablishment.
10551 * Now SCH to trigger this. CRG ueRecfg for ueId change
10553 rntiInfo.ueIdChng = ueIdChng;
10554 rntiInfo.newRnti = newRnti;
10556 rntiInfo.isUeSCellDel = FALSE;
10558 /* Invoke MAC to release the rnti */
10559 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
10560 RgSchMacRlsRnti(&pst, &rntiInfo);
10564 /* LTE_ADV_FLAG_REMOVED_START */
10566 * @brief API for sending LOAD INF indication from Scheduler to RRM.
10569 * Function: rgSCHUtlRgrLoadInfInd
10571 * This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
10572 * This API fills in Pst structure and RgrLoadInfIndInfo
10573 * and calls the Sta primitive API towards RRM.
10575 * @param[in] cell RgSchCellCb
10576 * @param[in] RgrLoadInfIndInfo *rgrLoadInf
10582 PUBLIC S16 rgSCHUtlRgrLoadInfInd
10585 RgrLoadInfIndInfo *rgrLoadInf
10588 PUBLIC S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf)
10590 RgrLoadInfIndInfo *rgrLoadInf;
10594 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10596 TRC2(rgSCHUtlRgrLoadInfInd)
10599 rgrSap = cell->rgrSap;
10600 if (rgrSap->sapSta.sapState != LRG_BND)
10602 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10603 "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
10604 rgrSap->sapSta.sapState);
10607 RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
10608 cell->rgrSap->sapCfg.suId, rgrLoadInf);
10610 } /* rgSCHUtlRgrLoadInfInd*/
10611 /* LTE_ADV_FLAG_REMOVED_END */
10613 /* MS_FIX : syed SCH to act as MASTER in maintaining
10614 * rnti related context. Trigger to rnti del/Chng at SCH
10615 * will result in a Indication to MAC to release its
10616 * RNTI context. MAC inturn indicates the context cleared
10617 * indication to SCH, upon which SCH would set this
10619 * @brief API for sending STA indication from Scheduler to RRM.
10623 * Function: rgSCHUtlRlsRnti
10625 * This API is invoked to indicate MAC to release rnti
10627 * @param[in] RgSchCellCb *cellCb
10628 * @param[in] RgSchRntiLnk *rntiLnk,
10629 * @param[in] Bool ueIdChngd,
10630 * @param[in] CmLteRnti newRnti
10635 PUBLIC Void rgSCHUtlRlsRnti
10638 RgSchRntiLnk *rntiLnk,
10643 PUBLIC Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti)
10645 RgSchRntiLnk *rntiLnk;
10651 TRC2(rgSCHUtlRlsRnti)
10654 if(cell->emtcEnable)
10656 rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
10661 /*Add to Guard Pool*/
10662 cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
10663 rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
10665 /* Fix: syed Explicitly Inidcate MAC to release RNTI */
10666 rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
10673 * @brief This function fills StaInd struct
10677 * Function: rgSCHUtlFillSndUeStaInd
10678 * Purpose: Fills StaInd struct and sends the
10681 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10682 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10683 * @param[in] U8 numCqiRept NUmber of reports to be filled
10688 PUBLIC S16 rgSCHUtlFillSndUeStaInd
10692 RgrUeStaIndInfo *ueStaInfo
10695 PUBLIC S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo)
10698 RgrUeStaIndInfo *ueStaInfo;
10702 ueStaInfo->cellId = cell->cellId;
10703 ueStaInfo->crnti = ue->ueId;
10705 /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
10706 if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
10708 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10709 "UE Sta reports CRNTI:%d",ue->ueId);
10715 }/* End of rgSCHUtlFillSndStaInd */
10720 * @brief API for sending STA indication from Scheduler to RRM.
10724 * Function: rgSCHUtlRgrStaInd
10726 * This API is invoked to send STA indication from Scheduler instance to RRM.
10727 * This API fills in Pst structure and RgrStaIndInfo
10728 * and calls the Sta primitive API towards RRM.
10730 * @param[in] cell RgSchCellCb
10731 * @param[in] RgrStsIndInfo *rgrSta
10737 PUBLIC S16 rgSCHUtlRgrUeStaInd
10740 RgrUeStaIndInfo *rgrUeSta
10743 PUBLIC S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta)
10745 RgrUeStaIndInfo *rgrUeSta;
10749 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10751 TRC2(rgSCHUtlRgrStaInd)
10754 rgrSap = cell->rgrSap;
10755 if (rgrSap->sapSta.sapState != LRG_BND)
10757 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10758 "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
10759 rgrSap->sapSta.sapState);
10762 RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
10763 cell->rgrSap->sapCfg.suId, rgrUeSta);
10765 } /* rgSCHUtlRgrStaInd*/
10769 * @brief function to report DL and UL PRB usage to RRM.
10772 * Function: rgSCHUtlUpdAvgPrbUsage
10773 * This function sends the PRB usage report to
10774 * RRM with the interval configured by RRM.
10776 * @param[in] cell *RgSchCellCb
10782 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage
10787 PUBLIC S16 rgSCHUtlUpdAvgPrbUsage(cell)
10791 CmLteTimingInfo frm;
10792 RgmPrbRprtInd *prbRprtInd;
10795 #ifdef DBG_MAC_RRM_PRB_PRINT
10796 static U32 count = 0;
10797 const U32 reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
10802 TRC2(rgSCHUtlUpdAvgPrbUsage);
10804 frm = cell->crntTime;
10805 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
10811 if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
10813 /* Get the total number of DL and UL slots within the reporting period*/
10814 numDlSf = (cell->prbUsage.rprtPeriod *
10815 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10816 / RGSCH_NUM_SUB_FRAMES;
10817 numUlSf = (cell->prbUsage.rprtPeriod *
10818 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10819 / RGSCH_NUM_SUB_FRAMES;
10823 /* Get the total number of DL and UL slots < 10 ms interval */
10824 numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10825 numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10828 numDlSf = cell->prbUsage.rprtPeriod;
10829 numUlSf = cell->prbUsage.rprtPeriod;
10832 if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
10833 cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd,
10834 sizeof(RgmPrbRprtInd)) != ROK)
10839 cmMemset((U8 *) &prbRprtInd->stQciPrbRpts[0],
10841 (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
10843 prbRprtInd->bCellId = cell->cellId;
10847 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL;
10848 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10850 prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage =
10851 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
10852 (numDlSf * cell->bwCfg.dlTotalBw));
10853 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10854 cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
10860 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL;
10861 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10863 prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage =
10864 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
10865 (numUlSf * cell->ulAvailBw));
10866 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10867 cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
10871 #ifdef DBG_MAC_RRM_PRB_PRINT
10872 if((count % reprotForEvery20Sec) == 0 )
10874 printf("\n====================================================================");
10875 printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n");
10876 printf("======================================================================\n");
10877 printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n",
10878 prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
10879 prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
10880 prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
10881 prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
10882 prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
10883 prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
10884 prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
10885 prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
10888 RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst),
10889 cell->rgmSap->sapCfg.suId, prbRprtInd);
10897 * @brief This function resends the Ta in case of
10898 * max retx failure or DTX for the Ta transmitted
10902 * Function: rgSCHUtlReTxTa
10905 * @param[in] RgSchCellCb *cell
10906 * @param[in] RgSchUeCb *ue
10911 PUBLIC Void rgSCHUtlReTxTa
10913 RgSchCellCb *cellCb,
10917 PUBLIC Void rgSCHUtlReTxTa(cellCb, ueCb)
10918 RgSchCellCb *cellCb;
10922 TRC2(rgSCHUtlReTxTa)
10924 /* If TA Timer is running. Stop it */
10925 if (ueCb->taTmr.tmrEvnt != TMR_NONE)
10927 rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
10929 /*[ccpu00121813]-ADD-If maxretx is reached then
10930 * use outstanding TA val for scheduling again */
10931 if(ueCb->dl.taCb.outStndngTa == TRUE)
10933 ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
10934 ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
10935 ueCb->dl.taCb.outStndngTa = FALSE;
10938 /* Fix : syed TA state updation missing */
10939 ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
10940 rgSCHUtlDlTARpt(cellCb, ueCb);
10945 /* Added function for dropping Paging Message*/
10947 * @brief Handler for BO Updt received for BCCH or PCCH.
10951 * Function : rgSCHChkBoUpdate
10953 * This function shall check for BO received falls within the scheduling window or not
10956 * @param[in] RgSchCellCb *cell
10962 PRIVATE S16 rgSCHChkBoUpdate
10965 RgInfCmnBoRpt *boUpdt
10968 PRIVATE S16 rgSCHChkBoUpdate (cell, boUpdt)
10970 RgInfCmnBoRpt *boUpdt;
10974 U32 crntTimeInSubFrms = 0;
10975 U32 boUpdTimeInSubFrms = 0;
10977 TRC2(rgSCHChkBoUpdate);
10979 crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.slot +
10980 RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI
10981 so incrementing with +1 more */
10982 boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.slot;
10985 distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
10986 boUpdTimeInSubFrms - crntTimeInSubFrms : \
10987 (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
10989 if (distance > RGSCH_PCCHBCCH_WIN)
10995 }/*rgSCHChkBoUpdate*/
11000 * @brief Utility function to calculate the UL reTxIdx in TDD cfg0
11004 * Function : rgSchUtlCfg0ReTxIdx
11006 * Update the reTxIdx according to the rules mentioned
11007 * in 3GPP TS 36.213 section 8 for TDD Cfg0
11009 * @param[in] RgSchCellCb *cell
11010 * @param[in] CmLteTimingInfo phichTime
11011 * @param[in] U8 hqFdbkIdx
11015 PUBLIC U8 rgSchUtlCfg0ReTxIdx
11018 CmLteTimingInfo phichTime,
11022 PUBLIC U8 rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx)
11024 CmLteTimingInfo phichTime;
11028 U8 reTxIdx = RGSCH_INVALID_INFO;
11030 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
11032 U8 ulSF; /* UL SF in the TDD frame */
11034 TRC2(rgSchUtlCfg0ReTxIdx);
11036 ulSf = &cellUl->ulSfArr[hqFdbkIdx];
11037 ulSF = ulSf->ulSfIdx;
11039 /* Check for the UL SF 4 or 9 */
11040 if(ulSF == 9 || ulSF == 4)
11044 if(phichTime.slot == 0 || phichTime.slot == 5)
11048 /* Retx will happen according to the Pusch k table */
11049 reTxIdx = cellUl->schdIdx;
11053 /* Retx will happen at n+7 */
11054 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11055 /* Fetch the corresponding UL slot Idx in UL sf array */
11056 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11059 else if(phichTime.slot == 1 || phichTime.slot == 6)
11061 /* Retx will happen at n+7 */
11062 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
11063 /* Fetch the corresponding UL slot Idx in UL sf array */
11064 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
11071 * @brief Utility function to calculate total num of PRBs required to
11072 * satisfy DL BO for TM1/TM2/TM6/TM7
11076 * Function : rgSchUtlDlCalc1CwPrb
11078 * Calculate PRBs required for UE to satisfy BO in DL
11080 * Note : Total calculated PRBs will be assigned to *prbReqrd
11083 * @param[in] RgSchCellCb *cell
11084 * @param[in] RgSchUeCb *ue
11085 * @param[in] U32 bo
11086 * @param[out] U32 *prbReqrd
11090 PUBLIC Void rgSchUtlDlCalc1CwPrb
11098 PUBLIC Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd)
11105 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11106 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11110 U8 cfi = dlCell->currCfi;
11112 TRC2(rgSchUtlDlCalc1CwPrb);
11114 iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11115 eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
11117 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11118 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11119 noRes = ((U64)((bo << 3) << 10)) / (eff);
11120 /* Get the number of RBs needed for this transmission */
11121 /* Number of RBs = No of REs / No of REs per RB */
11122 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11125 } /* rgSchUtlDlCalc1CwPrb*/
11128 * @brief Utility function to calculate total num of PRBs required to
11129 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11134 * Function : rgSchUtlDlCalc2CwPrb
11136 * Calculate PRBs required for UE to satisfy BO in DL
11138 * Note : Total calculated PRBs will be assigned to *prbReqrd
11141 * @param[in] RgSchCellCb *cell
11142 * @param[in] RgSchUeCb *ue
11143 * @param[in] U32 bo
11144 * @param[out] U32 *prbReqrd
11148 PUBLIC Void rgSchUtlDlCalc2CwPrb
11156 PUBLIC Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd)
11163 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
11164 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
11169 U8 cfi = dlCell->currCfi;
11171 TRC2(rgSchUtlDlCalc2CwPrb);
11173 if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
11174 (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
11176 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0];
11177 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
11179 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11180 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11181 noRes = ((U64)((bo << 3) << 10)) / (eff1);
11182 /* Get the number of RBs needed for this transmission */
11183 /* Number of RBs = No of REs / No of REs per RB */
11184 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11188 noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
11189 noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
11190 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
11191 iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
11192 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
11193 eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
11195 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
11196 * i.e, << 3 and multiply with 1024 i.e, << 10 */
11197 noRes = ((U64)((bo << 3) << 10)) / (eff1 + eff2);
11198 /* Get the number of RBs needed for this transmission */
11199 /* Number of RBs = No of REs / No of REs per RB */
11200 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
11203 } /* rgSchUtlDlCalc2CwPrb */
11206 * @brief Utility function to calculate total num of PRBs required to
11207 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
11211 * Function : rgSchUtlCalcTotalPrbReq
11213 * This function calls TM specific routine to calculate PRB
11216 * @param[in] RgSchCellCb *cell
11217 * @param[in] RgSchUeCb *ue
11218 * @param[in] U32 bo
11219 * @param[out] U32 *prbReqrd
11223 PUBLIC Void rgSchUtlCalcTotalPrbReq
11231 PUBLIC Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd)
11238 TRC2(rgSchUtlCalcTotalPrbReq);
11240 /* Call TM specific Prb calculation routine */
11241 (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
11244 } /* rgSchUtlCalcTotalPrbReq */
11247 /***********************************************************
11249 * Func : rgSCHUtlFetchPcqiBitSz
11252 * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
11261 **********************************************************/
11263 PRIVATE U8 rgSCHUtlFetchPcqiBitSz
11270 PRIVATE U8 rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt)
11279 RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
11281 TRC3(rgSCHUtlFetchPcqiBitSz);
11282 confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
11283 if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) &&
11284 (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
11290 ri = cqiCb->perRiVal;
11292 switch(confRepMode)
11294 case RGR_PRD_CQI_MOD10:
11300 case RGR_PRD_CQI_MOD11:
11313 else if(numTxAnt == 4)
11326 /* This is number of antenna case 1.
11327 * This is not applicable for Mode 1-1.
11328 * So setting it to invalid value */
11334 case RGR_PRD_CQI_MOD20:
11342 pcqiSz = 4 + cqiCb->label;
11347 case RGR_PRD_CQI_MOD21:
11362 else if(numTxAnt == 4)
11375 /* This might be number of antenna case 1.
11376 * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
11377 * So setting invalid value.*/
11385 pcqiSz = 4 + cqiCb->label;
11389 pcqiSz = 7 + cqiCb->label;
11405 * @brief Utility function to returns the number of subbands based on the
11410 * Function : rgSchUtlGetNumSbs
11412 * Calculate the number of PRBs
11413 * Update the subbandRequired based on the nPrbs and subband size
11415 * @param[in] RgSchCellCb *cell
11416 * @param[in] RgSchUeCb *ue
11417 * @param[in] U32 *numSbs
11421 PUBLIC U8 rgSchUtlGetNumSbs
11428 PUBLIC U8 rgSchUtlGetNumSbs (cell, ue, numSbs)
11435 //Currently hardcoding MAX prb for each UE
11436 nPrb = ue->ue5gtfCb.maxPrb;
11437 (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
11442 * @brief Utility function to insert the UE node into UE Lst based on the
11443 * number of subbands allocated for the UE for the current TTI.
11447 * Function : rgSchUtlSortInsUeLst
11449 * If subbandRequired < Min, then insert at head
11450 * Else If subbandRequired > Max, then insert at tail
11451 * Else, traverse the list and place the node at the appropriate place
11453 * @param[in] RgSchCellCb *cell
11454 * @param[in] RgSchUeCb *ue
11458 PUBLIC U8 rgSchUtlSortInsUeLst
11466 PUBLIC U8 rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired)
11474 CmLList *firstUeInLst;
11475 CmLList *lastUeInLst;
11477 RgSchCmnUlUe *ueUl;
11479 //firstUeInLst = cmLListFirst(ueLst);
11480 CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
11481 if(NULLP == firstUeInLst)
11483 /* first node to be added to the list */
11484 cmLListAdd2Tail(ueLst, node);
11488 /* Sb Required for the UE is less than the first node in the list */
11489 tempUe = (RgSchUeCb *)(firstUeInLst->node);
11490 ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
11492 if(vrbgRequired <= ueUl->vrbgRequired)
11494 cmLListInsCrnt(ueLst, (node));
11498 /* Sb Required for this UE is higher than the UEs in the list */
11499 lastUeInLst = cmLListLast(ueLst);
11500 tempUe = (RgSchUeCb *)(lastUeInLst->node);
11501 if(vrbgRequired >= ueUl->vrbgRequired)
11503 cmLListAdd2Tail(ueLst, (node));
11507 /* This UE needs to be in the middle. Search and insert the UE */
11508 ueInLst = cmLListFirst(ueLst);
11511 tempUe = (RgSchUeCb *)(ueInLst->node);
11513 if(vrbgRequired <= ueUl->vrbgRequired)
11515 cmLListInsCrnt(ueLst, (node));
11519 ueInLst = cmLListNext(ueLst);
11521 } while(NULLP != ueInLst && ueInLst != firstUeInLst);
11530 * @brief Function to Send LCG GBR register to MAC
11534 * Function: rgSCHUtlBuildNSendLcgReg
11536 * Handler for sending LCG GBR registration
11541 * Processing Steps:
11543 * @param[in] RgSchCellCb *cell
11544 * @param[in] CmLteRnti crnti
11545 * @param[in] U8 lcgId
11546 * @param[in] Bool isGbr
11551 PUBLIC S16 rgSCHUtlBuildNSendLcgReg
11559 PUBLIC S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr)
11567 RgInfLcgRegReq lcgRegReq;
11569 TRC3(rgSCHUtlBuildNSendLcgReg);
11571 cmMemset((U8*)&pst, (U8)0, sizeof(Pst));
11572 lcgRegReq.isGbr = isGbr;
11573 lcgRegReq.cellId = cell->cellId;
11574 lcgRegReq.crnti = crnti;
11575 lcgRegReq.lcgId = lcgId;
11576 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
11577 /* code Coverage portion of the test case */
11578 RgSchMacLcgReg(&pst, &lcgRegReq);
11587 * @brief Function to map RGR pucch type to TFU type
11591 * Function: rgSchUtlGetFdbkMode
11597 * Processing Steps:
11599 * @param[in] RgrSchFrmt1b3TypEnum
11600 * @return TfuAckNackMode
11604 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode
11606 RgrSchFrmt1b3TypEnum fdbkType
11609 PUBLIC TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType)
11610 RgrSchFrmt1b3TypEnum fdbkType;
11614 TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
11616 TRC2(rgSchUtlGetFdbkMode);
11620 case RG_SCH_UCI_FORMAT_NON_CA:
11621 case RG_SCH_UCI_FORMAT1A_1B:
11623 mode = TFU_UCI_FORMAT_1A_1B;
11626 case RG_SCH_UCI_FORMAT1B_CS:
11628 mode = TFU_UCI_FORMAT_1B_CS;
11631 case RG_SCH_UCI_FORMAT3:
11633 mode = TFU_UCI_FORMAT_3;
11639 #endif /* TFU_TDD */
11640 #endif /* LTE_ADV */
11641 #endif /*TFU_UPGRADE */
11645 * @brief Send Ue SCell delete to SMAC.
11649 * Function : rgSCHUtlSndUeSCellDel2Mac
11650 * This function populates the struct RgInfRlsRnti and
11651 * get the pst for SMac and mark field isUeSCellDel to TRUE which
11652 * indicates that it is a Ue SCell delete.
11656 * @param[in] RgSchCellCb *cell
11657 * @param[in] CmLteRnti rnti
11662 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac
11668 PUBLIC Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti)
11674 Inst inst = cell->instIdx;
11675 RgInfRlsRnti rntiInfo;
11677 TRC2(rgSCHUtlSndUeSCellDel2Mac)
11679 RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti));
11680 /* Copy the info to rntiInfo */
11681 rntiInfo.cellId = cell->cellId;
11682 rntiInfo.rnti = rnti;
11683 /* Fix : syed ueId change as part of reestablishment.
11684 * Now SCH to trigger this. CRG ueRecfg for ueId change
11686 rntiInfo.ueIdChng = FALSE;
11687 rntiInfo.newRnti = rnti;
11688 rntiInfo.isUeSCellDel = TRUE;
11689 /* Invoke MAC to release the rnti */
11690 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
11691 RgSchMacRlsRnti(&pst, &rntiInfo);
11696 * @brief Returns max TB supported by a given txMode
11700 * Function : rgSCHUtlGetMaxTbSupp
11701 * Max TB supported for TM Modes (1,2,5,6 and 7) is 1
11705 * @param[in] RgrTxMode txMode
11706 * @return U8 maxTbCount;
11710 PUBLIC U8 rgSCHUtlGetMaxTbSupp
11715 PUBLIC U8 rgSCHUtlGetMaxTbSupp(txMode)
11721 TRC2(rgSCHUtlGetMaxTbSupp);
11745 RETVALUE(maxTbCount);
11749 * @brief Send Ue SCell delete to SMAC.
11753 * Function : rgSCHTomUtlGetTrigSet
11754 * This function gets the triggerset based on cqiReq
11756 * @param[in] RgSchCellCb *cell
11757 * @param[in] RgSchUeCb ueCb
11758 * @param[in] U8 cqiReq,
11759 * @param[out] U8 *triggerSet
11765 PUBLIC Void rgSCHTomUtlGetTrigSet
11773 PRIVATE S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet)
11780 RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
11783 case RG_SCH_APCQI_SERVING_CC:
11785 /* APeriodic CQI request for Current Carrier.*/
11786 U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
11787 *triggerSet = 1 << (7 - sCellIdx);
11790 case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
11792 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
11795 case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
11797 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
11810 * @brief This function updates the value of UE specific DCI sizes
11814 * Function: rgSCHUtlUpdUeDciSize
11815 * Purpose: This function calculates and updates DCI Sizes in bits.
11817 * Invoked by: Scheduler
11819 * @param[in] RgSchCellCb *cell
11820 * @param[in] RgSchUeCb *ueCb
11821 * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI
11826 PUBLIC Void rgSCHUtlUpdUeDciSize
11833 PUBLIC Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit)
11839 U8 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11840 U8 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11841 if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
11843 dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
11844 dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
11846 if (isCsi2Bit == TRUE)
11848 dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
11852 dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
11855 /* Common CSI is always 1 bit DCI 0 */
11856 dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
11858 /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
11859 if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11861 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11863 if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11865 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11868 /* 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 */
11869 dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
11870 dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
11872 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize;
11873 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
11875 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize;
11876 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
11878 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11880 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11881 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11882 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11883 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11884 if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
11886 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
11889 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11890 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11891 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11892 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11893 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
11894 } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
11896 /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
11897 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11898 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11899 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11900 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11902 /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource
11903 * on a secondary cell without an uplink configuration associated with the secondary cell */
11904 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11905 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
11906 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11908 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11909 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11910 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11911 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11912 if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
11914 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
11917 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11918 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11919 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11920 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11921 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
11922 } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
11924 rgSCHEmtcUtlUpdUeDciSize(cell, ueCb);
11929 * @brief This function initialises the DCI Size table
11933 * Function: rgSCHUtlCalcDciSizes
11934 * Purpose: This function calculates and initialises DCI Sizes in bits.
11936 * Invoked by: Scheduler
11938 * @param[in] RgSchCellCb *cell
11943 PUBLIC Void rgSCHUtlCalcDciSizes
11948 PUBLIC Void rgSCHUtlCalcDciSizes(cell)
11954 U32 bits = 0, idx = 0;
11956 switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
11958 case TFU_DCI_FORMAT_0:
11960 /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
11962 /*-- Calculate resource block assignment bits need to be set
11963 Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
11964 bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
11965 while ((bits & 0x8000) == 0)
11972 dciSize = 1 /* DCI 0 bit indicator */ + \
11973 1 /* Frequency hoping enable bit field */ + \
11974 (U8)bits /* For frequency Hopping */ + \
11981 2 /* UL Index Config 0 or DAI Config 1-6 */
11985 cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
11987 /* If hoping flag is enabled */
11988 if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
11990 cell->dciSize.dci0HopSize = 1;
11994 cell->dciSize.dci0HopSize = 2;
11997 /* Update common non-CRNTI scrambled DCI 0/1A flag */
11998 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
12000 case TFU_DCI_FORMAT_1A:
12002 /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
12005 /* Calculate resource block assignment bits need to be set
12006 Which is ln(N(N+1)/2) */
12007 bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
12008 while ((bits & 0x8000) == 0)
12015 dciSize += 1 /* Format 1A */ + \
12016 1 /* Local or Distributed */ + \
12017 (U8)bits /* Resource block Assignment */ + \
12020 4 /* HARQ Proc Id */ +
12022 3 /* HARQ Proc Id */ +
12032 cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
12034 /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI,
12035 * and the number of information bits in format 1A is less than that of format 0,
12036 * zeros shall be appended to format 1A until the payload size equals that of format 0. */
12037 /* Compare the size with DCI 1A and DCI 0 and consider the greater one */
12038 if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
12040 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
12042 /* If the number of information bits in format 1A belongs to one of the sizes in
12043 * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
12044 dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
12045 cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
12047 case TFU_DCI_FORMAT_1:
12049 /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
12051 if (cell->bwCfg.dlTotalBw > 10)
12053 dciSize = 1; /* Resource Allocation header bit */
12056 /* Resouce allocation bits Type 0 and Type 1 */
12057 bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
12058 if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
12063 dciSize += (U8)bits /* Resource Allocation bits */ + \
12071 2 /* Redunancy Version */ + \
12080 cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
12082 cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
12085 /* If the UE is not configured to decode PDCCH with CRC
12086 * scrambled by the C-RNTI and the number of information bits in format 1
12087 * is equal to that for format 0/1A, one bit of value zero shall be appended
12089 if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
12091 cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
12094 /* If the number of information bits in format 1 belongs to one of the sizes in
12095 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until
12096 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1
12097 * and is not equal to that of format 0/1A mapped onto the same search space. */
12098 cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
12099 } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
12101 case TFU_DCI_FORMAT_2:
12103 /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
12105 if (cell->bwCfg.dlTotalBw > 10)
12107 dciSize = 1; /* Resource Allocation bit */
12110 dciSize += (U8)bits /* Resource Allocation bits */ + \
12118 1 /* CW Swap Flag */ + \
12119 5 /* MCS for TB1 */+ \
12120 1 /* NDI for TB1 */+ \
12121 2 /* RV for TB1 */ + \
12122 5 /* MCS for TB2 */+ \
12123 1 /* NDI for TB2 */+ \
12124 2 /* RV for TB2 */;
12125 if (cell->numTxAntPorts == 2)
12129 else if (cell->numTxAntPorts == 4)
12133 cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
12134 cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
12136 case TFU_DCI_FORMAT_2A:
12138 /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
12140 if (cell->bwCfg.dlTotalBw > 10)
12142 dciSize = 1; /* Resource Allocation bit */
12145 dciSize += (U8)bits /* Resource Allocation bits */ + \
12153 1 /* CW Swap Flag */ + \
12154 5 /* MCS for TB1 */+ \
12155 1 /* NDI for TB1 */+ \
12156 2 /* RV for TB1 */ + \
12157 5 /* MCS for TB2 */+ \
12158 1 /* NDI for TB2 */+ \
12159 2 /* RV for TB2 */;
12160 if (cell->numTxAntPorts == 4)
12164 cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
12165 cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
12166 rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
12168 case TFU_DCI_FORMAT_3:
12170 /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
12171 cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
12172 if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
12174 cell->dciSize.size[TFU_DCI_FORMAT_3]++;
12177 case TFU_DCI_FORMAT_3A:
12179 /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
12180 cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
12183 case TFU_DCI_FORMAT_6_0A:
12185 rgSCHEmtcGetDciFrmt60ASize(cell);
12187 case TFU_DCI_FORMAT_6_1A:
12189 rgSCHEmtcGetDciFrmt61ASize(cell);
12194 /* DCI format not supported */
12201 * @brief Handler for the CPU OvrLd related state adjustment.
12205 * Function : rgSCHUtlCpuOvrLdAdjItbsCap
12207 * Processing Steps:
12208 * - Record dl/ulTpts
12209 * - Adjust maxItbs to acheive target throughputs
12211 * @param[in] RgSchCellCb *cell
12215 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap
12220 PUBLIC Void rgSCHUtlCpuOvrLdAdjItbsCap(cell)
12226 TRC3(rgSCHUtlCpuOvrLdAdjItbsCap)
12228 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP |
12229 RGR_CPU_OVRLD_DL_TPT_DOWN))
12231 /* Regulate DL Tpt for CPU overload */
12232 if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
12234 tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
12235 /* Upto 0.5% drift in measured vs target tpt is ignored */
12236 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12238 cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
12243 tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
12244 /* Upto 0.5% drift in measured vs target tpt is ignored */
12245 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
12247 cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
12250 #ifdef CPU_OL_DBG_PRINTS
12251 printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt,
12252 cell->thresholds.maxDlItbs);
12256 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP |
12257 RGR_CPU_OVRLD_UL_TPT_DOWN))
12259 /* Regualte DL Tpt for CPU overload */
12260 if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
12262 tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
12263 /* Upto 1% drift in measured vs target tpt is ignored */
12264 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12266 cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
12271 tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
12272 /* Upto 1% drift in measured vs target tpt is ignored */
12273 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12275 cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
12278 #ifdef CPU_OL_DBG_PRINTS
12279 printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt,
12280 cell->thresholds.maxUlItbs);
12287 * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
12291 * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12293 * Processing Steps:
12294 * - Validate the config params.
12295 * - Update numUEperTTi CPU OL related information.
12296 * - If successful, return ROK else RFAILED.
12298 * @param[in] RgSchCellCb *cell
12299 * @param[in] U8 cnrtCpuOvrLdIns
12303 PRIVATE Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12309 PRIVATE S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns)
12311 U8 crntCpuOvrLdIns;
12314 RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl);
12315 RgSchCmnCell *cellSch;
12316 U8 maxUeNewDlTxPerTti;
12317 U8 maxUeNewUlTxPerTti;
12319 #ifdef CPU_OL_DBG_PRINTS
12325 cellSch = RG_SCH_CMN_GET_CELL(cell);
12327 maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti;
12328 maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
12330 /* Calculate Maximum Decremen */
12331 maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12332 maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12334 /* Check for DL CPU Commands */
12335 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI )
12337 /* Decrement till 90% of maxUeNewDlTxPerTti */
12338 if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
12340 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12341 cpuInstr->dlNxtIndxDecNumUeTti++;
12342 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] > 1 )
12344 cpuInstr->maxUeNewTxPerTti[tmpslot]--;
12348 #ifdef CPU_OL_DBG_PRINTS
12349 printf("CPU_OL_TTI__ERROR\n");
12351 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12354 #ifdef CPU_OL_DBG_PRINTS
12355 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12357 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12358 cpuInstr->dlNxtIndxDecNumUeTti);
12360 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
12362 if ( cpuInstr->dlNxtIndxDecNumUeTti > 0)
12364 cpuInstr->dlNxtIndxDecNumUeTti--;
12365 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12366 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] < maxUeNewDlTxPerTti )
12368 cpuInstr->maxUeNewTxPerTti[tmpslot]++;
12372 #ifdef CPU_OL_DBG_PRINTS
12373 printf("CPU_OL_TTI__ERROR\n");
12375 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12378 #ifdef CPU_OL_DBG_PRINTS
12379 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12381 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12382 cpuInstr->dlNxtIndxDecNumUeTti);
12384 /* Check for UL CPU commands */
12385 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
12387 /* Decrement till 90% of maxUeNewDlTxPerTti */
12388 if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
12390 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12391 cpuInstr->ulNxtIndxDecNumUeTti++;
12392 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] > 1 )
12394 cpuInstr->maxUeNewRxPerTti[tmpslot]--;
12398 #ifdef CPU_OL_DBG_PRINTS
12399 printf("CPU_OL_TTI__ERROR\n");
12401 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12404 #ifdef CPU_OL_DBG_PRINTS
12405 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12407 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12408 cpuInstr->dlNxtIndxDecNumUeTti);
12410 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
12412 if ( cpuInstr->ulNxtIndxDecNumUeTti > 0)
12414 cpuInstr->ulNxtIndxDecNumUeTti--;
12415 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12416 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] < maxUeNewUlTxPerTti )
12418 cpuInstr->maxUeNewRxPerTti[tmpslot]++;
12422 #ifdef CPU_OL_DBG_PRINTS
12423 printf("CPU_OL_TTI__ERROR\n");
12425 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12428 #ifdef CPU_OL_DBG_PRINTS
12429 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12431 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12432 cpuInstr->dlNxtIndxDecNumUeTti);
12434 #ifdef CPU_OL_DBG_PRINTS
12435 /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
12436 printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
12437 printf("DL Sf numUePerTti:");
12438 for ( idx = 0; idx < 10 ; idx ++ )
12440 printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]);
12442 printf("\nUL Sf numUePerTti:");
12443 for ( idx = 0; idx < 10 ; idx ++ )
12445 printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]);
12451 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
12454 * @brief Handler for the CPU OvrLd related cell Recfg.
12458 * Function : rgSCHUtlResetCpuOvrLdState
12460 * Processing Steps:
12461 * - Validate the config params.
12462 * - Update CPU OL related state information.
12463 * - If successful, return ROK else RFAILED.
12465 * @param[in] RgSchCellCb *cell
12466 * @param[in] U8 cnrtCpuOvrLdIns
12472 PUBLIC S16 rgSCHUtlResetCpuOvrLdState
12478 PUBLIC S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns)
12480 U8 crntCpuOvrLdIns;
12485 RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
12488 TRC3(rgSCHUtlResetCpuOvrLdState)
12490 #ifdef CPU_OL_DBG_PRINTS
12491 printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
12493 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd");
12495 if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
12497 /* The CPU OL instruction received with RESET (0), hence reset it */
12498 #ifdef CPU_OL_DBG_PRINTS
12499 printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
12501 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD");
12502 cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
12503 /* Reset the max UL and DL itbs to 26 */
12504 cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
12505 cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
12506 /* Reset the num UE per TTI intructions */
12507 cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
12508 cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
12509 for ( idx = 0; idx < 10; idx++ )
12511 cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] =
12512 schCmnCell->dl.maxUeNewTxPerTti;
12513 cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] =
12514 schCmnCell->ul.maxUeNewTxPerTti;
12519 /* Check and Update numUEPer TTI based CPU overload instruction before
12520 * going for TP based CPU OL
12521 * TTI based intrcuctions shall be > 0xF */
12522 if ( crntCpuOvrLdIns > 0xF )
12524 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
12525 /* If need to have both TP and numUePerTti instrcution together in
12526 * one command then dont return from here */
12530 crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
12531 (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
12532 if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) &&
12533 (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
12535 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12538 crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
12539 (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
12540 if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) &&
12541 (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
12543 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12546 if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
12548 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12552 cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
12556 if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
12558 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
12559 (cell->measurements.ulTpt * 3 )/100;
12563 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
12564 (cell->measurements.ulTpt * 2 )/100;
12566 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to "
12567 "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
12568 #ifdef CPU_OL_DBG_PRINTS
12569 printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
12570 cell->measurements.ulTpt);
12576 if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
12578 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
12579 (cell->measurements.dlTpt * 1 )/100;
12583 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
12584 (cell->measurements.dlTpt * 1 )/100;
12586 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to "
12587 "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
12589 #ifdef CPU_OL_DBG_PRINTS
12590 printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
12591 cell->measurements.dlTpt);
12594 rgSCHUtlCpuOvrLdAdjItbsCap(cell);
12598 PUBLIC S16 rgSCHUtlAddToResLst
12601 RgSchIotRes *iotRes
12604 cmLListAdd2Tail(cp, &iotRes->resLnk);
12605 iotRes->resLnk.node = (PTR)iotRes;
12608 PUBLIC S16 rgSCHUtlDelFrmResLst
12611 RgSchIotRes *iotRes
12614 CmLListCp *cp = NULLP;
12615 RgSchEmtcUeInfo *emtcUe = NULLP;
12616 emtcUe = RG_GET_EMTC_UE_CB(ue);
12617 if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
12619 cp = &emtcUe->ulResLst;
12620 }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
12622 cp = &emtcUe->dlResLst;
12625 RLOG0(L_INFO, "*****restype mismatch");
12631 RLOG0(L_INFO,"****error count*****\n");
12635 cmLListDelFrm(cp, &iotRes->resLnk);
12636 iotRes->resLnk.node = NULLP;
12640 /**********************************************************************
12643 **********************************************************************/