1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Entry point fucntions
29 **********************************************************************/
31 /** @file rg_sch_utl.c
32 @brief This file implements the schedulers main access to MAC layer code.
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_MODULE_ID=4096;
37 static int RLOG_FILE_ID=177;
39 /* header include files -- defines (.h) */
40 #include "common_def.h"
45 #include "rg_sch_err.h"
46 #include "rg_sch_inf.h"
48 #include "rg_sch_cmn.h"
50 #include "rl_interface.h"
51 #include "rl_common.h"
53 /* header/extern include files (.x) */
54 #include "tfu.x" /* TFU types */
55 #include "lrg.x" /* layer management typedefs for MAC */
56 #include "rgr.x" /* layer management typedefs for MAC */
58 #include "rg_sch_inf.x" /* typedefs for Scheduler */
59 #include "rg_sch.x" /* typedefs for Scheduler */
60 #include "rg_sch_cmn.x" /* typedefs for Scheduler */
62 #include "rg_sch_emtc_ext.x"
67 U32 rgNumPrachRecvd =0; /* Num of Rach Req received including dedicated preambles */
68 U32 rgNumRarSched =0; /* Num of RARs sent */
69 U32 rgNumBI =0; /* Num of BackOff Ind sent */
70 U32 rgNumMsg3CrcPassed =0; /* Num of CRC success for Msg3 */
71 U32 rgNumMsg3CrcFailed =0; /* Num of CRC fail for Msg 3 */
72 U32 rgNumMsg3FailMaxRetx =0; /* Num of Msg3 fail after Max Retx attempts */
73 U32 rgNumMsg4Ack =0; /* Num of Acks for Msg4 Tx */
75 /* Num of Nacks for Msg4 Tx */
76 U32 rgNumMsg4FailMaxRetx =0; /* Num of Msg4 Tx failed after Max Retx attempts */
77 U32 rgNumSrRecvd =0; /* Num of Sched Req received */
78 U32 rgNumSrGrant =0; /* Num of Sched Req Grants sent */
79 U32 rgNumMsg3CrntiCE =0; /* Num of Msg 3 CRNTI CE received */
80 U32 rgNumDedPream =0; /* Num of Dedicated Preambles recvd */
81 U32 rgNumMsg3CCCHSdu =0; /* Num of Msg 3 CCCH Sdus recvd */
82 U32 rgNumCCCHSduCrntiNotFound =0; /*UE Ctx not found for CCCH SDU Msg 3 */
83 U32 rgNumCrntiCeCrntiNotFound =0; /*UE Ctx not found for CRNTI CE Msg 3 */
84 U32 rgNumMsg4WithCCCHSdu =0; /* Num of Msg4 with CCCH Sdu */
85 U32 rgNumMsg4WoCCCHSdu =0; /* Num of Msg4 without CCCH Sdu */
86 U32 rgNumMsg4Dtx =0; /* Num of DTX received for Msg 4 */
87 U32 rgNumMsg3AckSent =0; /* Num of PHICH Ack sent for Msg 3 */
88 U32 rgNumMsg3NackSent =0; /* Num of PHICH Nack sent for Msg 3 */
89 U32 rgNumMsg4PdcchWithCrnti =0; /* Num of PDCCH for CRNTI based contention resolution */
90 U32 rgNumRarFailDuetoRntiExhaustion =0; /* Num of RACH Failures due to RNTI pool exhaution */
91 U32 rgNumTAModified =0; /* Num of times TA received is different from prev value */
92 U32 rgNumTASent =0; /* Num of TA Command sent */
93 U32 rgNumMsg4ToBeTx =0; /* Num of times MSG4 that should be sent */
94 U32 rgNumMsg4Txed =0; /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */
95 U32 rgNumMsg3DtxRcvd =0; /* CRC Fail with SINR < 0 */
97 U32 rgNumDedPreamUECtxtFound =0; /* Num of Dedicated Preambles recvd */
99 PRIVATE U8 rgSchDciAmbigSizeTbl[61] = {0,0,0,0,0,0,0,0,0,0,0,
100 0,1,0,1,0,1,0,0,0,1,
101 0,0,0,1,0,1,0,0,0,0,
102 0,1,0,0,0,0,0,0,0,1,
103 0,0,0,1,0,0,0,0,0,0,
104 0,0,0,0,0,1,0,0,0,0};
108 EXTERN U32 rgSchCmnBetaCqiOffstTbl[16];
109 EXTERN U32 rgSchCmnBetaRiOffstTbl[16];
110 EXTERN RgSchdApis rgSchCmnApis;
111 EXTERN S16 RgUiRgmSendPrbRprtInd ARGS((
114 RgmPrbRprtInd *prbRprtInd
117 EXTERN S16 RgUiRgmSendTmModeChangeInd ARGS((
120 RgmTransModeInd *txModeChngInd
123 EXTERN S16 rgSCHEmtcUtlGetSfAlloc ARGS((
126 EXTERN S16 rgSCHEmtcUtlPutSfAlloc ARGS((
129 EXTERN Void rgSCHEmtcUtlUpdUeDciSize ARGS((
133 EXTERN Void rgSCHEmtcGetDciFrmt61ASize ARGS((
136 EXTERN Void rgSCHEmtcGetDciFrmt60ASize ARGS((
139 EXTERN S16 rgSCHEmtcUtlFillPdschDciInfo ARGS((
140 TfuPdschDciInfo *pdsch,
143 EXTERN Void rgSCHEmtcUtlRlsRnti ARGS((
145 RgSchRntiLnk *rntiLnk,
148 EXTERN S16 rgSCHEmtcPdcchAlloc ARGS((
152 EXTERN Void rgSCHEmtcPdcchFree ARGS((
157 /* Functions specific to TM1/TM2/TM6/TM7 for PRB calculation*/
158 Void rgSchUtlDlCalc1CwPrb ARGS(( RgSchCellCb *cell,
163 /* Functions specific to TM3/TM4 for PRB calculation*/
164 Void rgSchUtlDlCalc2CwPrb ARGS(( RgSchCellCb *cell,
170 RgSchCellCb* rgSchUtlGetCellCb ARGS(( Inst inst,
175 typedef Void (*RgSchUtlDlCalcPrbFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
176 U32 bo, U32 *prbRequrd));
178 /* Functions specific to each transmission mode for PRB calculation*/
179 RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[7] = {rgSchUtlDlCalc1CwPrb,
180 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
181 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb};
184 /* Functions specific to each transmission mode for PRB calculation*/
185 RgSchUtlDlCalcPrbFunc dlCalcPrbFunc[9] = {rgSchUtlDlCalc1CwPrb,
186 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
187 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb, NULLP, NULLP};
192 /* The below table will be used to map the UL SF number in a TDD Cfg 0
193 frame to the ul Sf array maintained in cellCb */
194 PRIVATE U8 rgSchTddCfg0UlSfTbl[] = {2, 3, 4, 7, 8, 9};
197 PRIVATE S16 rgSCHUtlUlAllocDbInit ARGS((
202 PRIVATE Void rgSCHUtlUlAllocDbDeinit ARGS((
206 PRIVATE S16 rgSCHUtlUlHoleDbInit ARGS((
213 PRIVATE Void rgSCHUtlUlHoleDbDeinit ARGS((
218 PRIVATE S16 rgSCHChkBoUpdate ARGS((
220 RgInfCmnBoRpt *boUpdt
224 PRIVATE U8 rgSCHUtlFetchPcqiBitSz ARGS((
231 /* sorted in ascending order of tbSz */
232 CONSTANT struct rgSchUtlBcchPcchTbSz
234 U8 rbIndex; /* RB index {2,3} */
235 U16 tbSz; /* one of the Transport block size in bits of
237 /* Corrected allocation for common channels */
239 } rgSchUtlBcchPcchTbSzTbl[44] = {
240 { 2, 32, 0 }, { 2, 56, 1 }, { 2, 72, 2 }, { 3, 88, 1 },
241 { 2, 104, 3 }, { 2, 120, 4 }, { 2, 144, 5 }, { 2, 176, 6 },
242 { 3, 208, 4 }, { 2, 224, 7 }, { 2, 256, 8 }, { 2, 296, 9 },
243 { 2, 328, 10 }, { 2, 376, 11 }, { 3, 392, 8 }, { 2, 440, 12 },
244 { 3, 456, 9 }, { 2, 488, 13 }, { 3, 504, 10 }, { 2, 552, 14 },
245 { 3, 584, 11 }, { 2, 600, 15 }, { 2, 632, 16 }, { 3, 680, 12 },
246 { 2, 696, 17 }, { 3, 744, 13 }, { 2, 776, 18 }, { 2, 840, 19 },
247 { 2, 904, 20 }, { 3, 968, 16 }, { 2, 1000, 21 }, { 2, 1064, 22 },
248 { 2, 1128, 23 }, { 3, 1160, 18 }, { 2, 1192, 24 }, { 2, 1256, 25 },
249 { 3, 1288, 19 }, { 3, 1384, 20 }, { 2, 1480, 26 }, { 3, 1608, 22 },
250 { 3, 1736, 23 }, { 3, 1800, 24 }, { 3, 1864, 25 }, { 3, 2216, 26 }
257 /* forward references */
259 PRIVATE Void rgSCHUtlUpdPrachOcc ARGS((
261 RgrTddPrachInfo *cellCfg));
264 #define RGSCH_NUM_PCFICH_REG 4
265 #define RGSCH_NUM_REG_PER_CCE 9
266 #define RGSCH_NUM_REG_PER_PHICH_GRP 3
269 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _iPhich) {\
270 (_phich)->hqFeedBack = _hqFeedBack; \
271 (_phich)->rbStart = _rbStart; \
272 (_phich)->nDmrs = _nDmrs; \
273 (_phich)->iPhich = _iPhich; \
274 (_phich)->lnk.next = NULLP; \
275 (_phich)->lnk.prev = NULLP; \
276 (_phich)->lnk.node = (PTR)(_phich); \
279 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _isForMsg3) {\
280 (_phich)->hqFeedBack = _hqFeedBack; \
281 (_phich)->rbStart = _rbStart; \
282 (_phich)->nDmrs = _nDmrs; \
283 (_phich)->isForMsg3 = _isForMsg3; \
284 (_phich)->lnk.next = NULLP; \
285 (_phich)->lnk.prev = NULLP; \
286 (_phich)->lnk.node = (PTR)(_phich); \
290 #define RGSCH_PHICH_ALLOC(_inst,_dataPtr, _size, _ret) {\
291 _ret = rgSCHUtlAllocSBuf(_inst, (Data **)&_dataPtr, _size); \
294 /* ccpu00117052 - MOD - Passing double pointer
295 for proper NULLP assignment*/
296 #define RGSCH_PHICH_FREE(_inst, _dataPtr, _size) {\
297 rgSCHUtlFreeSBuf(_inst, (Data **)(&(_dataPtr)), _size); \
301 #define RGSCH_GETBIT(a, b) ((((U8*)a)[(b)>>3] >> ((7-((b)&7)))) & 1)
307 * Desc: This function finds of the Power of x raised to n
309 * Ret: value of x raised to n
323 F64 rgSCHUtlPower(x, n)
334 return ( x * rgSCHUtlPower( x, n-1 ) );
338 return ( (1/x) * rgSCHUtlPower( x, n+1 ) );
340 } /* end of rgSCHUtlPower*/
346 * Desc: This function parses bits x to y of an array and
347 * returns the integer value out of it.
349 * Ret: integer value of z bits
365 U32 rgSCHUtlParse(buff, startPos, endPos, buffSize)
372 U8 pointToChar,pointToEnd, loop;
373 U8 size = endPos - startPos;
375 pointToEnd = (startPos)%8;
376 for ( loop=0; loop<size; loop++)
378 pointToChar = (((startPos)+loop)/8);
379 if (RGSCH_GETBIT(buff+pointToChar,pointToEnd%8)==1)
381 result=result+(rgSCHUtlPower(2,(size-loop-1)));
385 return ((U32)result);
386 } /* end of rgSCHUtlParse*/
390 * Fun: rgSCHUtlFindDist
392 * Desc: This function calculates the iterations need to cover
393 * before the valid Index can be used for next possible Reception
395 * Ret: integer value of z bits
409 U8 rgSCHUtlFindDist(crntTime, tempIdx)
415 /* ccpu00137113- Distance is not estimated properly if the periodicity is
416 * equal to RG_SCH_PCQI_SRS_SR_TRINS_SIZE.
418 while(crntTime<=tempIdx)
420 crntTime += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
424 } /* end of rgSCHUtlFindDist*/
429 * @brief This function checks availability of a PDCCH
433 * Function: rgSCHUtlPdcchAvail
434 * Purpose: This function checks if a particular PDCCH is in use.
435 * map field of PDCCH is used to track the CCEs arleady
436 * allocated. Each bit of map represents one CCE and the
437 * LSBit of first byte represents CCE 0.
439 * 1. Locate the set of bits that represent the PDCCH for
440 * the provided location.
441 * 2. If the value of the bits is non-zero one or many CCEs
442 * for the PDCCH are in use and hence the PDCCH is not available.
443 * 3. If pdcch is available, assign it to [out]pdcch.
444 * 4. Set all of the bits to one. There is no check performed
445 * to see if the PDCCH is available.
447 * Invoked by: scheduler
449 * @param[in] RgSchCellCb* cell
450 * @param[in] RgSchPdcchInfo* pdcchInfo
452 * @param[in] U8 aggrLvl
453 * @param[out] RgSchPdcch** pdcch
455 * -# TRUE if available
460 Bool rgSCHUtlPdcchAvail
463 RgSchPdcchInfo *pdcchInfo,
464 CmLteAggrLvl aggrLvl,
468 Bool rgSCHUtlPdcchAvail(cell, pdcchInfo, aggrLvl, pdcch)
470 RgSchPdcchInfo *pdcchInfo;
471 CmLteAggrLvl aggrLvl;
479 Inst inst = cell->instIdx;
485 byte = &pdcchInfo->map[0];
486 initMask = (0xffff >> (16 - aggrLvl));
488 /* if N(symbol, xPDCCH) =2, then xPDCCH will be candidates in
489 * search space of index {0,1,2,3} and {8,9,..14}
491 if ((cell->cell5gtfCb.cfi == 2) && (aggrLvl == CM_LTE_AGGR_LVL2))
493 offsetStepMask = 0xc;
497 offsetStepMask = 0xc0;
500 /* Loop till the number of bytes available in the CCE map */
501 while (offset < ((pdcchInfo->nCce+ 7) >> 3))
503 byte = &pdcchInfo->map[offset];
504 /* Checking for available CCE */
505 if ((*byte & currMask) == 0)
509 /* if the number of CCEs required are not available, move to next offset */
510 if (currMask & offsetStepMask)
517 /* Move to the next available CCE index in the current byte(cce map) */
518 currMask = currMask << aggrLvl;
522 if ((offset >= ((pdcchInfo->nCce + 7) >> 3)) ||
523 ((aggrLvl == CM_LTE_AGGR_LVL16) && (offset > 0)))
528 byte = &pdcchInfo->map[offset];
530 if (cell->pdcchLst.first != NULLP)
532 *pdcch = (RgSchPdcch *)(cell->pdcchLst.first->node);
533 cmLListDelFrm(&cell->pdcchLst, cell->pdcchLst.first);
537 ret = rgSCHUtlAllocSBuf(inst, (Data **)pdcch, sizeof(RgSchPdcch));
547 /* ALL CCEs will be used in case of level 16 */
548 if (aggrLvl == CM_LTE_AGGR_LVL16)
550 *(byte+1) |= currMask;
552 (*pdcch)->aggrLvl = aggrLvl;
553 cmLListAdd2Tail(&pdcchInfo->pdcchs, &((*pdcch)->lnk));
554 (*pdcch)->lnk.node = (PTR)*pdcch;
555 (*pdcch)->nCce = aggrLvl;
556 (*pdcch)->ue = NULLP;
564 * @brief This function releases a PDCCH
568 * Function: rgSCHUtlPdcchPut
569 * Purpose: This function releases a PDCCH.
571 * 1. Locate the set of bits that represent the PDCCH for
572 * the provided location.
573 * 2. Set all of the bits to zero.
574 * 3. Release the memory of PDCCH to the cell free Q
576 * Invoked by: scheduler
578 * @param[in] RgSchPdcchInfo* pdcchInfo
580 * @param[in] U8 aggrLvl
585 Void rgSCHUtlPdcchPut
588 RgSchPdcchInfo *pdcchInfo,
592 Void rgSCHUtlPdcchPut(cell, pdcchInfo, pdcch)
594 RgSchPdcchInfo *pdcchInfo;
602 switch(pdcch->aggrLvl)
604 case CM_LTE_AGGR_LVL2:
605 offset = (pdcch->nCce >> 1) & 3;
606 mask = 0x3 << (offset * 2); /*ccpu00128826 - Offset Correction */
608 case CM_LTE_AGGR_LVL4:
609 offset = (pdcch->nCce >> 2) & 1;
610 mask = 0xf << (offset * 4);/*ccpu00128826 - Offset Correction */
612 case CM_LTE_AGGR_LVL8:
615 case CM_LTE_AGGR_LVL16:
621 /* Placing common computation of byte from all the cases above here
623 byte = &pdcchInfo->map[pdcch->nCce >> 3];
625 cmLListDelFrm(&pdcchInfo->pdcchs, &pdcch->lnk);
626 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
627 pdcch->lnk.node = (PTR)pdcch;
636 * @brief This function initializes PDCCH information for frame
640 * Function: rgSCHUtlPdcchInit
641 * Purpose: This function initializes PDCCH information for
642 * a slot. It removes the list of PDCCHs allocated
643 * in the prior use of this slot structure.
645 * Invoked by: rgSCHUtlSubFrmPut
647 * @param[in] RgSchCellCb* cell
648 * @param[in] RgSubFrm* subFrm
653 Void rgSCHUtlPdcchInit
660 Void rgSCHUtlPdcchInit(cell, subFrm, nCce)
666 RgSchPdcchInfo *pdcchInfo;
668 Inst inst = cell->instIdx;
672 pdcchInfo = &subFrm->pdcchInfo;
673 while(pdcchInfo->pdcchs.first != NULLP)
675 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
676 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
677 cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
680 cmLListInit(&pdcchInfo->pdcchs);
683 subFrm->relPdcch = NULLP;
686 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
688 /* The bitMap array size is the number of ceiling(CCEs/8) */
689 /* If nCce received is not the same as the one stored in
690 * pdcchInfo, free the pdcchInfo map */
692 if(pdcchInfo->nCce != nCce)
696 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), cceMapSz);
698 pdcchInfo->nCce = nCce;
699 cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
700 rgSCHUtlAllocSBuf(inst, (Data **)&pdcchInfo->map,
702 if (pdcchInfo->map == NULLP)
704 /* Generate log error here */
709 memset(subFrm->pdcchInfo.map, 0, cceMapSz);
710 /* If nCce is not exactly same as the bitMap size(no of bits allocated
711 * to represent the Cce's, then mark the extra bits as unavailable
712 extra bits = (((pdcchInfo->nCce + 7) >> 3)*8) - pdcchInfo->nCce
713 The last byte of bit map = subFrm->pdcchInfo.map[((pdcchInfo->nCce + 7) >> 3) - 1]
714 NOTE : extra bits are most significant of the last byte eg. */
715 extraBits = (cceMapSz)*8 - pdcchInfo->nCce;
716 subFrm->pdcchInfo.map[cceMapSz - 1] |=
717 ((1 << extraBits) - 1) << (8 - extraBits);
721 /* LTE_ADV_FLAG_REMOVED_START */
723 * @brief This function frees Pool
726 * Function: rgSchSFRTotalPoolFree
728 * Invoked by: rgSchSFRTotalPoolInit
730 * @param[in] RgSchCellCb* cell
731 * @param[in] RgSubFrm* subFrm
736 Void rgSchSFRTotalPoolFree
738 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo,
742 Void rgSchSFRTotalPoolFree(sfrTotalPoolInfo, cell)
743 RgSchSFRTotalPoolInfo *sfrTotalPoolInfo;
750 /*Deinitialise if these cc pools and ce pools are already existent*/
751 l = &sfrTotalPoolInfo->ccPool;
755 /*REMOVING Cell Centred POOLS IF ANY*/
756 n = cmLListDelFrm(l, n);
758 /* Deallocate buffer */
759 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
761 /* Deallocate buffer */
762 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
766 /*REMOVING Cell Edged POOLS IF ANY*/
767 l = &sfrTotalPoolInfo->cePool;
771 n = cmLListDelFrm(l, n);
773 /* Deallocate buffer */
774 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
776 /* Deallocate buffer */
777 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));
784 * @brief This function resets temporary variables in Pool
787 * Function: rgSchSFRResetPoolVariables
789 * Invoked by: rgSCHSFRUtlTotalPoolInit
791 * @param[in] RgSchCellCb* cell
792 * @param[in] RgSubFrm* subFrm
797 S16 rgSchSFRTotalPoolInit
803 PRIVATE Void rgSchSFRTotalPoolInit(cell, sf)
808 /* Initialise the variables */
809 RgSchSFRPoolInfo *sfrCCPool;
810 RgSchSFRPoolInfo *sfrCEPool;
813 CmLList *temp = NULLP;
816 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
817 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = 0;
818 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = 0;
819 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = 0;
820 sf->sfrTotalPoolInfo.CC1 = FALSE;
821 sf->sfrTotalPoolInfo.CC2 = FALSE;
822 /*Initialise the CE Pools*/
823 cmLListInit (&(sf->sfrTotalPoolInfo.cePool));
825 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
828 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
829 "CE Pool memory allocation FAILED for cell");
830 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
834 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
837 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
838 "CE Pool memory allocation FAILED for cell ");
839 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
843 l = &sf->sfrTotalPoolInfo.cePool;
844 cmLListAdd2Tail(l, temp);
846 /*Initialise Bandwidth and startRB and endRB for each pool*/
849 /* Initialise the CE Pools */
850 sfrCEPool = (RgSchSFRPoolInfo*)n->node;
852 sfrCEPool->poolstartRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb;
853 sfrCEPool->poolendRB = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb;
854 sfrCEPool->bw = sfrCEPool->poolendRB - sfrCEPool->poolstartRB + 1;
855 sf->sfrTotalPoolInfo.CEPoolBwAvlbl = sfrCEPool->bw;
857 sfrCEPool->bwAlloced = 0;
858 sfrCEPool->type2Start = sfrCEPool->poolstartRB;
859 sfrCEPool->type2End = RGSCH_CEIL(sfrCEPool->poolstartRB, cell->rbgSize);
860 sfrCEPool->type0End = ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1;
861 sfrCEPool->pwrHiCCRange.startRb = 0;
862 sfrCEPool->pwrHiCCRange.endRb = 0;
864 /*Initialise CC Pool*/
865 cmLListInit (&(sf->sfrTotalPoolInfo.ccPool));
867 /*Add memory and Update CCPool*/
868 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
871 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
872 "CC Pool memory allocation FAILED for cell ");
873 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
877 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
880 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
881 "CC Pool memory allocation FAILED for cell ");
882 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
886 l = &sf->sfrTotalPoolInfo.ccPool;
887 cmLListAdd2Tail(l, temp);
889 /*Initialise Bandwidth and startRB and endRB for each pool*/
890 if(sfrCEPool->poolstartRB)
893 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
895 sfrCCPool->poolstartRB = 0;
896 sfrCCPool->poolendRB = sfrCEPool->poolstartRB - 1;
897 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
898 sf->sfrTotalPoolInfo.CCPool1BwAvlbl = sfrCCPool->bw;
899 sfrCCPool->bwAlloced = 0;
900 sfrCCPool->type2Start = 0;
901 sfrCCPool->type2End = 0;
902 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
903 sf->sfrTotalPoolInfo.CC1 = TRUE;
904 sfrCCPool->pwrHiCCRange.startRb = 0;
905 sfrCCPool->pwrHiCCRange.endRb = 0;
910 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
912 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
913 sfrCCPool->poolendRB = sf->bw - 1;
914 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
915 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
916 sfrCCPool->CCPool2Exists = TRUE;
917 sfrCCPool->bwAlloced = 0;
918 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
919 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
920 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
921 sf->sfrTotalPoolInfo.CC2 = TRUE;
922 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
923 sfrCCPool->pwrHiCCRange.startRb = 0;
924 sfrCCPool->pwrHiCCRange.endRb = 0;
927 if((sfrCEPool->poolendRB != sf->bw - 1) && (!sfrCCPool->poolstartRB))
929 /*Add memory and Update CCPool*/
930 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
933 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
934 "CC Pool memory allocation FAILED for cell ");
935 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
939 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
942 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
943 "CC Pool memory allocation FAILED for cell ");
944 rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
948 cmLListAdd2Tail(l, temp);
951 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
953 sfrCCPool->poolstartRB = sfrCEPool->poolendRB + 1;
954 sfrCCPool->poolendRB = sf->bw - 1;
955 sfrCCPool->bw = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
956 sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
957 sfrCCPool->CCPool2Exists = TRUE;
958 sfrCCPool->bwAlloced = 0;
959 sfrCCPool->type2Start = sfrCCPool->poolstartRB;
960 sfrCCPool->type2End = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
961 sfrCCPool->type0End = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
962 sf->sfrTotalPoolInfo.CC2 = TRUE;
963 sfrCEPool->adjCCPool = sfrCCPool; /* SFR_FIX */
964 sfrCCPool->pwrHiCCRange.startRb = 0;
965 sfrCCPool->pwrHiCCRange.endRb = 0;
968 sf->sfrTotalPoolInfo.CCRetx = FALSE;
969 sf->sfrTotalPoolInfo.CERetx = FALSE;
971 sf->sfrTotalPoolInfo.ccBwFull = FALSE;
972 sf->sfrTotalPoolInfo.ceBwFull = FALSE;
973 sf->sfrTotalPoolInfo.isUeCellEdge = FALSE;
977 * @brief This function resets temporary variables in RNTP Prepration
980 * Function: rgSchDSFRRntpInfoInit
982 * Invoked by: rgSCHSFRUtlTotalPoolInit
984 * @param[in] TknStrOSXL* rntpPtr
985 * @param[in] RgSubFrm* subFrm
990 S16 rgSchDSFRRntpInfoInit
997 PRIVATE Void rgSchDSFRRntpInfoInit(rntpPtr, cell, bw)
1003 Inst inst = cell->instIdx;
1006 rntpPtr->pres = PRSNT_NODEF;
1008 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1012 /* Allocate memory for "scheduled UE" Info */
1013 if((rgSCHUtlAllocSBuf(inst, (Data**)&(rntpPtr->val),
1014 (len * sizeof(U8)))) != ROK)
1016 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
1024 * @brief This function release RNTP pattern from slot and Cell
1027 * Function: rgSchDSFRRntpInfoFree
1029 * Invoked by: rgSCHSFRUtlTotalPoolInit
1031 * @param[in] TknStrOSXL* rntpPtr
1032 * @param[in] RgSubFrm* subFrm
1037 S16 rgSchDSFRRntpInfoFree
1039 TknStrOSXL *rntpPtr,
1044 PRIVATE Void rgSchDSFRRntpInfoFree(rntpPtr, cell, bw)
1045 TknStrOSXL *rntpPtr;
1050 Inst inst = cell->instIdx;
1053 len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
1055 if(rntpPtr->pres == PRSNT_NODEF)
1057 rgSCHUtlFreeSBuf(inst, (Data **)(&(rntpPtr->val)),(len * sizeof(U8)));
1058 rntpPtr->pres = NOTPRSNT;
1066 * @brief This function resets temporary variables in Pool
1069 * Function: rgSchSFRResetPoolVariables
1070 * Purpose: Initialise the dynamic variables in each pool.
1071 * Reset bwAlloced, bwAssigned, type2End, type0End, type2Start
1072 * Invoked by: rgSCHSFRUtlTotalPoolReset
1074 * @param[in] RgSchCellCb* cell
1075 * @param[in] RgSchSFRPoolInfo *pool
1080 PRIVATE Void rgSchSFRResetPoolVariables
1083 RgSchSFRPoolInfo *pool
1086 PRIVATE Void rgSchSFRResetPoolVariables(cell, pool)
1088 RgSchSFRPoolInfo *pool;
1092 pool->bwAlloced = 0;
1094 /*type0end will be the last RBG in pool with all available RBs*/
1095 pool->type0End = (((pool->poolendRB + 1)/cell->rbgSize) - 1);
1097 /*type2end will be the first RBG in pool with all available RBs*/
1098 pool->type2End = RGSCH_CEIL(pool->poolstartRB, cell->rbgSize);
1099 pool->type2Start = pool->poolstartRB;
1100 pool->bw = pool->poolendRB - pool->poolstartRB + 1;
1105 * @brief This function resets SFR Pool information for frame
1109 * Function: rgSCHSFRUtlTotalPooReset
1110 * Purpose: Update the dynamic variables in each pool as they will be modified in each slot.
1111 * Dont modify the static variables like startRB, endRB, BW
1112 * Invoked by: rgSCHUtlSubFrmPut
1114 * @param[in] RgSchCellCb* cell
1115 * @param[in] RgSchDlSf* subFrm
1120 PRIVATE Void rgSCHSFRUtlTotalPoolReset
1126 PRIVATE Void rgSCHSFRUtlTotalPoolReset(cell, subFrm)
1131 RgSchSFRTotalPoolInfo *totalPoolInfo = &subFrm->sfrTotalPoolInfo;
1132 CmLListCp *ccPool = &totalPoolInfo->ccPool;
1133 CmLListCp *cePool = &totalPoolInfo->cePool;
1134 CmLList *node = NULLP;
1135 RgSchSFRPoolInfo *tempPool = NULLP;
1137 totalPoolInfo->ccBwFull = FALSE;
1138 totalPoolInfo->ceBwFull = FALSE;
1139 totalPoolInfo->isUeCellEdge = FALSE;
1140 totalPoolInfo->CCPool1BwAvlbl = 0;
1141 totalPoolInfo->CCPool2BwAvlbl = 0;
1142 totalPoolInfo->CEPoolBwAvlbl = 0;
1143 totalPoolInfo->CCRetx = FALSE;
1144 totalPoolInfo->CERetx = FALSE;
1146 node = ccPool->first;
1149 tempPool = (RgSchSFRPoolInfo *)(node->node);
1151 rgSchSFRResetPoolVariables(cell, tempPool);
1152 if(tempPool->poolstartRB == 0)
1153 totalPoolInfo->CCPool1BwAvlbl = tempPool->bw;
1155 totalPoolInfo->CCPool2BwAvlbl = tempPool->bw;
1158 node = cePool->first;
1161 tempPool = (RgSchSFRPoolInfo *)(node->node);
1163 rgSchSFRResetPoolVariables(cell, tempPool);
1164 totalPoolInfo->CEPoolBwAvlbl = tempPool->bw;
1169 /* LTE_ADV_FLAG_REMOVED_END */
1171 * @brief This function appends PHICH information for frame
1175 * Function: rgSCHUtlAddPhich
1176 * Purpose: This function appends PHICH information for
1181 * @param[in] RgSchCellCb* cell
1182 * @param[in] RgSubFrm* subFrm
1183 * @param[in] U8 hqFeedBack
1184 * @param[in] U8 nDmrs
1185 * @param[in] U8 rbStart
1192 S16 rgSCHUtlAddPhich
1195 CmLteTimingInfo frm,
1202 S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, iPhich)
1204 CmLteTimingInfo frm;
1212 S16 rgSCHUtlAddPhich
1215 CmLteTimingInfo frm,
1222 S16 rgSCHUtlAddPhich(cell, frm, hqFeedBack, nDmrs, rbStart, isForMsg3)
1224 CmLteTimingInfo frm;
1235 Inst inst = cell->instIdx;
1237 dlSf = rgSCHUtlSubFrmGet(cell, frm);
1238 RGSCH_PHICH_ALLOC(inst, phich,sizeof(RgSchPhich), ret);
1242 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, " rgSCHUtlAddPhich(): "
1243 "Allocation of RgSchPhich failed");
1247 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, iPhich);
1249 RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, isForMsg3); /*SR_RACH_STATS */
1251 cmLListAdd2Tail(&dlSf->phichInfo.phichs, &phich->lnk);
1253 } /* rgSCHUtlAddPhich */
1256 * @brief This function resets PHICH information for frame
1260 * Function: rgSCHUtlPhichReset
1261 * Purpose: This function initializes PHICH information for
1262 * a slot. It removes the list of PHICHs allocated
1263 * in the prior use of this slot structure.
1265 * Invoked by: rgSCHUtlSubFrmPut
1267 * @param[in] RgSchCellCb* cell
1268 * @param[in] RgSubFrm* subFrm
1273 PRIVATE Void rgSCHUtlPhichReset
1279 PRIVATE Void rgSCHUtlPhichReset(cell, subFrm)
1284 RgSchPhichInfo *phichInfo;
1289 phichInfo = &subFrm->phichInfo;
1290 while(phichInfo->phichs.first != NULLP)
1292 phich = (RgSchPhich *)phichInfo->phichs.first->node;
1293 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
1294 RGSCH_PHICH_FREE(cell->instIdx, phich, sizeof(RgSchPhich));
1296 cmLListInit(&phichInfo->phichs);
1298 } /* rgSCHUtlPhichReset */
1302 * @brief This function returns slot data structure for a cell
1306 * Function: rgSCHUtlSubFrmGet
1307 * Purpose: This function resets the slot data structure
1308 * when the slot is released
1310 * Invoked by: scheduler
1312 * @param[in] RgSubFrm subFrm
1317 RgSchDlSf* rgSCHUtlSubFrmGet
1323 RgSchDlSf* rgSCHUtlSubFrmGet(cell, frm)
1325 CmLteTimingInfo frm;
1332 dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
1333 //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1334 sf = cell->subFrms[dlIdx];
1336 /* Changing the idexing
1337 so that proper slot is selected */
1338 dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
1339 RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1340 sf = cell->subFrms[dlIdx];
1350 * @brief This function returns slot data structure for a cell
1354 * Function: rgSCHUtlSubFrmPut
1355 * Purpose: This function resets the slot data structure
1356 * when the slot is released
1358 * Invoked by: scheduler
1360 * @param[in] RgSubFrm subFrm
1365 Void rgSCHUtlSubFrmPut
1371 Void rgSCHUtlSubFrmPut(cell, sf)
1380 /* Release all the held PDCCH information */
1381 rgSCHUtlPdcchInit(cell, sf, sf->nCce);
1383 /* Release all the held PDCCH information */
1384 rgSCHUtlPdcchInit(cell, sf, cell->nCce);
1386 rgSCHUtlPhichReset(cell, sf);
1388 /* Reset the bw allocated. */
1391 /* Setting allocated bandwidth to SPS bandwidth for non-SPS RB allocator */
1392 sf->bwAlloced = ((cell->spsCellCfg.maxSpsDlBw +
1393 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
1394 if (sf->bwAlloced > sf->bw)
1396 sf->bwAlloced = sf->bw;
1398 sf->spsAllocdBw = 0;
1399 sf->type2Start = sf->bwAlloced;
1400 memset( &sf->dlSfAllocInfo, 0, sizeof(RgSchDlSfAllocInfo));
1403 /* Fix for ccpu00123918*/
1405 /* LTE_ADV_FLAG_REMOVED_START */
1406 /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
1407 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
1409 memset(sf->rntpInfo.val, 0, sf->rntpInfo.len);
1411 /* LTE_ADV_FLAG_REMOVED_END */
1414 /*[ccpu00138609]-ADD-Reset the CCCH UE counter */
1417 /* Non DLFS scheduling using Type0 RA requires the following
1418 * parameter's tracking */
1419 /* Type 2 localized allocations start from 0th RBG and onwards */
1420 /* Type 0 allocations start from last RBG and backwards*/
1424 sf->type2End = RGSCH_CEIL(sf->bwAlloced,cell->rbgSize);
1426 sf->type0End = cell->noOfRbgs - 1;
1427 /* If last RBG is of incomplete size then special handling */
1428 (sf->bw % cell->rbgSize == 0)? (sf->lstRbgDfct = 0) :
1429 (sf->lstRbgDfct = cell->rbgSize - (sf->bw % cell->rbgSize));
1430 /* This resets the allocation for BCCH and PDCCH */
1432 /* TODO we need to move this reset for emtc functions */
1433 if(!(cell->emtcEnable))
1442 sf->bcch.pdcch = NULLP;
1443 sf->pcch.pdcch = NULLP;
1445 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
1447 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
1449 for (i = 0; i < noRaRsps; i++)
1451 sf->raRsp[i].pdcch = NULLP;
1452 cmLListInit(&(sf->raRsp[i].raRspLst));
1454 /* LTE_ADV_FLAG_REMOVED_START */
1455 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
1457 rgSCHSFRUtlTotalPoolReset(cell, sf);
1459 /* LTE_ADV_FLAG_REMOVED_END */
1461 cmLListInit(&sf->n1PucchResLst);
1465 sf->isCceFailure = FALSE;
1466 sf->dlUlBothCmplt = 0;
1472 * @brief This function computes log N (32 bit Unsigned) to the base 2
1476 * Function: rgSCHUtlLog32bitNbase2
1477 * Purpose: This function computes log N (32 bit Unsigned) to the base 2.
1478 * For n= 0,1 ret = 0.
1480 * Invoked by: Scheduler
1487 U8 rgSCHUtlLog32bitNbase2
1492 U8 rgSCHUtlLog32bitNbase2(n)
1496 U32 b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
1497 U32 s[] = {1, 2, 4, 8, 16};
1501 for (i=4; i >= 0; i--)
1515 * @brief This function is a wrapper to call scheduler specific API.
1519 * Function: rgSCHUtlDlRelPdcchFbk
1520 * Purpose: Calls scheduler's handler for SPS release PDCCH feedback
1525 * @param[in] RgSchCellCb *cell
1526 * @param[in] RgSchUeCb *ue
1527 * @param[in] U8 isAck
1532 Void rgSCHUtlDlRelPdcchFbk
1539 Void rgSCHUtlDlRelPdcchFbk(cell, ue, isAck)
1545 cell->sc.apis->rgSCHDlRelPdcchFbk(cell, ue, isAck);
1552 * @brief This function is a wrapper to call scheduler specific API.
1556 * Function: rgSCHUtlDlProcAck
1557 * Purpose: Calls scheduler's handler to process Ack
1562 * @param[in] RgSchCellCb *cell
1563 * @param[in] RgSchDlHqProcCb *hqP
1568 Void rgSCHUtlDlProcAck
1571 RgSchDlHqProcCb *hqP
1574 Void rgSCHUtlDlProcAck(cell, hqP)
1576 RgSchDlHqProcCb *hqP;
1579 cell->sc.apis->rgSCHDlProcAck(cell, hqP);
1584 * @brief CRNTI CE Handler
1588 * Function : rgSCHUtlHdlCrntiCE
1590 * - Call scheduler common API
1593 * @param[in] RgSchCellCb *cell
1594 * @param[in] RgSchUeCb *ue
1595 * @param[out] RgSchErrInfo *err
1599 Void rgSCHUtlHdlCrntiCE
1605 Void rgSCHUtlHdlCrntiCE(cell, ue)
1611 cell->sc.apis->rgSCHHdlCrntiCE(cell, ue);
1613 } /* rgSCHUtlHdlCrntiCE */
1614 #endif /* LTEMAC_SPS */
1616 /***********************************************************
1618 * Func : rgSCHUtlCalcTotalRegs
1620 * Desc : Calculate total REGs, given a bandwidth, CFI
1621 * and number of antennas.
1623 * Ret : Total REGs (U16)
1625 * Notes: Could optimise if bw values are limited
1626 * (taken from RRC spec) by indexing values from
1628 * Input values are not validated. CFI is assumed
1633 **********************************************************/
1635 PRIVATE U16 rgSCHUtlCalcTotalRegs
1643 PRIVATE U16 rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp)
1652 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1658 /* Refer 36.211 section 6.10.1.2
1659 * For symbols 2 and 4, the REGs per RB will be based on cyclic prefix
1660 * and number of antenna ports.
1661 * For symbol 1, there are 2 REGs per RB always. Similarly symbol 3
1665 /*CR changes [ccpu00124416] - MOD*/
1668 regs = bw * RGSCH_NUM_REGS_4TH_SYM_EXT_CP;
1672 regs = bw * RGSCH_NUM_REGS_4TH_SYM_NOR_CP;
1675 regs += bw * RGSCH_NUM_REGS_3RD_SYM;
1677 /*CR changes [ccpu00124416] - MOD using number of antenna ports*/
1678 regs += (numAntna == RGSCH_NUM_ANT_PORT_FOUR) ? \
1679 (bw * RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT) : \
1680 (bw * RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT);
1681 default: /* case 1 */
1682 regs += bw * RGSCH_NUM_REGS_1ST_SYM;
1687 /***********************************************************
1689 * Func : rgSCHUtlCalcPhichRegs
1691 * Desc : Calculates number of PHICH REGs
1693 * Ret : Number of PHICH REGs (U8)
1695 * Notes: ng6 is Ng multiplied by 6
1699 **********************************************************/
1701 PRIVATE U16 rgSCHUtlCalcPhichRegs
1707 PRIVATE U16 rgSCHUtlCalcPhichRegs(bw, ng6)
1712 /* ccpu00115330: Corrected the calculation for number of PHICH groups*/
1713 return (RGSCH_CEIL((bw * ng6) ,(8 * 6)) * RGSCH_NUM_REG_PER_PHICH_GRP);
1718 * @brief Calculates total CCEs (N_cce)
1722 * Function: rgSCHUtlCalcNCce
1723 * Purpose: This function calculates and returns total CCEs for a
1724 * cell, given the following: bandwidth, Ng configuration
1725 * (multiplied by six), cfi (actual number of control
1726 * symbols), m factor for PHICH and number of antennas.
1728 * Invoked by: Scheduler
1733 * @param[in] U8 mPhich
1734 * @param[in] U8 numAntna
1735 * @param[in] Bool isEcp
1736 * @return N_cce (U8)
1750 U8 rgSCHUtlCalcNCce(bw, ng, cfi, mPhich, numAntna, isEcp)
1764 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1768 case RGR_NG_ONESIXTH:
1783 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1784 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1785 cceRegs = totalRegs - mPhich*phichRegs - RGSCH_NUM_PCFICH_REG;
1787 return ((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1792 * @brief Calculates total CCEs (N_cce)
1796 * Function: rgSCHUtlCalcNCce
1797 * Purpose: This function calculates and returns total CCEs for a
1798 * cell, given the following: bandwidth, Ng configuration
1799 * (multiplied by six), cfi (actual number of control
1800 * symbols) and number of antennas.
1802 * Invoked by: Scheduler
1807 * @param[in] U8 numAntna
1808 * @return N_cce (U8)
1821 U8 rgSCHUtlCalcNCce(bw, ng, cfi, numAntna, isEcp)
1834 /*ccpu00116757- removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1838 case RGR_NG_ONESIXTH:
1853 totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1854 phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1855 cceRegs = totalRegs - phichRegs - RGSCH_NUM_PCFICH_REG;
1857 return ((U8)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1862 * @brief Returns PHICH info associated with an uplink
1863 * HARQ process allocation
1867 * Function: rgSCHUtlGetPhichInfo
1868 * Purpose: This function returns PHICH info associated with
1869 * an uplink HARQ process allocation. PHICH info
1870 * comprises RB start and N_dmrs.
1872 * @param[in] RgSchUlHqProcCb *hqProc
1873 * @param[out] U8 *rbStartRef
1874 * @param[out] U8 *nDmrsRef
1879 S16 rgSCHUtlGetPhichInfo
1881 RgSchUlHqProcCb *hqProc,
1887 S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef, iPhich)
1888 RgSchUlHqProcCb *hqProc;
1895 S16 rgSCHUtlGetPhichInfo
1897 RgSchUlHqProcCb *hqProc,
1902 S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef)
1903 RgSchUlHqProcCb *hqProc;
1912 if ((hqProc != NULLP) && (hqProc->alloc != NULLP))
1914 *rbStartRef = hqProc->alloc->grnt.rbStart;
1915 *nDmrsRef = hqProc->alloc->grnt.nDmrs;
1917 *iPhich = hqProc->iPhich;
1925 * @brief Returns uplink grant information required to permit
1926 * PHY to receive data
1930 * Function: rgSCHUtlAllocRcptInfo
1931 * Purpose: Given an uplink allocation, this function returns
1932 * uplink grant information which is needed by PHY to
1933 * decode data sent from UE. This information includes:
1938 * @param[in] RgSchUlAlloc *alloc
1939 * @param[out] U8 *rbStartRef
1940 * @param[out] U8 *numRbRef
1941 * @param[out] U8 *rvRef
1942 * @param[out] U16 *size
1943 * @param[out] TfuModScheme *modType
1944 * @param[out] Bool *isRtx
1945 * @param[out] U8 *nDmrs
1946 * @param[out] Bool *ndi
1947 * @param[out] U8 *hqPId
1951 S16 rgSCHUtlAllocRcptInfo
1953 RgSchUlAlloc *alloc,
1960 TfuModScheme *modType,
1967 S16 rgSCHUtlAllocRcptInfo(alloc, rnti, iMcsRef, rbStartRef, numRbRef,
1968 rvRef, size, modType, isRtx, nDmrs, ndi,
1970 RgSchUlAlloc *alloc;
1977 TfuModScheme *modType;
1984 /* Modulation order for 16qam UEs would be
1985 * min(4,modulation order in grant). Please refer to 36.213-8.6.1*/
1986 CmLteUeCategory ueCtgy;
1988 #if (ERRCLASS & ERRCLS_DEBUG)
1989 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
1995 if ( !alloc->forMsg3 )
1997 if ( ((alloc->ue) == NULLP) || (RG_SCH_CMN_GET_UE(alloc->ue, alloc->ue->cell) == NULLP))
1999 RLOG_ARG2(L_ERROR,DBG_CELLID,alloc->ue->cell->cellId,
2000 "Failed: ue->sch is null RNTI:%d,isRetx=%d",
2001 alloc->rnti, alloc->grnt.isRtx);
2004 ueCtgy = (RG_SCH_CMN_GET_UE_CTGY(alloc->ue));
2007 *iMcsRef = alloc->grnt.iMcs;
2008 *rbStartRef = alloc->grnt.rbStart;
2009 *numRbRef = alloc->grnt.numRb;
2010 *rvRef = rgRvTable[alloc->hqProc->rvIdx];
2011 *rnti = alloc->rnti;
2012 *size = alloc->grnt.datSz;
2013 *modType = (alloc->forMsg3)? alloc->grnt.modOdr:
2014 ((ueCtgy == CM_LTE_UE_CAT_5)?
2016 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)));
2017 *isRtx = alloc->grnt.isRtx;
2018 *nDmrs = alloc->grnt.nDmrs;
2019 *ndi = alloc->hqProc->ndi;
2020 *hqPId = alloc->hqProc->procId;
2026 * @brief Returns uplink grant information required to permit
2027 * PHY to receive data
2031 * Function: rgSCHUtlAllocRcptInfo
2032 * Purpose: Given an uplink allocation, this function returns
2033 * uplink grant information which is needed by PHY to
2034 * decode data sent from UE. This information includes:
2039 * @param[in] RgSchUlAlloc *alloc
2040 * @param[out] U8 *rbStartRef
2041 * @param[out] U8 *numRbRef
2042 * @param[out] U8 *rvRef
2043 * @param[out] U16 *size
2044 * @param[out] TfuModScheme *modType
2048 S16 rgSCHUtlAllocRcptInfo
2051 RgSchUlAlloc *alloc,
2052 CmLteTimingInfo *timeInfo,
2053 TfuUeUlSchRecpInfo *recpReq
2056 S16 rgSCHUtlAllocRcptInfo(cell, alloc, timeInfo, recpReq)
2058 RgSchUlAlloc *alloc;
2059 CmLteTimingInfo *timeInfo;
2060 TfuUeUlSchRecpInfo *recpReq;
2063 #if (ERRCLASS & ERRCLS_DEBUG)
2064 if ((alloc == NULLP) || (alloc->hqProc == NULLP))
2069 recpReq->size = alloc->grnt.datSz;
2070 recpReq->rbStart = alloc->grnt.rbStart;
2071 recpReq->numRb = alloc->grnt.numRb;
2072 /* Modulation order min(4,mod in grant) for 16 qam UEs.
2073 * Please refer to 36.213-8.6.1*/
2074 #ifdef FOUR_TX_ANTENNA
2075 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2076 (/*(alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2077 alloc->grnt.modOdr: *//* Chandra:TmpFx-TM500 Cat5 with Only16QAM */
2078 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2080 recpReq->modType = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
2081 ((alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
2083 (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
2085 recpReq->nDmrs = alloc->grnt.nDmrs;
2086 recpReq->hoppingEnbld = FALSE;
2087 recpReq->hoppingBits = 0;
2088 recpReq->isRtx = alloc->grnt.isRtx;
2089 recpReq->ndi = alloc->hqProc->ndi;
2090 recpReq->rv = rgRvTable[alloc->hqProc->rvIdx];
2092 recpReq->harqProcId = alloc->hqProc->procId;
2094 recpReq->harqProcId = rgSCHCmnGetUlHqProcIdx(timeInfo, cell);
2096 /* Transmission mode is SISO till Uplink MIMO is implemented. */
2097 recpReq->txMode = 0;
2098 /* This value needs to filled in in the case of frequency hopping. */
2099 recpReq->crntTxNb = 0;
2101 recpReq->mcs = alloc->grnt.iMcs;
2103 recpReq->rbgStart = alloc->grnt.vrbgStart;
2104 recpReq->numRbg = alloc->grnt.numVrbg;
2105 recpReq->xPUSCHRange = alloc->grnt.xPUSCHRange;
2106 //TODO_SID Need to check
2107 recpReq->nAntPortLayer = 0;
2108 recpReq->SCID = alloc->grnt.SCID;
2109 recpReq->PMI = alloc->grnt.PMI;
2110 recpReq->uciWoTBFlag = alloc->grnt.uciOnxPUSCH;
2113 recpReq->beamIndex = alloc->ue->ue5gtfCb.BeamId;
2118 if (!alloc->forMsg3)
2120 if (alloc->grnt.isRtx)
2122 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulRetxOccns++;
2126 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulTxOccns++;
2127 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulSumiTbs += \
2128 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2129 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulNumiTbs ++;
2130 cell->tenbStats->sch.ulSumiTbs += \
2131 rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
2132 cell->tenbStats->sch.ulNumiTbs ++;
2134 alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulPrbUsg += alloc->grnt.numRb;
2135 cell->tenbStats->sch.ulPrbUsage[0] += alloc->grnt.numRb;
2138 /* ccpu00117050 - DEL - nSrs setting at rgSCHUtlAllocRcptInfo */
2145 * @brief This function initialises the PRACH slot occasions
2149 * Function: rgSCHUtlUpdPrachOcc
2150 * Purpose: This function updates the PRACH slots based on
2151 * RGR configuration.
2153 * Invoked by: Scheduler
2155 * @param[in] RgSchCellCb *cell
2156 * @param[in] RgrTddPrachInfo *cellCfg
2161 PRIVATE Void rgSCHUtlUpdPrachOcc
2164 RgrTddPrachInfo *cellCfg
2167 PRIVATE Void rgSCHUtlUpdPrachOcc(cell, cellCfg)
2169 RgrTddPrachInfo *cellCfg;
2178 /* In the 1st half frame */
2179 if(cellCfg->halfFrm == 0)
2184 /* In the 2nd half frame */
2190 for(idx = startIdx; idx < endIdx; idx++)
2192 if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
2193 == RG_SCH_TDD_UL_slot)
2195 if(cellCfg->ulStartSfIdx == count)
2197 size = cell->rachCfg.raOccasion.size;
2198 cell->rachCfg.raOccasion.slotNum[size] = idx;
2199 cell->rachCfg.raOccasion.size++;
2209 * @brief This function initialises the PRACH occasions
2213 * Function: rgSCHUtlPrachCfgInit
2214 * Purpose: This function initialises the PRACH occasions based on
2215 * RGR configuration.
2217 * Invoked by: Scheduler
2219 * @param[in] RgSchCellCb *cell
2220 * @param[in] RgrCellCfg *cellCfg
2225 Void rgSCHUtlPrachCfgInit
2231 Void rgSCHUtlPrachCfgInit(cell, cellCfg)
2233 RgrCellCfg *cellCfg;
2240 if(cellCfg->prachRscInfo.numRsc <= 0)
2242 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "Invalid"
2243 "PRACH resources Configuration ");
2247 /* Update SFN occasions */
2248 cell->rachCfg.raOccasion.sfnEnum =
2249 cellCfg->prachRscInfo.prachInfo[0].sfn;
2251 cell->rachCfg.raOccasion.size = 0;
2253 /* Update slot occasions */
2254 for(idx = 0; idx < cellCfg->prachRscInfo.numRsc; idx++)
2256 if(cellCfg->prachRscInfo.prachInfo[idx].freqIdx == 0)
2258 if(cellCfg->prachRscInfo.prachInfo[idx].halfFrm == 0)
2266 if(cellCfg->prachRscInfo.prachInfo[idx].ulStartSfIdx ==
2269 subfrmIdx = cell->rachCfg.raOccasion.size;
2270 cell->rachCfg.raOccasion.slotNum[subfrmIdx] = splFrm;
2271 cell->rachCfg.raOccasion.size++;
2275 rgSCHUtlUpdPrachOcc(cell,
2276 &cellCfg->prachRscInfo.prachInfo[idx]);
2284 * @brief This function performs RGR cell initialization
2288 * Function: rgSCHUtlRgrCellCfg
2289 * Purpose: This function initialises the cell with RGR configuration
2290 * and slot related initialization.
2292 * Invoked by: Scheduler
2294 * @param[in] RgSchCellCb *cell
2295 * @param[in] RgrCellCfg *cellCfg
2296 * @param[in] RgSchErrInfo *errInfo
2301 S16 rgSCHUtlRgrCellCfg
2304 RgrCellCfg *cellCfg,
2305 RgSchErrInfo *errInfo
2308 S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2310 RgrCellCfg *cellCfg;
2311 RgSchErrInfo *errInfo;
2318 CmLteTimingInfo frm;
2319 U8 ulDlCfgIdx = cellCfg->ulDlCfgIdx;
2323 U16 bw; /*!< Number of RBs in the cell */
2325 memset(&frm,0,sizeof(CmLteTimingInfo));
2327 /* ccpu00132657-MOD- Determining DLSF array size independent of DELTAS */
2328 maxDlslots = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
2329 maxslots = 2 * maxDlslots;
2330 cell->numDlSubfrms = maxslots;
2331 /* ACC-TDD <ccpu00130639> */
2332 cell->tddHqSfnCycle = -1;
2333 cell->ulDlCfgIdx = ulDlCfgIdx;
2335 /* PRACH Occasions Initialization */
2336 rgSCHUtlPrachCfgInit(cell, cellCfg);
2338 /* ccpu00132658- Moved out of below for loop since the updating rbgSize and
2339 * bw are independent of sfNum*/
2340 /* determine the RBG size and no of RBGs for the configured
2342 if (cell->bwCfg.dlTotalBw > 63)
2346 else if (cell->bwCfg.dlTotalBw > 26)
2350 else if (cell->bwCfg.dlTotalBw > 10)
2358 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2360 bw = cell->bwCfg.dlTotalBw;
2362 rgSCHUtlAllocSBuf(cell->instIdx,
2363 (Data **)&cell->subFrms, sizeof(RgSchDlSf *) * maxslots);
2364 if (cell->subFrms == NULLP)
2369 /* Create memory for each frame. */
2370 for(i = 0; i < maxslots; i++)
2372 while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
2375 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2378 rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf, sizeof(RgSchDlSf));
2383 memset(sf, 0, sizeof(*sf));
2386 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2394 /* Mark SPS bandwidth to be occupied */
2395 sf->bwAlloced = ((cellCfg->spsCfg.maxSpsDlBw +
2396 cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
2397 sf->spsAllocdBw = 0;
2398 sf->type2End = sf->bwAlloced/cell->rbgSize;
2401 /* Fix for ccpu00123918*/
2403 #endif /* LTEMAC_SPS */
2404 /* Initialize the ackNakRepQ here */
2405 #ifdef RG_MAC_MEASGAP
2406 cmLListInit (&(sf->ackNakRepQ));
2408 cell->subFrms[i] = sf;
2409 sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2415 /* ccpu00117052 - MOD - Passing double pointer
2416 for proper NULLP assignment*/
2417 rgSCHUtlFreeSBuf(cell->instIdx,
2418 (Data **)(&(cell->subFrms[i-1])), sizeof(RgSchDlSf));
2420 rgSCHLaaDeInitDlSfCb(cell, sf);
2423 /* ccpu00117052 - MOD - Passing double pointer
2424 for proper NULLP assignment*/
2425 rgSCHUtlFreeSBuf(cell->instIdx,
2426 (Data **)(&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2431 if (cell->sc.apis == NULLP)
2433 cell->sc.apis = &rgSchCmnApis;
2435 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2439 /* ccpu00132286- Removed deletion of sf nodes as the deletion will be
2440 * happening during CellDelete. Added return handling to provide negative
2445 /* Release the slots and thereby perform the initialization */
2446 for (i = 0; i < maxslots; i++)
2448 if((i > 0) && (i%maxDlslots == 0))
2453 frm.slot = cell->subFrms[i]->sfNum;
2454 rgSCHUtlDlRlsSubFrm(cell, frm);
2463 * @brief This function performs scheduler related cell creation
2467 * Function: rgSCHUtlRgrCellCfg
2468 * Purpose: This function creates the slots needed for the
2469 * cell. It then peforms init of the scheduler by calling
2470 * scheduler specific cell init function.
2472 * Invoked by: Scheduler
2474 * @param[in] RgSchCellCb *cell
2475 * @param[in] RgrCellCfg *cellCfg
2476 * @param[in] RgSchErrInfo *errInfo
2481 S16 rgSCHUtlRgrCellCfg
2484 RgrCellCfg *cellCfg,
2485 RgSchErrInfo *errInfo
2488 S16 rgSCHUtlRgrCellCfg(cell, cellCfg, errInfo)
2490 RgrCellCfg *cellCfg;
2491 RgSchErrInfo *errInfo;
2496 CmLteTimingInfo frm;
2498 Inst inst = cell->instIdx;
2499 /* LTE_ADV_FLAG_REMOVED_START */
2501 len = (U16)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /*KW fix for LTE_ADV */
2502 /* LTE_ADV_FLAG_REMOVED_END */
2504 memset(&frm,0,sizeof(CmLteTimingInfo));
2506 /* determine the RBG size and no of RBGs for the configured
2508 if (cell->bwCfg.dlTotalBw > 63)
2512 else if (cell->bwCfg.dlTotalBw > 26)
2516 else if (cell->bwCfg.dlTotalBw > 10)
2524 cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2525 /* Create memory for each frame. */
2526 /* Changing loop limit from
2527 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2528 for(i = 0; i < RGSCH_NUM_DL_slotS; i++)
2530 rgSCHUtlAllocSBuf(inst, (Data **)&sf, sizeof(RgSchDlSf));
2535 memset(sf, 0, sizeof(*sf));
2538 if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2543 /* Doing MOD operation before assigning value of i */
2544 sf->sfNum = i % RGSCH_NUM_SUB_FRAMES;
2545 sf->bw = cell->bwCfg.dlTotalBw;
2546 /* Initialize the ackNakRepQ here */
2547 #ifdef RG_MAC_MEASGAP
2548 cmLListInit (&(sf->ackNakRepQ));
2550 cell->subFrms[i] = sf;
2551 /* LTE_ADV_FLAG_REMOVED_START */
2552 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2554 /*initialize the RNTP Buffer*/
2555 if(rgSchDSFRRntpInfoInit(&sf->rntpInfo, cell, sf->bw))
2561 if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
2563 /*initialise the pools of CC and CE*/
2564 if(rgSchSFRTotalPoolInit(cell, sf))
2569 /* LTE_ADV_FLAG_REMOVED_END */
2572 /* LTE_ADV_FLAG_REMOVED_START */
2573 /* Allocate memory for "scheduled UE" Info */
2574 if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2576 if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val),
2577 (len * sizeof(U8)))) != ROK)
2579 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for RNTP Alloc");
2582 cell->rntpAggrInfo.pres = PRSNT_NODEF;
2583 cell->rntpAggrInfo.len = len;
2585 /* LTE_ADV_FLAG_REMOVED_END */
2587 /* Changing loop limit from
2588 RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2589 if (i != RGSCH_NUM_DL_slotS)
2593 /* ccpu00117052 - MOD - Passing double pointer
2594 for proper NULLP assignment*/
2595 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i-1])),
2598 rgSCHLaaDeInitDlSfCb(cell, sf);
2604 if (cell->sc.apis == NULLP)
2606 cell->sc.apis = &rgSchCmnApis;
2609 /* Release the slots and thereby perform the initialization */
2610 for (i = 0; i < RGSCH_NUM_DL_slotS; i++)
2612 if (i >= RGSCH_NUM_SUB_FRAMES)
2614 /* [ccpu00123828]-MOD-The below statement sfn += 1incorrectly modified
2615 * the value of sfn for i>=10 thru 19. Correct way is to assign
2619 frm.slot = i % RGSCH_NUM_SUB_FRAMES;
2620 rgSCHUtlDlRlsSubFrm(cell, frm);
2623 ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2626 errInfo->errCause = RGSCHERR_SCH_CFG;
2630 if(cell->emtcEnable)
2632 /* TODO: Repetition framework in RGR and APP */
2633 if (rgSCHUtlEmtcResMngmtInit(
2635 RGSCH_IOT_PDSCH_POOLSZ, RGSCH_IOT_PDSCH_DELTA, cellCfg->bwCfg.dlTotalBw,
2636 RGSCH_IOT_PUSCH_POOLSZ, RGSCH_IOT_PUSCH_DELTA, RGSCH_IOT_PUSCH_MAXFREQSZ,
2637 RGSCH_IOT_PUCCH_POOLSZ, RGSCH_IOT_PUCCH_DELTA, RGSCH_IOT_PUCCH_MAXFREQSZ) != ROK)
2639 errInfo->errCause = RGSCHERR_SCH_CFG;
2651 * @brief This function performs the cell reconfiguration at RGR interface
2655 * Function: rgSCHUtlRgrCellRecfg
2656 * Purpose: This function updates the reconfigurable parameters
2657 * on the cell control block for the scheduler.
2659 * Invoked by: Scheduler
2661 * @param[in] RgSchCellCb *cell
2662 * @param[in] RgrCellCfg *cellCfg
2663 * @param[in] RgSchErrInfo *errInfo
2668 S16 rgSCHUtlRgrCellRecfg
2671 RgrCellRecfg *recfg,
2675 S16 rgSCHUtlRgrCellRecfg(cell, recfg, err)
2677 RgrCellRecfg *recfg;
2681 return (cell->sc.apis->rgSCHRgrCellRecfg(cell, recfg, err));
2687 * @brief This function returns the Y value of UE for a sub frame
2691 * Function: rgSCHUtlFreeCell
2692 * Purpose: This function updates the value of Y stored in the
2693 * UE control block. It uses the previously computed
2694 * value for computing for this slot.
2696 * Invoked by: Scheduler
2698 * @param[in] RgSchCellCb *cell
2703 S16 rgSCHUtlFreeCell
2708 S16 rgSCHUtlFreeCell(cell)
2715 RgSchPdcchInfo *pdcchInfo;
2716 RgSchPhichInfo *phichInfo;
2718 Inst inst = cell->instIdx;
2721 RgSchRaReqInfo *raReqInfo;
2726 maxslots = cell->numDlSubfrms;
2728 maxslots = RGSCH_NUM_DL_slotS;
2732 /* Invoke the index for scheduler, cell deletion */
2733 cell->sc.apis->rgSCHFreeCell(cell);
2735 /* Release the slots allocated */
2736 for (i = 0; i < maxslots; i++)
2739 rgSCHLaaDeInitDlSfCb(cell, cell->subFrms[i]);
2741 pdcchInfo = &cell->subFrms[i]->pdcchInfo;
2742 /* ccpu00117052 - MOD - Passing double pointer
2743 for proper NULLP assignment*/
2744 rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)),
2745 (pdcchInfo->nCce + 7) >> 3);
2746 while (pdcchInfo->pdcchs.first != NULLP)
2748 pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
2749 cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
2750 /* ccpu00117052 - MOD - Passing double pointer
2751 for proper NULLP assignment*/
2752 rgSCHUtlFreeSBuf(inst, (Data **)&pdcch, sizeof(RgSchPdcch));
2755 phichInfo = &cell->subFrms[i]->phichInfo;
2756 while(phichInfo->phichs.first != NULLP)
2758 phich = (RgSchPhich *)phichInfo->phichs.first->node;
2759 cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
2760 RGSCH_PHICH_FREE(inst, phich, sizeof(RgSchPhich));
2763 /* LTE_ADV_FLAG_REMOVED_START */
2764 /*releasing SFR pool entries*/
2765 rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell);
2767 /*releasing dsfr rntp pattern info*/
2768 rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell,
2769 cell->bwCfg.dlTotalBw);
2770 /* LTE_ADV_FLAG_REMOVED_END */
2772 /* ccpu00117052 - MOD - Passing double pointer
2773 for proper NULLP assignment*/
2774 rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i])), sizeof(RgSchDlSf));
2777 /* Release the slot pointers */
2778 /* ccpu00117052 - MOD - Passing double pointer
2779 for proper NULLP assignment*/
2780 rgSCHUtlFreeSBuf(inst,
2781 (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2783 for(idx=0; idx < cell->raInfo.lstSize; idx++)
2785 lst = &cell->raInfo.raReqLst[idx];
2786 while (lst->first != NULLP)
2788 raReqInfo = (RgSchRaReqInfo *)lst->first->node;
2789 cmLListDelFrm(lst, &raReqInfo->raReqLstEnt);
2790 /* ccpu00117052 - MOD - Passing double pointer
2791 for proper NULLP assignment*/
2792 rgSCHUtlFreeSBuf(inst,(Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
2795 /* ccpu00117052 - MOD - Passing double pointer
2796 for proper NULLP assignment*/
2797 rgSCHUtlFreeSBuf(inst,
2798 (Data **)(&(cell->raInfo.raReqLst)),
2799 sizeof(CmLListCp) * (cell->raInfo.lstSize));
2802 /* Release allocated pdcchs */
2803 lst = &cell->pdcchLst;
2804 while (lst->first != NULLP)
2806 pdcch = (RgSchPdcch *)lst->first->node;
2807 cmLListDelFrm(lst, &pdcch->lnk);
2809 if(cell->emtcEnable)
2811 rgSCHEmtcPdcchFree(cell, pdcch);
2812 rgSCHUtlEmtcResMngmtDeinit(cell);
2815 /* ccpu00117052 - MOD - Passing double pointer
2816 for proper NULLP assignment*/
2817 rgSCHUtlFreeSBuf(inst,(Data **)&pdcch, sizeof(RgSchPdcch));
2820 rgSCHLaaFreeLists(cell);
2823 /* LTE_ADV_FLAG_REMOVED_START */
2824 /* releasing RNTP Aggregation Info from CellCb*/
2825 rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw);
2826 /* LTE_ADV_FLAG_REMOVED_END */
2833 * @brief This function adds the UE to scheduler
2837 * Function: rgSCHUtlRgrUeCfg
2838 * Purpose: This function performs addition of UE to scheduler
2839 * 1. First, it updates the Y table in the UE
2840 * 2. Then, it calls the scheduler's handler for UE addition
2842 * Invoked by: Scheduler
2844 * @param[in] RgSchCellCb *cell
2845 * @param[in] RgSchUeCb *ue
2846 * @param[in] RgrUeCfg *cfg
2847 * @param[in] RgSchErrInfo *err
2852 S16 rgSCHUtlRgrUeCfg
2860 S16 rgSCHUtlRgrUeCfg(cell, ue, cfg, err)
2868 /* Assign TM 1 as UE's default TM */
2869 ue->mimoInfo.txMode = RGR_UE_TM_1;
2870 ue->txModeTransCmplt = TRUE;
2871 cmInitTimers(&ue->txModeTransTmr, 1);
2872 if (cfg->txMode.pres == PRSNT_NODEF)
2874 /* DL MU-MIMO not supported */
2875 if (cfg->txMode.txModeEnum == RGR_UE_TM_5)
2877 err->errCause = RGSCHERR_SCH_CFG;
2880 ue->mimoInfo.txMode = cfg->txMode.txModeEnum;
2882 ue->ul.ulTxAntSel = cfg->ulTxAntSel;
2883 ue->mimoInfo.cdbkSbstRstrctn = cfg->ueCodeBookRstCfg;
2885 ue->ueCatEnum = cfg->ueCatEnum;
2886 if ((cfg->puschDedCfg.bACKIdx > 15) ||
2887 (cfg->puschDedCfg.bCQIIdx > 15) ||
2888 (cfg->puschDedCfg.bRIIdx > 15))
2890 err->errCause = RGSCHERR_SCH_CFG;
2893 ue->ul.betaHqOffst = cfg->puschDedCfg.bACKIdx;
2894 ue->ul.betaCqiOffst = cfg->puschDedCfg.bCQIIdx;
2895 ue->ul.betaRiOffst = cfg->puschDedCfg.bRIIdx;
2897 ue->csgMmbrSta = cfg->csgMmbrSta;
2899 memset(&ue->pfsStats, 0, sizeof(RgSchPfsStats));
2901 /* Call the handler of the scheduler based on cell configuration */
2902 return (cell->sc.apis->rgSCHRgrUeCfg(cell, ue, cfg, err));
2904 /* Start : LTEMAC_2.1_DEV_CFG */
2907 * @brief This function adds a service to scheduler
2911 * Function: rgSCHUtlRgrLcCfg
2912 * Purpose: This function performs addition of service to scheduler
2913 * The addition is performed for each direction based
2914 * the direction field of the configuration
2916 * Invoked by: Scheduler
2918 * @param[in] RgSchCellCb *cell
2919 * @param[in] RgSchUeCb *ue
2920 * @param[in] RgSchDlLcCb *dlLc
2921 * @param[in] RgrLchCfg *cfg
2922 * @param[in] RgSchErrInfo *err
2927 S16 rgSCHUtlRgrLcCfg
2933 RgSchErrInfo *errInfo
2936 S16 rgSCHUtlRgrLcCfg(cell, ue, dlLc, cfg, errInfo)
2941 RgSchErrInfo *errInfo;
2944 return (cell->sc.apis->rgSCHRgrLchCfg(cell, ue, dlLc, cfg, errInfo));
2949 * @brief This function modifies a service to scheduler
2953 * Function: rgSCHUtlRgrLcRecfg
2954 * Purpose: This function performs modification of a service in
2955 * scheduler. The modification is performed for each direction
2956 * based the direction field of the configuration
2958 * Invoked by: Scheduler
2960 * @param[in] RgSchCellCb *cell
2961 * @param[in] RgSchUeCb *ue
2962 * @param[in] RgSchDlLcCb *dlLc
2963 * @param[in] RgrLchRecfg *recfg
2964 * @param[in] RgSchErrInfo *err
2969 S16 rgSCHUtlRgrLcRecfg
2978 S16 rgSCHUtlRgrLcRecfg(cell, ue, dlLc, recfg, err)
2986 return (cell->sc.apis->rgSCHRgrLchRecfg(cell, ue, dlLc, recfg, err));
2990 * @brief This function deletes a Lc in scheduler
2994 * Function: rgSCHUtlRgrLcDel
2995 * Purpose: This function performs deletion of Lc in scheduler
2997 * Invoked by: Scheduler
2999 * @param[in] RgSchCellCb *cell
3000 * @param[in] RgSchUeCb *ue
3001 * @param[in] CmLteLcId lcId
3002 * @param[in] U8 lcgId
3007 S16 rgSCHUtlRgrLcDel
3015 S16 rgSCHUtlRgrLcDel(cell, ue, lcId, lcgId)
3022 cell->sc.apis->rgSCHRgrLchDel(cell, ue, lcId, lcgId);
3025 } /* rgSCHUtlRgrLcDel */
3028 * @brief This function adds a service to scheduler
3032 * Function: rgSCHUtlRgrLcgCfg
3033 * Purpose: This function performs addition of service to scheduler
3034 * The addition is performed for each direction based
3035 * the direction field of the configuration
3037 * Invoked by: Scheduler
3039 * @param[in] RgSchCellCb *cell
3040 * @param[in] RgSchUeCb *ue
3041 * @param[in] RgrLchCfg *cfg
3042 * @param[in] RgSchErrInfo *err
3047 S16 rgSCHUtlRgrLcgCfg
3052 RgSchErrInfo *errInfo
3055 S16 rgSCHUtlRgrLcgCfg(cell, ue, cfg, errInfo)
3059 RgSchErrInfo *errInfo;
3062 return (cell->sc.apis->rgSCHRgrLcgCfg(cell, ue, &(ue->ul.lcgArr[cfg->ulInfo.lcgId]), cfg, errInfo));
3067 * @brief This function modifies a service to scheduler
3071 * Function: rgSCHUtlRgrLcgRecfg
3072 * Purpose: This function performs modification of a service in
3073 * scheduler. The modification is performed for each direction
3074 * based the direction field of the configuration
3076 * Invoked by: Scheduler
3078 * @param[in] RgSchCellCb *cell
3079 * @param[in] RgSchUeCb *ue
3080 * @param[in] RgrLcgRecfg *recfg
3081 * @param[in] RgSchErrInfo *err
3086 S16 rgSCHUtlRgrLcgRecfg
3094 S16 rgSCHUtlRgrLcgRecfg(cell, ue, recfg, err)
3101 return (cell->sc.apis->rgSCHRgrLcgRecfg(cell, ue, &(ue->ul.lcgArr[recfg->ulRecfg.lcgId]), recfg, err));
3102 } /* rgSCHUtlRgrLcRecfg */
3105 * @brief This function modifies a service to scheduler
3109 * Function: rgSCHUtlRgrLcgDel
3110 * Purpose: This function performs modification of a service in
3111 * scheduler. The modification is performed for each direction
3112 * based the direction field of the configuration
3114 * Invoked by: Scheduler
3116 * @param[in] RgSchCellCb *cell
3117 * @param[in] RgSchUeCb *ue
3118 * @param[in] RgrDel *lcDelInfo
3123 Void rgSCHUtlRgrLcgDel
3130 Void rgSCHUtlRgrLcgDel(cell, ue, lcgId)
3136 cell->sc.apis->rgSCHFreeLcg(cell, ue, &ue->ul.lcgArr[lcgId]);
3138 /* Stack Crash problem for TRACE5 changes. added the return below . */
3141 } /* rgSCHUtlRgrLcgDel */
3144 /* End: LTEMAC_2.1_DEV_CFG */
3147 * @brief This function is a wrapper to call scheduler specific API.
3151 * Function: rgSCHUtlDoaInd
3152 * Purpose: Updates the DOA for the UE
3156 * @param[in] RgSchCellCb *cell
3157 * @param[in] RgSchUeCb *ue
3158 * @param[in] TfuDoaRpt *doaRpt
3170 Void rgSCHUtlDoaInd(cell, ue, doaRpt)
3176 ue->mimoInfo.doa.pres = PRSNT_NODEF;
3177 ue->mimoInfo.doa.val = doaRpt->doa;
3182 * @brief This function is a wrapper to call scheduler specific API.
3186 * Function: rgSCHUtlDlCqiInd
3187 * Purpose: Updates the DL CQI for the UE
3191 * @param[in] RgSchCellCb *cell
3192 * @param[in] RgSchUeCb *ue
3193 * @param[in] TfuDlCqiRpt *dlCqiRpt
3194 * @param[in] CmLteTimingInfo timingInfo
3199 Void rgSCHUtlDlCqiInd
3203 TfuDlCqiRpt *dlCqiRpt,
3204 CmLteTimingInfo timingInfo
3207 Void rgSCHUtlDlCqiInd(cell, ue, dlCqiRpt, timingInfo)
3210 TfuDlCqiRpt *dlCqiRpt;
3211 CmLteTimingInfo timingInfo;
3214 RgSchCellCb *sCellCb = NULLP;
3215 if (dlCqiRpt->isPucchInfo)
3217 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pucchCqi.cellIdx]->cell;
3218 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3219 (Void *)&dlCqiRpt->dlCqiInfo.pucchCqi, timingInfo);
3224 for (idx = 0; idx < dlCqiRpt->dlCqiInfo.pusch.numOfCells; idx++)
3226 sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx].cellIdx]->cell;
3227 sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
3228 (Void *)&dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx], timingInfo);
3237 * @brief This function is a wrapper to call scheduler specific API.
3241 * Function: rgSCHUtlSrsInd
3242 * Purpose: Updates the UL SRS for the UE
3246 * @param[in] RgSchCellCb *cell
3247 * @param[in] RgSchUeCb *ue
3248 * @param[in] TfuSrsRpt* srsRpt
3249 * @param[in] CmLteTimingInfo timingInfo
3259 CmLteTimingInfo timingInfo
3262 Void rgSCHUtlSrsInd(cell, ue, srsRpt, timingInfo)
3266 CmLteTimingInfo timingInfo;
3269 cell->sc.apis->rgSCHSrsInd(cell, ue, srsRpt, timingInfo);
3275 * @brief This function is a wrapper to call scheduler specific API.
3279 * Function: rgSCHUtlDlTARpt
3280 * Purpose: Reports PHY TA for a UE.
3284 * @param[in] RgSchCellCb *cell
3285 * @param[in] RgSchUeCb *ue
3290 Void rgSCHUtlDlTARpt
3296 Void rgSCHUtlDlTARpt(cell, ue)
3301 cell->sc.apis->rgSCHDlTARpt(cell, ue);
3307 * @brief This function is a wrapper to call scheduler specific API.
3311 * Function: rgSCHUtlDlRlsSubFrm
3312 * Purpose: Releases scheduler Information from DL SubFrm.
3316 * @param[in] RgSchCellCb *cell
3317 * @param[out] CmLteTimingInfo subFrm
3322 Void rgSCHUtlDlRlsSubFrm
3325 CmLteTimingInfo subFrm
3328 Void rgSCHUtlDlRlsSubFrm(cell, subFrm)
3330 CmLteTimingInfo subFrm;
3333 cell->sc.apis->rgSCHDlRlsSubFrm(cell, subFrm);
3339 * @brief This API is invoked to update the AperCQI trigger
3344 * Function : rgSCHUtlUpdACqiTrigWt
3345 * - If HqFdbk is ACK then add up weight corresponding
3346 * to ACK to the AcqiTrigWt.
3347 * - If HqFdbk is NACK then add up weight corresponding
3348 * to NACK to the AcqiTrigWt.
3349 * - If AcqiTrigWt crosses threshold then trigger
3350 * grant req for APERCQI to SCH.
3352 * @param[in] RgSchUeCb *ue
3353 * @param[in] U8 isAck
3358 Void rgSCHUtlUpdACqiTrigWt
3361 RgSchUeCellInfo *cellInfo,
3365 Void rgSCHUtlUpdACqiTrigWt(ue,cellInfo, isAck)
3367 RgSchUeCellInfo *cellInfo;
3376 if (isAck == TFU_HQFDB_ACK)
3378 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_ACK_WGT;
3382 cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_NACK_WGT;
3385 if (cellInfo->acqiCb.aCqiTrigWt > RG_APER_CQI_THRESHOLD_WGT)
3387 RgSchCellCb *cell = ue->cell;
3388 RgSchErrInfo unUsed;
3390 if(ue->dl.reqForCqi)
3392 /* Already one ACQI trigger procedure is going on
3393 * which is not yet satisfied. Delaying this request till
3394 * the previous is getting satisfied*/
3398 ue->dl.reqForCqi = TRUE;
3400 rgSchCmnSetCqiReqField(cellInfo,ue,&ue->dl.reqForCqi);
3401 //Reset aCqiTrigWt for all the serving cells for which we have triggered ACQI
3402 rgSCHTomUtlGetTrigSet(cell, ue, ue->dl.reqForCqi, &triggerSet);
3403 for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++)
3405 /* The Aperiodic requested for SCell index sIdx */
3406 if ((triggerSet >> (7 - sIdx)) & 0x01)
3408 /* The Aperiodic request for SCell index sIdx */
3409 ue->cellInfo[sIdx]->acqiCb.aCqiTrigWt = 0;
3414 /* Force SCH to send UL grant by indicating fake SR.
3415 * If this UE already in UL SCH Qs this SR Ind will
3417 rgSCHUtlSrRcvd(cell, ue, cell->crntTime, &unUsed);
3425 * @brief This API is invoked to indicate scheduler of a CRC indication.
3429 * Function : rgSCHUtlHdlUlTransInd
3430 * This API is invoked to indicate scheduler of a CRC indication.
3432 * @param[in] RgSchCellCb *cell
3433 * @param[in] RgSchUeCb *ue
3434 * @param[in] CmLteTimingInfo timingInfo
3439 Void rgSCHUtlHdlUlTransInd
3443 CmLteTimingInfo timingInfo
3446 Void rgSCHUtlHdlUlTransInd(cell, ue, timingInfo)
3449 CmLteTimingInfo timingInfo;
3452 cell->sc.apis->rgSCHHdlUlTransInd(cell, ue, timingInfo);
3457 * @brief This API is invoked to indicate scheduler of a CRC failure.
3461 * Function : rgSCHUtlHdlCrcInd
3462 * This API is invoked to indicate CRC to scheduler.
3464 * @param[in] RgSchCellCb *cell
3465 * @param[in] RgSchUeCb *ue
3466 * @param[in] CmLteTimingInfo timingInfo
3471 Void rgSCHUtlHdlCrcInd
3475 CmLteTimingInfo timingInfo
3478 Void rgSCHUtlHdlCrcInd(cell, ue, timingInfo)
3481 CmLteTimingInfo timingInfo;
3484 cell->sc.apis->rgSCHUlCrcInd(cell, ue, timingInfo);
3486 } /* end of rgSCHUtlHdlCrcFailInd */
3489 * @brief This API is invoked to indicate scheduler of a CRC failure.
3493 * Function : rgSCHUtlHdlCrcFailInd
3494 * This API is invoked to indicate CRC failure to scheduler.
3496 * @param[in] RgSchCellCb *cell
3497 * @param[in] RgSchUeCb *ue
3498 * @param[in] CmLteTimingInfo timingInfo
3503 Void rgSCHUtlHdlCrcFailInd
3507 CmLteTimingInfo timingInfo
3510 Void rgSCHUtlHdlCrcFailInd(cell, ue, timingInfo)
3513 CmLteTimingInfo timingInfo;
3516 cell->sc.apis->rgSCHUlCrcFailInd(cell, ue, timingInfo);
3518 } /* end of rgSCHUtlHdlCrcFailInd */
3519 #endif /* LTEMAC_SPS */
3523 * @brief This function is a wrapper to call scheduler specific API.
3527 * Function: rgSCHUtlDlProcAddToRetx
3528 * Purpose: This function adds a HARQ process to retransmission
3529 * queue. This may be performed when a HARQ ack is
3532 * Invoked by: HARQ feedback processing
3534 * @param[in] RgSchCellCb* cell
3535 * @param[in] RgSchDlHqProc* hqP
3540 Void rgSCHUtlDlProcAddToRetx
3543 RgSchDlHqProcCb *hqP
3546 Void rgSCHUtlDlProcAddToRetx(cell, hqP)
3548 RgSchDlHqProcCb *hqP;
3551 cell->sc.apis->rgSCHDlProcAddToRetx(cell, hqP);
3557 * @brief This function adds a HARQ process TB to transmission
3561 * Function: rgSCHUtlDlHqPTbAddToTx
3562 * Purpose: This function a HarqProcess TB to the slot
3565 * Invoked by: Scheduler
3567 * @param[in] RgSubFrm* subFrm
3568 * @param[in] RgDlHqProc* hqP
3569 * @param[in] U8 tbIdx
3574 Void rgSCHUtlDlHqPTbAddToTx
3577 RgSchDlHqProcCb *hqP,
3581 Void rgSCHUtlDlHqPTbAddToTx(subFrm, hqP, tbIdx)
3583 RgSchDlHqProcCb *hqP;
3587 RgSchUeCb *ue = NULLP;
3588 RgSchCellCb *cell = hqP->hqE->cell;
3590 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3591 /* ue->cell will always hold PCell information */
3592 if (NULLP == hqP->hqPSfLnk.node)
3597 if(NULLP == ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node)
3599 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)ue;
3600 cmLListAdd2Tail(&cell->subFrms[subFrm->dlIdx]->ueLst,
3601 &ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3603 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].isPuschHarqRecpPres = FALSE;
3607 /* Add Hq proc in particular dlIdx List for this UE
3608 This list will be used while processing feedback*/
3609 hqP->hqPSfLnk.node = (PTR)hqP;
3610 cmLListAdd2Tail(&ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3613 extern U32 gSCellSchedCount,gPrimarySchedCount;
3614 if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue,hqP->hqE->cell))
3618 gPrimarySchedCount++;
3622 else if (hqP->hqE->msg4Proc == hqP)
3624 /* Msg4 will be scheduled on PCELL only hence add directly to subFrm msg4HqpList */
3625 hqP->hqPSfLnk.node = (PTR)hqP;
3626 cmLListAdd2Tail(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3633 if((ue) && (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state))
3636 ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt++;
3638 /*totalTbCnt will hold the total number of TBs across all harq Proc from all
3641 hqP->subFrm = subFrm;
3650 * @brief This function removes a HARQ process TB from transmission
3654 * Function: rgSCHUtlDlHqPTbRmvFrmTx
3655 * Purpose: This function removes a HarqProcess TB to the slot
3658 * Invoked by: Scheduler
3660 * @param[in] RgSubFrm* subFrm
3661 * @param[in] RgDlHqProc* hqP
3662 * @param[in] U8 tbIdx
3663 * @param[in] Bool isRepeting
3668 Void rgSCHUtlDlHqPTbRmvFrmTx
3671 RgSchDlHqProcCb *hqP,
3676 Void rgSCHUtlDlHqPTbRmvFrmTx(subFrm, hqP, tbIdx, isRepeting)
3678 RgSchDlHqProcCb *hqP;
3683 RgSchCellCb *cell = NULLP;
3684 /* Check with TDD */
3686 (hqP->hqE->ue->ackNakRepCb.cfgRepCnt !=
3687 hqP->tbInfo[tbIdx].fbkRepCntr))
3689 cmLListDelFrm(&subFrm->ackNakRepQ,
3690 &hqP->tbInfo[tbIdx].anRepLnk[hqP->tbInfo[tbIdx].fbkRepCntr]);
3694 if (NULLP != hqP->hqPSfLnk.node)
3697 if (hqP->hqE->msg4Proc == hqP)
3699 /* Msg4 will be scheduled on PCELL only hence delete directly from subFrm msg4HqpList */
3700 cmLListDelFrm(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
3704 cell = hqP->hqE->cell;
3705 /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3706 /* ue->cell will always hold PCell information */
3707 cmLListDelFrm(&hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk);
3708 if (0 == hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst.count)
3711 cmLListDelFrm(&cell->subFrms[subFrm->dlIdx]->ueLst,
3712 &hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3713 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)NULLP;
3714 hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt = 0;
3717 hqP->hqPSfLnk.node = NULLP;
3719 hqP->subFrm = NULLP;
3726 * @brief Handler for accessing the existing SCellCb identified by the key
3727 * SCellId under the CellCb.
3731 * Function : rgSchUtlGetCellCb
3734 * @param[in] *cellCb
3736 * @return RgSchUeCb*
3739 RgSchCellCb* rgSchUtlGetCellCb
3745 RgSchCellCb* rgSchUtlGetCellCb(inst, cellId)
3750 RgSchCellCb *cellCb = NULLP;
3753 strtCellId = rgSchCb[inst].genCfg.startCellId;
3754 cellCb = rgSchCb[inst].cells[cellId - strtCellId];
3758 } /* rgSchUtlGetCellCb */
3761 * @brief Handler for deriving the servCellidx
3765 * Function : rgSchUtlGetServCellIdx
3768 * @param[in] *cellId
3769 * @param[in] RgSchUeCb *ue
3770 * @return U8 servCellIdx
3773 U8 rgSchUtlGetServCellIdx
3780 U8 rgSchUtlGetServCellIdx(inst,cellId,ue)
3789 strtCellId = rgSchCb[inst].genCfg.startCellId;
3791 servCellIdx = ue->cellIdToCellIdxMap[cellId - strtCellId];
3793 return (servCellIdx);
3795 } /* rgSchUtlGetCellCb */
3798 * @brief Handler for validating the Cell Id received secondary Cell Addition
3802 * Function : rgSchUtlGetCellId
3805 * @param[in] *cellCb
3807 * @return RgSchUeCb*
3810 S16 rgSchUtlVldtCellId
3816 S16 rgSchUtlVldtCellId(inst, cellId)
3823 strtCellId = rgSchCb[inst].genCfg.startCellId;
3824 if((cellId >= strtCellId) && ((cellId - strtCellId) < CM_LTE_MAX_CELLS))
3829 } /* rgSchUtlVldtCellId */
3833 * @brief UE reconfiguration for scheduler
3837 * Function : rgSCHUtlRgrUeRecfg
3839 * This functions updates UE specific scheduler
3840 * information upon UE reconfiguration
3842 * @param[in] RgSchCellCb *cell
3843 * @param[in] RgSchUeCb *ue
3844 * @param[int] RgrUeRecfg *ueRecfg
3845 * @param[out] RgSchErrInfo *err
3851 S16 rgSCHUtlRgrUeRecfg
3855 RgrUeRecfg *ueRecfg,
3859 S16 rgSCHUtlRgrUeRecfg(cell, ue, ueRecfg, err)
3862 RgrUeRecfg *ueRecfg;
3866 /* Changes for UE Category Reconfiguration feature addition */
3867 RgSchCmnUe *ueSch = RG_SCH_CMN_GET_UE(ue, cell);
3869 /* Changes for UE Category Reconfiguration feature addition */
3870 if (ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
3872 ueSch->cmn.ueCat = ueRecfg->ueCatEnum-1;
3874 ue->ueCatEnum = ueRecfg->ueCatEnum;
3878 /* DL MU-MIMO not supported */
3879 if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
3882 if (ueRecfg->txMode.pres == PRSNT_NODEF)
3884 if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_5)
3886 err->errCause = RGSCHERR_SCH_CFG;
3890 if(ue->mimoInfo.txMode != ueRecfg->txMode.txModeEnum)
3892 /* Decremnt the previos A value for this cell */
3893 ue->f1bCsAVal -= rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode);
3894 /* Update A value with the new TM Mode */
3895 ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(ueRecfg->txMode.txModeEnum);
3898 RLOG1(L_INFO,"UeReCfg A valie is %d\n",ue->f1bCsAVal);
3901 ue->mimoInfo.txMode = ueRecfg->txMode.txModeEnum;
3905 /* [ccpu00123958]-ADD- Check for PUSCH related Reconfig from the bit mask */
3906 if(ueRecfg->ueRecfgTypes & RGR_UE_PUSCH_RECFG)
3908 /* Fix: ccpu00124012 */
3909 /* TODO:: Need to check if this is
3910 mandatory to be re-configured on UE category re-configuration */
3911 /* ue->ul.betaHqOffst = ueRecfg->puschDedCfg.bACKIdx;
3912 ue->ul.betaCqiOffst = ueRecfg->puschDedCfg.bCQIIdx;
3913 ue->ul.betaRiOffst = ueRecfg->puschDedCfg.bRIIdx;*/
3916 if (ueRecfg->ueRecfgTypes & RGR_UE_ULTXANTSEL_RECFG)
3918 ue->ul.ulTxAntSel = ueRecfg->ulTxAntSel;
3920 if (ueRecfg->ueRecfgTypes & RGR_UE_CDBKSBST_RECFG)
3922 ue->mimoInfo.cdbkSbstRstrctn = ueRecfg->ueCodeBookRstRecfg;
3925 /* Commenting here to assign garbage value when it is not set in APP. */
3926 //ue->accessStratumRls = ueRecfg->accessStratumRls;
3927 return (cell->sc.apis->rgSCHRgrUeRecfg(cell, ue, ueRecfg, err));
3928 } /* rgSCHUtlRgrUeRecfg */
3931 * @brief This function deletes a service from scheduler
3935 * Function: rgSCHUtlFreeDlLc
3936 * Purpose: This function is made available through a FP for
3937 * making scheduler aware of a service being deleted from UE
3939 * Invoked by: BO and Scheduler
3941 * @param[in] RgSchCellCb* cell
3942 * @param[in] RgSchUeCb* ue
3943 * @param[in] RgSchDlLcCb* svc
3947 Void rgSCHUtlFreeDlLc
3954 Void rgSCHUtlFreeDlLc(cell, ue, svc)
3960 cell->sc.apis->rgSCHFreeDlLc(cell, ue, svc);
3962 /* Stack Crash problem for TRACE5 changes. added the return below . */
3968 * @brief UE deletion for scheduler
3972 * Function : rgSCHUtlFreeUe
3974 * This functions deletes all scheduler information
3975 * pertaining to a UE
3977 * @param[in] RgSchCellCb *cell
3978 * @param[in] RgSchUeCb *ue
3988 Void rgSCHUtlFreeUe(cell, ue)
3994 rgSCHUtlDelUeANFdbkInfo(ue,RGSCH_PCELL_INDEX);
3996 cell->sc.apis->rgSCHFreeUe(cell, ue);
3998 /* Stack Crash problem for TRACE5 changes. added the return below . */
4001 } /* rgSCHUtlFreeUe */
4004 * @brief This function updates the scheduler with service for a UE
4008 * Function: rgSCHUtlDlDedBoUpd
4009 * Purpose: This function should be called whenever there is a
4010 * change BO for a service.
4012 * Invoked by: BO and Scheduler
4014 * @param[in] RgSchCellCb* cell
4015 * @param[in] RgSchUeCb* ue
4016 * @param[in] RgSchDlLcCb* lc
4020 Void rgSCHUtlDlDedBoUpd
4027 Void rgSCHUtlDlDedBoUpd(cell, ue, lc)
4033 cell->sc.apis->rgSCHDlDedBoUpd(cell, ue, lc);
4037 * @brief Record MSG3 allocation into the UE
4041 * Function : rgSCHUtlRecMsg3Alloc
4043 * This function is invoked to update record msg3 allocation information
4044 * in the UE when UE is detected for RaCb
4046 * @param[in] RgSchCellCb *cell
4047 * @param[in] RgSchUeCb *ue
4048 * @param[in] RgSchRaCb *raCb
4052 Void rgSCHUtlRecMsg3Alloc
4059 Void rgSCHUtlRecMsg3Alloc(cell, ue, raCb)
4065 cell->sc.apis->rgSCHUlRecMsg3Alloc(cell, ue, raCb);
4068 } /* rgSCHRecMsg3Alloc */
4072 * @brief Update harq process for allocation
4076 * Function : rgSCHUtlUpdUlHqProc
4078 * This function is invoked when harq process
4079 * control block is now in a new memory location
4080 * thus requiring a pointer/reference update.
4082 * @param[in] RgSchCellCb *cell
4083 * @param[in] RgSchUlHqProcCb *curProc
4084 * @param[in] RgSchUlHqProcCb *oldProc
4090 S16 rgSCHUtlUpdUlHqProc
4093 RgSchUlHqProcCb *curProc,
4094 RgSchUlHqProcCb *oldProc
4097 S16 rgSCHUtlUpdUlHqProc(cell, curProc, oldProc)
4099 RgSchUlHqProcCb *curProc;
4100 RgSchUlHqProcCb *oldProc;
4103 return (cell->sc.apis->rgSCHUpdUlHqProc(cell, curProc, oldProc));
4104 } /* rgSCHUtlUpdUlHqProc */
4107 * @brief UL grant for contention resolution
4111 * Function : rgSCHUtlContResUlGrant
4113 * Add UE to another queue specifically for CRNTI based contention
4116 * @param[in] RgSchCellCb *cell
4117 * @param[in] RgSchUeCb *ue
4118 * @param[out] RgSchErrInfo *err
4124 S16 rgSCHUtlContResUlGrant
4131 S16 rgSCHUtlContResUlGrant(cell, ue, err)
4138 ue->isMsg4PdcchWithCrnti = TRUE;
4140 return (cell->sc.apis->rgSCHContResUlGrant(cell, ue, err));
4141 } /* rgSCHUtlContResUlGrant */
4144 * @brief SR reception handling
4148 * Function : rgSCHUtlSrRcvd
4150 * - Handles SR reception for UE
4152 * @param[in] RgSchCellCb *cell
4153 * @param[in] RgSchUeCb *ue
4154 * @param[out] RgSchErrInfo *err
4164 CmLteTimingInfo frm,
4168 S16 rgSCHUtlSrRcvd(cell, ue, frm, err)
4171 CmLteTimingInfo frm;
4175 return (cell->sc.apis->rgSCHSrRcvd(cell, ue, frm, err));
4176 } /* rgSCHUtlSrRcvd */
4179 * @brief Short BSR update
4183 * Function : rgSCHUtlUpdBsrShort
4185 * This functions does requisite updates to handle short BSR reporting
4187 * @param[in] RgSchCellCb *cell
4188 * @param[in] RgSchUeCb *ue
4189 * @param[in] U8 lcgId
4191 * @param[out] RgSchErrInfo *err
4197 Void rgSCHUtlUpdBsrShort
4206 Void rgSCHUtlUpdBsrShort(cell, ue, lcgId, bsr, err)
4214 cell->sc.apis->rgSCHUpdBsrShort(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4216 } /* rgSCHUtlUpdBsrShort */
4220 * @brief Truncated BSR update
4224 * Function : rgSCHUtlUpdBsrTrunc
4226 * This functions does required updates to handle truncated BSR report
4229 * @param[in] RgSchCellCb *cell
4230 * @param[in] RgSchUeCb *ue
4231 * @param[in] U8 lcgId
4233 * @param[out] RgSchErrInfo *err
4239 Void rgSCHUtlUpdBsrTrunc
4248 Void rgSCHUtlUpdBsrTrunc(cell, ue, lcgId, bsr, err)
4256 cell->sc.apis->rgSCHUpdBsrTrunc(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
4258 } /* rgSCHUtlUpdBsrTrunc */
4262 * @brief Long BSR update
4266 * Function : rgSCHUtlUpdBsrLong
4268 * - Update BSRs for all configured LCGs
4269 * - Update priority of LCGs if needed
4270 * - Update UE's position within/across uplink scheduling queues
4273 * @param[in] RgSchCellCb *cell
4274 * @param[in] RgSchUeCb *ue
4275 * @param[in] U8 bsr0
4276 * @param[in] U8 bsr1
4277 * @param[in] U8 bsr2
4278 * @param[in] U8 bsr3
4279 * @param[out] RgSchErrInfo *err
4285 Void rgSCHUtlUpdBsrLong
4296 Void rgSCHUtlUpdBsrLong(cell, ue, bsr0, bsr1, bsr2, bsr3, err)
4312 cell->sc.apis->rgSCHUpdBsrLong(cell, ue, bsArr, err);
4314 } /* rgSCHUtlUpdBsrLong */
4317 * @brief EXT PHR update
4321 * Function : rgSCHUtlUpdExtPhr
4323 * Updates extended power headroom info for a UE
4325 * @param[in] RgSchCellCb *cell
4326 * @param[in] RgSchUeCb *ue
4328 * @param[out] RgSchErrInfo *err
4334 S16 rgSCHUtlUpdExtPhr
4338 RgInfExtPhrCEInfo * extPhr,
4342 S16 rgSCHUtlUpdExtPhr(cell, ue, extPhr, err)
4345 RgInfExtPhrCEInfo * extPhr;
4349 return (cell->sc.apis->rgSCHUpdExtPhr(cell, ue, extPhr, err));
4350 } /* rgSCHUtlUpdExtPhr */
4359 * Function : rgSCHUtlUpdPhr
4361 * Updates power headroom info for a UE
4363 * @param[in] RgSchCellCb *cell
4364 * @param[in] RgSchUeCb *ue
4366 * @param[out] RgSchErrInfo *err
4380 S16 rgSCHUtlUpdPhr(cell, ue, phr, err)
4387 return (cell->sc.apis->rgSCHUpdPhr(cell, ue, phr, err));
4388 } /* rgSCHUtlUpdPhr */
4392 * @brief Indication of UL CQI
4396 * Function : rgSCHUtlUlCqiInd
4398 * - Updates uplink CQI information for the UE. Computes and
4399 * stores the lowest CQI of CQIs reported in all subbands
4401 * @param[in] RgSchCellCb *cell
4402 * @param[in] RgSchUeCb *ue
4403 * @param[in] TfuUlCqiRpt *ulCqiInfo
4407 Void rgSCHUtlUlCqiInd
4411 TfuUlCqiRpt *ulCqiInfo
4414 Void rgSCHUtlUlCqiInd(cell, ue, ulCqiInfo)
4417 TfuUlCqiRpt *ulCqiInfo;
4420 cell->sc.apis->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
4422 } /* rgSCHUtlUlCqiInd */
4425 * @brief Indication of PUCCH power adjustment
4429 * Function : rgSCHUtlPucchDeltaPwrInd
4431 * - Updates uplink CQI information for the UE. Computes and
4432 * stores the lowest CQI of CQIs reported in all subbands
4434 * @param[in] RgSchCellCb *cell
4435 * @param[in] RgSchUeCb *ue
4436 * @param[in] U8 delta
4440 Void rgSCHUtlPucchDeltaPwrInd
4447 Void rgSCHUtlPucchDeltaPwrInd(cell, ue, delta)
4453 cell->sc.apis->rgSCHPucchDeltaPwrInd(cell, ue, delta);
4455 } /* rgSCHUtlPucchDeltaPwrInd */
4457 /* Start: LTEMAC_2.1_DEV_CFG */
4459 * @brief Ue Reset Request
4463 * Function : rgSCHUtlUeReset
4466 * @param[in] RgSchCellCb *cell
4467 * @param[in] RgSchUeCb *ue
4471 Void rgSCHUtlUeReset
4477 Void rgSCHUtlUeReset(cell, ue)
4483 cell->sc.apis->rgSCHUeReset(cell, ue);
4485 } /* rgSCHUtlUeReset */
4486 /* End: LTEMAC_2.1_DEV_CFG */
4489 * @brief Returns HARQ proc for which data expected now
4493 * Function: rgSCHUtlUlHqProcForUe
4494 * Purpose: This function returns the harq process for
4495 * which data is expected in the current slot.
4496 * It does not validate if the HARQ process
4497 * has an allocation.
4501 * @param[in] RgSchCellCb *cell
4502 * @param[in] CmLteTimingInfo frm
4503 * @param[in] RgSchUeCb *ue
4504 * @param[out] RgSchUlHqProcCb **procRef
4508 Void rgSCHUtlUlHqProcForUe
4511 CmLteTimingInfo frm,
4513 RgSchUlHqProcCb **procRef
4516 Void rgSCHUtlUlHqProcForUe(cell, frm, ue, procRef)
4518 CmLteTimingInfo frm;
4520 RgSchUlHqProcCb **procRef;
4523 cell->sc.apis->rgSCHUlHqProcForUe(cell, frm, ue, procRef);
4525 /* Stack Crash problems for TRACE5 changes. added the return below */
4531 * @brief Returns first uplink allocation to send reception
4536 * Function: rgSCHUtlFirstRcptnReq(cell)
4537 * Purpose: This function returns the first uplink allocation
4538 * (or NULLP if there is none) in the slot
4539 * in which is expected to prepare and send reception
4544 * @param[in] RgSchCellCb *cell
4545 * @return RgSchUlAlloc*
4548 RgSchUlAlloc *rgSCHUtlFirstRcptnReq
4553 RgSchUlAlloc *rgSCHUtlFirstRcptnReq(cell)
4557 return (cell->sc.apis->rgSCHFirstRcptnReq(cell));
4561 * @brief Returns first uplink allocation to send reception
4566 * Function: rgSCHUtlNextRcptnReq(cell)
4567 * Purpose: This function returns the next uplink allocation
4568 * (or NULLP if there is none) in the slot
4569 * in which is expected to prepare and send reception
4574 * @param[in] RgSchCellCb *cell
4575 * @return RgSchUlAlloc*
4578 RgSchUlAlloc *rgSCHUtlNextRcptnReq
4584 RgSchUlAlloc *rgSCHUtlNextRcptnReq(cell, alloc)
4586 RgSchUlAlloc *alloc;
4589 return (cell->sc.apis->rgSCHNextRcptnReq(cell, alloc));
4593 * @brief Returns first uplink allocation to send HARQ feedback
4598 * Function: rgSCHUtlFirstHqFdbkAlloc
4599 * Purpose: This function returns the first uplink allocation
4600 * (or NULLP if there is none) in the slot
4601 * in which it is expected to prepare and send HARQ
4606 * @param[in] RgSchCellCb *cell
4608 * @return RgSchUlAlloc*
4611 RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc
4617 RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc(cell, idx)
4622 return (cell->sc.apis->rgSCHFirstHqFdbkAlloc(cell, idx));
4627 * @brief Returns next allocation to send HARQ feedback for
4631 * Function: rgSCHUtlNextHqFdbkAlloc(cell)
4632 * Purpose: This function returns the next uplink allocation
4633 * (or NULLP if there is none) in the slot
4634 * for which HARQ feedback needs to be sent.
4638 * @param[in] RgSchCellCb *cell
4639 * @return RgSchUlAlloc*
4642 RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc
4645 RgSchUlAlloc *alloc,
4649 RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc(cell, alloc, idx)
4651 RgSchUlAlloc *alloc;
4655 return (cell->sc.apis->rgSCHNextHqFdbkAlloc(cell, alloc, idx));
4658 /***********************************
4659 ***********************************/
4661 * @brief This API is invoked to send TFU SAP bind request to PHY.
4665 * Function : rgSCHUtlTfuBndReq
4667 * This API is invoked to send TFU SAP bind request to PHY from scheduler
4668 * isntance. It fills in the Pst structure, spId and suId values and
4669 * invokes bind request primitive at TFU.
4671 * @param[in] Inst instId
4672 * @param[in] SuId suId
4673 * @param[in] SpId spId
4679 S16 rgSCHUtlTfuBndReq
4686 S16 rgSCHUtlTfuBndReq(instId, suId, spId)
4693 RgSchLowSapCb *tfuSap;
4696 /* Get the lower SAP control block from the layer control block. */
4697 tfuSap = &(rgSchCb[instId].tfuSap[suId]);
4698 memcpy (&pst, &(tfuSap->sapCfg.sapPst), sizeof(Pst));
4699 if((ret = RgLiTfuSchBndReq (&pst, suId, spId)) != ROK)
4701 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlTfuBndReq() Call to RgLiTfuBndReq()"
4705 } /* rgSCHUtlTfuBndReq */
4708 * @brief This API is invoked to send TFU SAP unbind request to PHY.
4712 * Function : rgSCHUtlTfuUBndReq
4713 * This API is invoked to send TFU SAP unbind request to PHY from Scheduler
4714 * isntance. It fills in the Pst structure and spId value and invokes
4715 * unbind request primitive at TFU.
4717 * @param[in] SpId spId
4723 S16 rgSCHUtlTfuUBndReq
4726 RgSchLowSapCfgInfo sapCfg,
4730 S16 rgSCHUtlTfuUBndReq(inst, sapCfg, reason)
4732 RgSchLowSapCfgInfo sapCfg;
4739 /* Get the lower SAP control block from the layer control block. */
4740 memcpy (&pst, &(sapCfg.sapPst), sizeof(Pst));
4741 if((ret = RgLiTfuSchUbndReq (&pst, sapCfg.spId, reason)) != ROK)
4743 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuUBndReq() Call to"
4744 " RgLiTfuUbndReq() failed");
4748 } /* rgSCHUtlTfuUBndReq */
4750 /***********************************************************
4752 * Func : rgSCHUtlResetSfAlloc
4754 * Desc : Utility Function to Reset slot allocation information.
4763 **********************************************************/
4765 S16 rgSCHUtlResetSfAlloc
4767 RgInfSfAlloc *sfAlloc,
4768 Bool resetCmnLcInfo,
4772 S16 rgSCHUtlResetSfAlloc(sfAlloc,resetCmnLcInfo,restAlloc)
4773 RgInfSfAlloc *sfAlloc;
4774 Bool resetCmnLcInfo;
4778 if(TRUE == restAlloc)
4780 if(sfAlloc->ueInfo.numUes)
4782 memset(sfAlloc->ueInfo.allocInfo,0x00,
4783 (sizeof(RgInfUeAlloc)*sfAlloc->ueInfo.numUes));
4785 sfAlloc->ueInfo.numUes = 0;
4786 sfAlloc->rarInfo.numRaRntis = 0;
4787 sfAlloc->flowCntrlInfo.numUes = 0;
4789 if(TRUE == resetCmnLcInfo)
4791 sfAlloc->cmnLcInfo.bitMask = 0;
4796 /***********************************************************
4798 * Func : rgSCHUtlGetRlsHqAlloc
4800 * Desc : Utility Function to Allocate slot allocation information.
4809 **********************************************************/
4811 S16 rgSCHUtlGetRlsHqAlloc
4816 S16 rgSCHUtlGetRlsHqAlloc(cell)
4821 Inst inst = cell->instIdx;
4822 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4824 cell->rlsHqArr[idx].cellId = cell->cellId;
4826 /* Allocating with additional location, to accommodate
4827 TA scheduling along with maximum no of UEs per SF */
4829 /* Allocate memory for "scheduled UE" Info */
4830 if((rgSCHUtlAllocSBuf(inst,
4831 (Data**)&(cell->rlsHqArr[idx].ueHqInfo),
4832 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
4834 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4844 /***********************************************************
4846 * Func : rgSCHUtlPutRlsHqAlloc
4848 * Desc : Utility Function to deallocate slot allocation information.
4857 **********************************************************/
4859 S16 rgSCHUtlPutRlsHqAlloc
4864 S16 rgSCHUtlPutRlsHqAlloc(cell)
4869 Inst inst = cell->instIdx;
4871 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4873 /* Deallocate memory for "scheduled UE" Info */
4874 if (cell->rlsHqArr[idx].ueHqInfo != NULLP)
4876 /* Freeing with additional location, to accommodate TA
4877 scheduling along with maximum no of UEs per SF */
4878 /* ccpu00117052 - MOD - Passing double pointer
4879 for proper NULLP assignment*/
4880 rgSCHUtlFreeSBuf(inst,
4881 (Data **)(&(cell->rlsHqArr[idx].ueHqInfo)),
4882 (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF));
4891 /***********************************************************
4893 * Func : rgSCHUtlGetSfAlloc
4895 * Desc : Utility Function to Allocate slot allocation information.
4904 **********************************************************/
4906 S16 rgSCHUtlGetSfAlloc
4911 S16 rgSCHUtlGetSfAlloc(cell)
4917 Inst inst = cell->instIdx;
4918 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
4921 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
4923 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
4926 cell->sfAllocArr[idx].cellId = cell->cellId;
4928 /* Allocating with additional location, to accommodate
4929 TA scheduling along with maximum no of UEs per SF */
4931 /* Allocate memory for "scheduled UE" Info */
4932 if((rgSCHUtlAllocSBuf(inst,
4933 (Data**)&(cell->sfAllocArr[idx].ueInfo.allocInfo),
4934 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
4936 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4941 /* Allocate memory for "scheduled RAR" Info */
4942 if((rgSCHUtlAllocSBuf(inst,
4943 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo),
4944 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF))) != ROK)
4946 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4950 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
4952 if((rgSCHUtlAllocSBuf(inst,
4953 (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo),
4954 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)))) != ROK)
4956 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Memory allocation FAILED for "
4965 rgSCHEmtcUtlGetSfAlloc(cell);
4972 /***********************************************************
4974 * Func : rgSCHUtlPutSfAlloc
4976 * Desc : Utility Function to deallocate slot allocation information.
4985 **********************************************************/
4987 S16 rgSCHUtlPutSfAlloc
4992 S16 rgSCHUtlPutSfAlloc(cell)
4998 Inst inst = cell->instIdx;
4999 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
5002 for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
5004 for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
5007 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo != NULLP)
5009 for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
5011 if (cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo != NULLP)
5012 /* ccpu00117052 - MOD - Passing double pointer
5013 for proper NULLP assignment*/
5014 rgSCHUtlFreeSBuf(inst,
5015 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].\
5017 (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)));
5019 /* Deallocate memory for "scheduled RAR" Info */
5020 /* ccpu00117052 - MOD - Passing double pointer
5021 for proper NULLP assignment*/
5022 rgSCHUtlFreeSBuf(inst,
5023 (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo)),
5024 (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF));
5026 /* Deallocate memory for "scheduled UE" Info */
5027 if (cell->sfAllocArr[idx].ueInfo.allocInfo != NULLP)
5029 /* Freeing with additional location, to accommodate TA
5030 scheduling along with maximum no of UEs per SF */
5031 /* ccpu00117052 - MOD - Passing double pointer
5032 for proper NULLP assignment*/
5033 rgSCHUtlFreeSBuf(inst,
5034 (Data**)(&(cell->sfAllocArr[idx].ueInfo.allocInfo)),
5035 (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF));
5040 rgSCHEmtcUtlPutSfAlloc(cell);
5046 /***********************************************************
5048 * Func : rgSCHUtlAllocSBuf
5050 * Desc : Utility Function to Allocate static buffer.
5051 * Memory allocated is assumed contiguous.
5057 * Notes: Caller doesnt need to raise the alarm in case of memory
5058 * allocation gets failed.
5062 **********************************************************/
5064 S16 rgSCHUtlAllocSBuf
5066 Inst inst, /* Instance of the invoking scheduler */
5067 Data **pData, /* Pointer of the data to be returned */
5068 Size size /* size */
5071 S16 rgSCHUtlAllocSBuf(inst, pData, size)
5072 Inst inst; /* Instance of the invoking scheduler */
5073 Data **pData; /* Pointer of the data to be returned */
5074 Size size; /* size */
5077 /* Moving alarm diagnostics to available scope */
5079 /* Initialize the param to NULLP */
5082 /* May not be necessary for data performance path */
5090 /* allocate buffer */
5091 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5092 MS_BUF_ADD_ALLOC_CALLER();
5094 if (SGetSBuf(rgSchCb[inst].rgSchInit.region, rgSchCb[inst].rgSchInit.pool,
5095 pData, size) != ROK)
5097 RgUstaDgn dgn; /* Alarm diagnostics structure */
5098 dgn.type = LRG_USTA_DGNVAL_MEM;
5099 dgn.u.mem.region = rgSchCb[inst].rgSchInit.region;
5100 dgn.u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5101 /* Send an alarm to Layer Manager */
5102 rgSCHLmmStaInd(inst, LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
5103 LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
5104 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG015, 0, "Unable to Allocate Buffer");
5105 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Unable to Allocate the Buffer");
5110 /* zero out the allocated memory */
5111 memset(*pData, 0x00, size);
5115 } /* end of rgSCHUtlAllocSBuf */
5120 * Fun: rgSCHUtlFreeSBuf
5122 * Desc: The argument to rgSCHUtlFreeSBuf() is a pointer to a block
5123 * previously allocated by rgSCHUtlAllocSBuf() and size. It
5124 * deallocates the memory.
5132 Void rgSCHUtlFreeSBuf
5134 Inst inst, /* Instance of the invoking scheduler */
5135 Data **data, /* pointer to data */
5136 Size size /* size */
5139 Void rgSCHUtlFreeSBuf(inst, data, size)
5140 Inst inst; /* Instance of the invoking scheduler */
5141 Data **data; /* pointer to data */
5142 Size size; /* size */
5148 if ((data == NULLP) || (*data == NULLP) || (size == 0))
5154 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5155 MS_BUF_ADD_CALLER();
5157 /* Deallocate buffer */
5158 ret = SPutSBuf(rgSchCb[inst].rgSchInit.region,
5159 rgSchCb[inst].rgSchInit.pool, (*data), size);
5163 RGSCHLOGERROR(inst, ERRCLS_DEBUG, ERG016, (ErrVal) 0,
5164 "rgSCHUtlFreeSBuf failed.\n");
5165 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "rgSCHUtlFreeSBuf failed");
5169 /* ccpu00117052 - ADD - Assigning the pointer to NULLP */
5173 } /* end of rgSCHUtlFreeSBuf */
5179 * Fun: rgSCHUtlFreeWarningSiSeg
5181 * Desc: This is used to deallocate Warning SI Seg.
5190 Void rgSCHUtlFreeWarningSiSeg
5197 Void rgSCHUtlFreeWarningSiSeg(reg, pool, siPduLst)
5200 CmLListCp *siPduLst;
5206 while (siPduLst->first != NULLP)
5208 node = siPduLst->first;
5209 pdu = (Buffer *)node->node;
5210 cmLListDelFrm(siPduLst, node);
5211 RGSCH_FREE_MSG(pdu);
5212 SPutSBuf(reg, pool, (Data *)node,sizeof(CmLList));
5217 } /* end of rgSCHUtlFreeWarningSiSeg */
5222 * Fun: rgSCHUtlFreeWarningSiPdu
5224 * Desc: This is used to deallocate Warning SI PDU.
5233 Void rgSCHUtlFreeWarningSiPdu
5238 Void rgSCHUtlFreeWarningSiPdu(cell)
5244 RgSchWarningSiInfo *warningSi;
5245 RgSchWarningSiPdu *warningSiPdu;
5247 warningSi = (RgSchWarningSiInfo *) cell->siCb.\
5248 siArray[cell->siCb.siCtx.siId-1].si;
5249 /* ccpu00136659: CMAS ETWS design changes */
5250 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5256 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5257 pdu = warningSiPdu->pdu;
5258 /* ccpu00136659: CMAS ETWS design changes */
5259 cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node);
5260 RGSCH_FREE_MSG(pdu);
5261 if(warningSi->warningSiMsg.segLstCp.count == 0)
5263 /* ccpu00136659: CMAS ETWS design changes */
5264 cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP;
5265 rgSCHUtlRgrWarningSiCfgCfm(cell->instIdx,
5266 rgSchCb[cell->instIdx].rgrSap->sapCfg.spId,
5267 cell->siCb.warningSi[warningSi->idx].siId,
5268 warningSi->warningSiMsg.transId, RGR_CFG_CFM_TX_COMPLETE);
5273 } /* end of rgSCHUtlFreeWarningSiPdu */
5278 * Fun: rgSCHUtlGetWarningSiPdu
5280 * Desc: This is used to get Warning SI PDU for Scheduling.
5289 Buffer *rgSCHUtlGetWarningSiPdu
5294 Buffer *rgSCHUtlGetWarningSiPdu(cell)
5298 RgSchWarningSiInfo *warningSi;
5299 RgSchWarningSiPdu *warningSiPdu;
5303 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5304 siArray[cell->siCb.siCtx.siId-1].si;
5305 /* ccpu00136659: CMAS ETWS design changes */
5306 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5309 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5310 pdu = warningSiPdu->pdu;
5317 } /* rgSCHUtlGetWarningSiPdu */
5322 * Fun: rgSCHUtlGetMcsAndNPrb
5324 * Desc: This is used to get mcs and nPrb value.
5333 S16 rgSCHUtlGetMcsAndNPrb
5341 S16 rgSCHUtlGetMcsAndNPrb(cell, nPrb, mcs, msgLen)
5348 RgSchWarningSiInfo *warningSi;
5349 RgSchWarningSiPdu *warningSiPdu;
5352 if(cell->siCb.siCtx.warningSiFlag == FALSE)
5354 *mcs = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].mcs;
5355 *nPrb = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].nPrb;
5356 *msgLen = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].msgLen;
5360 warningSi = (RgSchWarningSiInfo *) cell->siCb.
5361 siArray[cell->siCb.siCtx.siId-1].si;
5362 /* ccpu00136659: CMAS ETWS design changes */
5363 CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
5369 warningSiPdu = (RgSchWarningSiPdu *)node->node;
5370 *mcs = warningSiPdu->mcs;
5371 *nPrb = warningSiPdu->nPrb;
5372 *msgLen = warningSiPdu->msgLen;
5377 } /* rgSCHUtlGetMcsAndNPrb */
5381 * Fun: rgSCHUtlCalMacAndPrb
5383 * Desc: This is used to Calculate mcs and nPrb value for SIB1 and SIs.
5392 S16 rgSCHUtlCalMcsAndNPrb
5400 S16 rgSCHUtlCalMcsAndNPrb(cell, nPrb, mcs, msgLen)
5410 /*Get the nPrb and mcs parametr values */
5411 if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8))
5413 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "msgLen does "
5414 "not match any valid TB Size");
5419 if(cfgType == RGR_SI_CFG_TYPE_SIB1 || cfgType == RGR_SI_CFG_TYPE_SIB1_PWS)
5422 if(cell->siCb.crntSiInfo.sib1Info.sib1 == NULLP)
5424 cell->siCb.crntSiInfo.sib1Info.mcs = mcs;
5425 cell->siCb.crntSiInfo.sib1Info.nPrb = nPrb;
5426 cell->siCb.crntSiInfo.sib1Info.msgLen = msgLen;
5430 cell->siCb.newSiInfo.sib1Info.mcs = mcs;
5431 cell->siCb.newSiInfo.sib1Info.nPrb= nPrb;
5432 cell->siCb.newSiInfo.sib1Info.msgLen = msgLen;
5437 if(cfgType == RGR_SI_CFG_TYPE_SI)
5439 if(cell->siCb.crntSiInfo.siInfo[siId-1].si == NULLP &&
5440 !(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD))
5442 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5443 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5444 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5448 cell->siCb.newSiInfo.siInfo[siId-1].mcs = mcs;
5449 cell->siCb.newSiInfo.siInfo[siId-1].nPrb= nPrb;
5450 cell->siCb.newSiInfo.siInfo[siId-1].msgLen = msgLen;
5454 if(cfgType == RGR_SI_CFG_TYPE_SIB8_CDMA)
5456 cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
5457 cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
5458 cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
5465 /***********************************************************
5467 * Func : rgSCHUtlFillDgnParams
5469 * Desc : Utility Function to Fill Diagonostic params.
5477 **********************************************************/
5479 Void rgSCHUtlFillDgnParams
5486 Void rgSCHUtlFillDgnParams(inst, dgn, dgnType)
5495 case LRG_USTA_DGNVAL_MEM:
5496 dgn->type = (U8) LRG_USTA_DGNVAL_MEM;
5497 dgn->u.mem.region = rgSchCb[inst].rgSchInit.region;
5498 dgn->u.mem.pool = rgSchCb[inst].rgSchInit.pool;
5506 } /* end of rgSCHUtlFillDgnParams */
5508 /***********************************************************
5510 * Func : rgSCHUtlGetPstToLyr
5512 * Desc : Utility Function to get the pst structure to post a message to MAC
5518 * Notes: This function should be called while sending a msg from
5519 * scheduler instance to MAC
5523 **********************************************************/
5525 Void rgSCHUtlGetPstToLyr
5532 Void rgSCHUtlGetPstToLyr (pst, schCb, macInst)
5539 /* Only the needed params are filled */
5540 pst->region = schCb->rgSchInit.region;
5541 pst->pool = schCb->rgSchInit.pool;
5542 pst->srcInst = schCb->rgSchInit.inst+SCH_INST_START;
5543 pst->srcProcId = schCb->rgSchInit.procId;
5544 pst->dstProcId = schCb->rgSchInit.procId;
5546 pst->dstInst = macInst;
5547 pst->dstEnt = ENTMAC;
5548 pst->srcEnt = ENTMAC;
5550 pst->prior = PRIOR0;
5552 pst->route = RTESPEC;
5555 } /* end of rgSCHUtlGetPstToLyr */
5557 /** @brief This function fills in the common lc information to be sent to MAC
5561 * Function: rgSCHUtlFillRgInfCmnLcInfo
5562 * @param RgSchDlSf *sf,
5563 * @param RgInfSfAlloc *sfAlloc,
5564 * @param CmLteLcId lcId,
5565 * @param Bool sendInd
5572 S16 rgSCHUtlFillRgInfCmnLcInfo
5575 RgInfSfAlloc *sfAlloc,
5580 S16 rgSCHUtlFillRgInfCmnLcInfo(sf, sfAlloc, lcId, sendInd)
5582 RgInfSfAlloc *sfAlloc;
5588 if((sf->bch.tbSize)&&
5589 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCH_INFO))
5592 sfAlloc->cmnLcInfo.bchInfo.lcId = lcId;
5594 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCH_INFO;
5596 else if((sf->bcch.pdcch != NULLP)&&
5597 !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCCH_INFO))
5599 sfAlloc->cmnLcInfo.bcchInfo.rnti = RGSCH_SI_RNTI;
5600 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.bcchInfo.dciInfo),
5601 &(sf->bcch.pdcch->dci));
5603 sfAlloc->cmnLcInfo.bcchInfo.lcId = lcId;
5604 sfAlloc->cmnLcInfo.bcchInfo.sndStatInd = sendInd;
5606 sfAlloc->cmnLcInfo.bitMask |= RGINF_BCCH_INFO;
5608 else if((sf->pcch.pdcch != NULLP) &&
5609 !(sfAlloc->cmnLcInfo.bitMask & RGINF_PCCH_INFO))
5611 sfAlloc->cmnLcInfo.pcchInfo.rnti = RGSCH_P_RNTI;
5612 rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.pcchInfo.dciInfo),
5613 &(sf->pcch.pdcch->dci));
5614 sfAlloc->cmnLcInfo.pcchInfo.lcId = lcId;
5615 sfAlloc->cmnLcInfo.bitMask |= RGINF_PCCH_INFO;
5620 /** @brief This function fills in the RAR information to be sent to MAC
5624 * Function: rgSCHUtlFillRgInfRarInfo
5626 * @param RgSchCellCb *cell
5627 * @param RgSchDlSf *sf
5628 * @param RgInfSfAlloc *sfAlloc
5634 S16 rgSCHUtlFillRgInfRarInfo
5637 RgInfSfAlloc *sfAlloc,
5641 S16 rgSCHUtlFillRgInfRarInfo(sf, sfAlloc, cell)
5643 RgInfSfAlloc *sfAlloc;
5652 RgInfRaRntiInfo *raRntiAlloc;
5654 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
5657 noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
5659 noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
5662 for(idx =0; idx < noRaRsps; idx++)
5664 if (sf->raRsp[idx].pdcch == NULLP)
5666 /* No further raResp Allocations. */
5669 /* Added Dl TB count for RACH Response transmission*/
5671 cell->dlUlTbCnt.tbTransDlTotalCnt++;
5673 raRntiAlloc = &(sfAlloc->rarInfo.raRntiInfo[idx]);
5674 raRntiAlloc->raRnti = sf->raRsp[idx].raRnti;
5675 raRntiAlloc->schdTbSz = sf->raRsp[idx].tbSz;
5676 raRntiAlloc->numCrnti = 0;
5677 rgSCHUtlFillPdschDciInfo(&(raRntiAlloc->dciInfo),
5678 &(sf->raRsp[idx].pdcch->dci));
5679 /* RACHO : fill backoff indicator information */
5680 raRntiAlloc->backOffInd = sf->raRsp[idx].backOffInd;
5682 /* Fill for contention free UEs*/
5683 lnkLst = &(sf->raRsp[idx].contFreeUeLst);
5684 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5687 ue = (RgSchUeCb *)tmp->node;
5689 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = ue->ueId;
5690 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = TRUE;
5691 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = ue->ul.rarGrnt.rapId;
5692 #ifndef MAC_5GTF_UPDATE
5693 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5695 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit =
5696 ue->ul.rarGrnt.cqiReqBit;
5698 /* SHASHAHNK ADD RIV CALC */
5699 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5700 ue->ul.rarGrnt.rbStart;
5701 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5702 ue->ul.rarGrnt.numRb;
5703 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5705 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5706 ue->ul.rarGrnt.iMcsCrnt;
5707 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta = ue->ul.rarGrnt.ta;
5708 raRntiAlloc->numCrnti++;
5709 cmLListDelFrm(lnkLst, &ue->ul.rarGrnt.raRspLnk);
5710 ue->ul.rarGrnt.raRspLnk.node = (PTR)NULLP;
5712 /* Fill for contention based UEs*/
5713 lnkLst = &(sf->raRsp[idx].raRspLst);
5715 CM_LLIST_FIRST_NODE(lnkLst, tmp);
5717 while((NULLP != tmp) && ((RgSchRaCb *)tmp->node != NULLP))
5719 raCb = (RgSchRaCb *)tmp->node;
5721 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = raCb->tmpCrnti;
5722 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = FALSE;
5723 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = raCb->rapId;
5724 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.pres = TRUE;
5725 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.val = raCb->ta.val;
5726 #ifndef MAC_5GTF_UPDATE
5727 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
5729 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = FALSE;
5731 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
5732 raCb->msg3Grnt.rbStart;
5733 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
5734 raCb->msg3Grnt.numRb;
5735 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
5737 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
5738 raCb->msg3Grnt.iMcsCrnt;
5739 raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.delayBit =
5740 raCb->msg3Grnt.delayBit;
5741 /* For initial attaching UEs Aperiodic CQI need not be triggered */
5742 raRntiAlloc->numCrnti++;
5743 /* Search the next node */
5744 CM_LLIST_NEXT_NODE(lnkLst, tmp);
5747 sfAlloc->rarInfo.numRaRntis = idx;
5748 /* ccpu00132314-ADD-Update the tx power allocation info
5749 TODO-Need to add a check for max tx power per symbol */
5750 sfAlloc->rarInfo.txPwrOffset = cellDl->rarTxPwrOffset;
5753 } /* end of rgSCHUtlFillRgInfRarInfo */
5755 /** @brief This function fills in the pdsch data related allocation Info
5756 * from the pdcch DCI info.
5761 * Function: rgSCHUtlFillPdschDciInfo
5764 * - Depending upon the DCI Format, fill the appropriate fields.
5766 * @param [out] TfuPdschDciInfo *pdschDci
5767 * @param [in] TfuDciInfo *pdcchDci
5773 S16 rgSCHUtlFillPdschDciInfo
5775 TfuPdschDciInfo *pdsch,
5776 TfuDciInfo *pdcchDci
5779 S16 rgSCHUtlFillPdschDciInfo(pdsch, pdcchDci)
5780 TfuPdschDciInfo *pdsch;
5781 TfuDciInfo *pdcchDci;
5788 pdsch->format = pdcchDci->dciFormat;
5789 switch(pdcchDci->dciFormat)
5791 case TFU_DCI_FORMAT_1:
5792 pdsch->u.format1AllocInfo = pdcchDci->u.format1Info.allocInfo;
5794 case TFU_DCI_FORMAT_1A:
5795 if (pdcchDci->u.format1aInfo.isPdcchOrder == FALSE)
5797 pdsch->u.format1aAllocInfo = pdcchDci->u.format1aInfo.t.pdschInfo.allocInfo;
5800 case TFU_DCI_FORMAT_1B:
5801 pdsch->u.format1bAllocInfo = pdcchDci->u.format1bInfo.allocInfo;
5803 case TFU_DCI_FORMAT_1C:
5804 pdsch->u.format1cAllocInfo = pdcchDci->u.format1cInfo;
5806 case TFU_DCI_FORMAT_1D:
5807 pdsch->u.format1dAllocInfo = pdcchDci->u.format1dInfo.allocInfo;
5809 case TFU_DCI_FORMAT_2:
5810 pdsch->u.format2AllocInfo = pdcchDci->u.format2Info.allocInfo;
5812 case TFU_DCI_FORMAT_2A:
5813 pdsch->u.format2AAllocInfo = pdcchDci->u.format2AInfo.allocInfo;
5816 case TFU_DCI_FORMAT_B1:
5817 pdsch->u.formatB1Info = pdcchDci->u.formatB1Info;
5819 case TFU_DCI_FORMAT_B2:
5820 pdsch->u.formatB2Info = pdcchDci->u.formatB2Info;
5825 ret = rgSCHEmtcUtlFillPdschDciInfo(pdsch, pdcchDci);
5837 /* LTE_ADV_FLAG_REMOVED_START */
5839 * @brief This function resets temporary variables in Pool
5842 * Function: rgSchSFRResetPoolVariables
5844 * Invoked by: rgSCHSFRUtlTotalPoolInit
5846 * @param[in] RgSchCellCb* cell
5847 * @param[in] RgSubFrm* subFrm
5852 Void rgSchDSFRPwrCheck
5855 Bool *isAllUePwrHigh
5858 PRIVATE Void rgSchDSFRPwrCheck(sf, isAllUePwrHigh)
5860 Bool *isAllUePwrHigh;
5864 RgSchSFRPoolInfo *sfrCCPool;
5869 l = &sf->sfrTotalPoolInfo.ccPool;
5870 n = cmLListFirst(l);
5873 sfrCCPool = (RgSchSFRPoolInfo*)n->node;
5874 if((sfrCCPool->poolstartRB == sfrCCPool->pwrHiCCRange.startRb) &&
5875 (sfrCCPool->poolendRB == sfrCCPool->pwrHiCCRange.endRb))
5882 *isAllUePwrHigh = TRUE;
5889 /* LTE_ADV_FLAG_REMOVED_END */
5890 /***********************************************************
5892 * Func : rgSCHUtlFillRgInfTbInfo
5894 * Desc : Utility Function to fill the allocation info of each Tb
5900 * Notes: This function should be called while sending a msg from
5901 * scheduler instance to MAC
5905 **********************************************************/
5907 PRIVATE Void rgSCHUtlFillRgInfTbInfo
5909 RgSchDlHqProcCb *hqP,
5910 RgInfUeAlloc *allocInfo,
5914 PRIVATE Void rgSCHUtlFillRgInfTbInfo (hqP, allocInfo, cell)
5915 RgSchDlHqProcCb *hqP;
5916 RgInfUeAlloc *allocInfo;
5922 RgInfUeTbInfo *tbInfo;
5924 /* LTE_ADV_FLAG_REMOVED_START */
5926 PRIVATE U32 tmpCnt = 0;
5927 Bool isAllUePwrHigh = FALSE;
5929 /* LTE_ADV_FLAG_REMOVED_END */
5930 RgSchDlLcCb *dlLcCb = NULLP;
5939 CmLteTimingInfo frm;
5941 /* Get Downlink slot */
5942 frm = cell->crntTime;
5943 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
5944 sf = rgSCHUtlSubFrmGet(cell, frm);
5945 /* Setting of fillCtrlPdu flag
5946 If both P-cell and S-cell are present,
5947 make TRUE for P-cell and FALSE for all s-cells
5948 For all other cases set TRUE */
5950 if ((rgSchCb[cell->instIdx].genCfg.forceCntrlSrbBoOnPCel) &&
5951 !RG_SCH_CMN_IS_PCELL_HQP(hqP))
5953 allocInfo->fillCtrlPdu = FALSE;
5957 allocInfo->fillCtrlPdu = TRUE;
5961 allocInfo->tbStrtIdx = -1;
5965 allocInfo->tbReqInfo.sCellHqPId = 0xff;
5966 rgSCHLaaHndlFillRgInfTbInfo(cell, hqP, allocInfo);
5969 /*TODO:REEMA: Check and fill the isRetx */
5970 for(tbCnt = 0; tbCnt < 2; tbCnt++)
5972 RgSchUeCb *ue = NULLP;
5973 /*Changed as a result of CR timer*/
5974 if ((hqP->hqE->ue != NULLP)/* &&
5975 ((hqP->tbInfo[tbCnt].lchSchdData[0].lcId != 0) || \
5976 (hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF))*/)
5979 allocInfo->rnti = ue->ueId;
5980 allocInfo->doa = hqP->hqE->ue->mimoInfo.doa;
5981 allocInfo->txMode = (TfuTxMode)(hqP->hqE->ue->mimoInfo.txMode);
5982 allocInfo->puschRptUsd = hqP->hqE->ue->mimoInfo.puschFdbkVld;
5983 allocInfo->puschPmiInfo = hqP->hqE->ue->mimoInfo.puschPmiInfo;
5984 if(hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF)
5986 hqP->tbInfo[tbCnt].taSnt = TRUE;
5989 if (RG_SCH_IS_PAPRSNT(ue,hqP->hqE->cell))
5991 /*update pA value */
5992 allocInfo->pa = (RG_SCH_CMN_GET_PA(ue,hqP->hqE->cell)).val;
5996 /* LTE_ADV_FLAG_REMOVED_START */
5997 /* If ABS is enabled, calculate resource used */
5998 if((0 == tbCnt) && (RGR_ENABLE == ue->cell->lteAdvCb.absCfg.status))
6000 /* For Macro count number resource used in Non-ABS SF */
6001 if(RGR_ABS_MUTE == ue->cell->lteAdvCb.absCfg.absPatternType)
6003 if(RG_SCH_ABS_ENABLED_NONABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6005 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6006 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6009 /* For pico count number resource used in ABS SF for ABS UE */
6010 else if(RGR_ABS_TRANSMIT == ue->cell->lteAdvCb.absCfg.absPatternType)
6012 if(RG_SCH_ABS_ENABLED_ABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
6014 if(TRUE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe)
6016 ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
6017 hqP->tbInfo[tbCnt].dlGrnt.numRb;
6024 /*if SFR is enabled*/
6025 allocInfo->isEnbSFR = (U8)RG_SCH_CMN_IS_SFR_ENB(ue->cell); /* KW fix for LTE_ADV */
6026 if((ue->cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) &&
6027 (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == FALSE))
6029 rgSchDSFRPwrCheck(sf, &isAllUePwrHigh);
6033 allocInfo->pa = (U8)ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh; /* KW fix for LTE_ADV */
6034 if(tmpCnt++ == 100000)
6036 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6037 "DSFR::ll UEs can go HIGH, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6043 if (allocInfo->isEnbSFR)
6045 /*Update pA to Plow if it is cell-centred ,else pA will be pHigh*/
6046 if (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == TRUE)
6048 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6049 if(tmpCnt++ == 100000)
6051 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6052 "SFR::UE is CELL EDGE, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
6059 if(TRUE == ue->lteAdvUeCb.isCCUePHigh)
6061 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
6062 ue->lteAdvUeCb.isCCUePHigh = FALSE;
6066 allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pLow;
6067 if(tmpCnt++ == 100000)
6069 RLOG_ARG2(L_DEBUG,DBG_CELLID,ue->cell->cellId,
6070 "SFR::UE is CELL CENTRE, PLow(%d) for UE(%d)\n",allocInfo->pa, ue->ueId);
6077 /* LTE_ADV_FLAG_REMOVED_END */
6085 RgSchCmnDlCell *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
6088 allocInfo->pdcchRnti = hqP->hqE->raCb->tmpCrnti;
6090 allocInfo->rnti = hqP->hqE->raCb->tmpCrnti;
6092 /*ccpu00132314-ADD-Use a default pA value
6094 allocInfo->pa = cellDl->msg4pAVal;
6098 /* If TB Is scheduled for this SF */
6099 if(hqP->tbInfo[tbCnt].state == HQ_TB_WAITING)
6101 if (allocInfo->tbStrtIdx == -1){
6102 allocInfo->tbStrtIdx = tbCnt;
6104 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6105 &(hqP->pdcch->dci));
6109 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6110 &(hqP->pdcch->dci));
6112 else if ((ue) && (ue->dl.spsOccPdcch.rnti == ue->spsRnti))
6114 rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
6115 &(ue->dl.spsOccPdcch.dci));
6117 #endif /* ifndef LTEMAC_SPS */
6122 allocInfo->pdcchRnti = hqP->pdcch->rnti;
6126 allocInfo->pdcchRnti = ue->spsRnti;
6129 tbInfo = &(allocInfo->tbInfo[tbCnt]);
6130 allocInfo->nmbOfTBs++;
6131 allocInfo->hqProcId = hqP->procId;
6132 allocInfo->tbInfo[tbCnt].schdTbSz = hqP->tbInfo[tbCnt].tbSz;
6134 tbInfo->disTb = FALSE;
6135 if(!(hqP->tbInfo[tbCnt].txCntr))
6138 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6139 rgSCHLaaSCellEnabled(cell))))
6142 hqP->tbInfo[tbCnt].txCntr++;
6144 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6146 tbInfo->schdDat[idx].lcId =\
6147 hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6148 tbInfo->schdDat[idx].numBytes =\
6149 hqP->tbInfo[tbCnt].lchSchdData[idx].schdData;
6152 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6155 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6158 RG_SCH_CMN_DL_GET_HDR_EST(dlLcCb, rlcHdrEstmt);
6159 /* Update the totalBo with the scheduled bo */
6160 (hqP->hqE->ue->totalBo <= tbInfo->schdDat[idx].numBytes - rlcHdrEstmt)?\
6161 (hqP->hqE->ue->totalBo = 0):\
6162 (hqP->hqE->ue->totalBo -= tbInfo->schdDat[idx].numBytes-rlcHdrEstmt);
6166 prbUsed = ((hqP->tbInfo[tbCnt].\
6167 lchSchdData[idx].schdData *
6168 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6169 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6170 dlLcCb->qciCb->dlPrbCount += prbUsed;
6171 if(dlLcCb->qciCb->qci > 0)
6173 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6175 #endif /* RRM_RBC_Y */
6178 //if(!(hqP->hqE->ue->pfsStats.lcStats[lcId-1].isLcCntSet))
6182 if (hqP->hqE->ue->cell == hqP->hqE->cell)
6184 idx = RGSCH_PCELL_INDEX;
6188 idx = RG_SCH_GET_SCELL_INDEX((hqP->hqE->ue), (hqP->hqE->cell));
6190 hqP->hqE->ue->pfsStats.lcStats[lcId-1].ueSchdOcc[idx]++;
6191 hqP->hqE->ue->pfsStats.lcStats[lcId-1].perRefresh[ue->pfsStats.lcStats[lcId-1].lastIdx].lcSchdOcc++;
6198 /* Added Dl TB count for SRB/DRB data transmission*/
6200 cell->dlUlTbCnt.tbTransDlTotalCnt++;
6202 tbInfo->ta.pres = hqP->tbInfo[tbCnt].schdTa.pres;
6203 tbInfo->ta.val = hqP->tbInfo[tbCnt].schdTa.val;
6205 tbInfo->sCellActCe = hqP->tbInfo[tbCnt].schdSCellActCe;
6207 tbInfo->numSchLch = hqP->tbInfo[tbCnt].numLch;
6208 if(!(hqP->tbInfo[tbCnt].numLch))
6210 tbInfo->schdDat[tbInfo->numSchLch].numBytes= hqP->tbInfo[tbCnt].tbSz;
6211 /* Fix: If only TA is scheduled, use some dummy LCID */
6212 if (tbInfo->ta.pres)
6213 tbInfo->schdDat[tbInfo->numSchLch].lcId = RG_TA_LCID;
6216 tbInfo->contResCe = hqP->tbInfo[tbCnt].contResCe;
6217 tbInfo->isReTx = FALSE;
6222 if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
6223 rgSCHLaaSCellEnabled(cell))))
6226 hqP->tbInfo[tbCnt].txCntr++;
6228 tbInfo->isReTx = TRUE;
6230 /* As per 36.314, harq retransmission also considered for
6231 * prb utilization calculation*/
6232 for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
6237 lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
6240 dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
6243 prbUsed = ((hqP->tbInfo[tbCnt].\
6244 lchSchdData[idx].schdData *
6245 hqP->tbInfo[tbCnt].dlGrnt.numRb) /
6246 (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
6247 if(dlLcCb->qciCb->qci > 0)
6249 RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
6261 rgSCHLaaResetDlHqProcCb(hqP);
6266 /***********************************************************
6268 * Func : rgSCHUtlFillRgInfUeInfo
6270 * Desc : Utility Function to fill the allocation info of Ue
6271 * : MIMO : Filling 2TB's of each UE
6276 * Notes: This function should be called while sending a msg from
6277 * scheduler instance to MAC
6281 **********************************************************/
6284 Void rgSCHUtlFillRgInfUeInfo
6288 CmLListCp *dlDrxInactvTmrLst,
6289 CmLListCp *dlInActvLst,
6290 CmLListCp *ulInActvLst
6293 Void rgSCHUtlFillRgInfUeInfo (sf,cell, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
6297 CmLListCp *dlDrxInactvTmrLst;
6298 CmLListCp *dlInActvLst;
6299 CmLListCp *ulInActvLst;
6302 RgInfSfAlloc *sfAlloc;
6303 CmLListCp *lnkLst; /* lnkLst assignment */
6306 RgSchUeCb *ue = NULLP;
6307 RgInfUeInfo *ueInfo = NULLP;
6308 RgInfUeAlloc *ueAlloc = NULLP;
6309 RgSchDlHqProcCb *hqCb = NULLP;
6311 /* Since Msg4 is sched only on PCELL, use cell arg's sfAllocArr */
6312 sfAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
6313 ueInfo = &(sfAlloc->ueInfo);
6314 ueAlloc = sfAlloc->ueInfo.allocInfo;
6316 lnkLst = &(sf->msg4HqPLst);
6317 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6320 printf("5GTF_ERROR MSG4 Consolidation\n");
6321 hqCb = (RgSchDlHqProcCb *)(tmp->node);
6322 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6324 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], cell);
6330 if((!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) && (ue->isDrxEnabled))
6332 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6333 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6339 lnkLst = &(sf->ueLst);
6340 CM_LLIST_FIRST_NODE(lnkLst, tmp);
6343 #if defined (TENB_STATS) && defined (RG_5GTF)
6344 cell->tenbStats->sch.dl5gtfPdschCons++;
6346 ue = (RgSchUeCb *)(tmp->node);
6347 CM_LLIST_NEXT_NODE(lnkLst, tmp);
6349 hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first;
6352 hqCb = (RgSchDlHqProcCb *)hqPNode->node;
6353 hqPNode = hqPNode->next;
6355 sfAlloc = &(hqCb->hqE->cell->sfAllocArr[hqCb->hqE->cell->crntSfIdx]);
6356 ueInfo = &(sfAlloc->ueInfo);
6357 ueAlloc = sfAlloc->ueInfo.allocInfo;
6359 rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes],
6362 if(ue->isDrxEnabled)
6364 rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes],
6365 dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
6370 if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE)
6372 /*If remaining BO is left then increment the count*/
6376 /* Check if trigger for Activation is met or not */
6377 if(rgSCHIsActvReqd(cell, ue))
6380 /*Passing primary cell*/
6381 rgSCHSCellSelectAndActDeAct(ue->cell, ue, RGR_SCELL_ACT);
6386 /*If remaining BO is 0 then reset the count*/
6394 } /* end of rgSCHUtlFillRgInfUeInfo */
6398 /** @brief This function shall update the scheduler with the CEs and data rcvd
6402 * Function: rgSCHUtlUpdSch
6405 * - Collate the information of all the SDUs received and inform the
6406 * scheduler rgSCHDataRcvd
6407 * - Send Data indication to the higher layer with the dedicated data
6408 * (rgUIMSndDedDatInd)
6409 * - Inform scheduler with any MAC CEs if present.
6411 * @param [in] RgCellCb *cellCb
6412 * @param [in] RgUeCb *ueCb
6413 * @param [in] RgMacPdu *pdu
6414 * @param [in] RgSchErrInfo *err
6422 RgInfSfDatInd *subfrmInfo,
6423 RgSchCellCb *cellCb,
6429 S16 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err)
6430 RgInfSfDatInd *subfrmInfo;
6431 RgSchCellCb *cellCb;
6441 if (RGSCH_UL_SPS_ACT_PRSENT & pdu->ceInfo.bitMask)
6443 /* SPS to be activated due to data on SPS LCG ID*/
6444 rgSCHUtlSpsActInd(cellCb, ueCb, pdu->ceInfo.spsSduSize);
6447 /* TODO : Temp Fix for crash due to UL SDU corruption*/
6448 if (RGSCH_PHR_CE_PRSNT & pdu->ceInfo.bitMask)
6451 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6452 if ((ret = rgSCHUtlUpdPhr(cellCb, ueCb, pdu->ceInfo.ces.phr, err)) != ROK)
6455 /* Note: Order of indication to Sch now is
6456 * 1st Indicate the DataInd info for each LCG's
6457 * 2nd Update the BSR reports received along with data
6458 * this is to make sure the effBsr is updated to the latest BSR
6461 cellCb->sc.apis->rgSCHUpdUeDataIndLcg(cellCb, ueCb, pdu);
6463 #ifndef MAC_5GTF_UPDATE
6464 if (RGSCH_TRUNC_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6466 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6467 /*ccpu00129922 - MOD - Deleted return value
6468 * checking since it returns void*/
6469 rgSCHUtlUpdBsrTrunc (cellCb, ueCb,
6470 (U8)(pdu->ceInfo.ces.bsr.truncBsr >> 6),
6471 (U8)(pdu->ceInfo.ces.bsr.truncBsr & 0x3F), err);
6475 if (RGSCH_SHORT_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6477 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6478 /*ccpu00129922 - MOD - Deleted return value
6479 checking since it returns void*/
6480 rgSCHUtlUpdBsrShort (cellCb, ueCb,
6481 (U8)(pdu->ceInfo.ces.bsr.shortBsr >> 6),
6482 (U8)(pdu->ceInfo.ces.bsr.shortBsr & 0x3F), err);
6486 if (RGSCH_LONG_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6488 if (RGSCH_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
6491 RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
6492 /*ccpu00129922 - MOD - Deleted return value
6493 checking since it returns void*/
6494 rgSCHUtlUpdBsrLong (cellCb, ueCb,
6495 pdu->ceInfo.ces.bsr.longBsr.bs1,
6496 pdu->ceInfo.ces.bsr.longBsr.bs2,
6497 pdu->ceInfo.ces.bsr.longBsr.bs3,
6498 pdu->ceInfo.ces.bsr.longBsr.bs4,
6501 #ifndef MAC_5GTF_UPDATE
6508 } /* end of rgSCHUtlUpdSch */
6511 * @brief Handler for Updating Bo received in StaRsp
6515 * Function : rgSCHUtlAddUeToCcchSduLst
6517 * This function shall be invoked once it receives staRsp on CCCH
6519 * @param[in] RgSchCellCb *cell
6520 * @param[in] RgSchUeCb *ueCb
6525 S16 rgSCHUtlAddUeToCcchSduLst
6531 S16 rgSCHUtlAddUeToCcchSduLst(cell, ueCb)
6536 RgSchCmnDlUe *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb, cell);
6537 RgSchDlHqProcCb *hqP = (RgSchDlHqProcCb *)ueDl->proc;
6539 /* Temp Guard: For back to back CCCH SDU BO
6540 * twice. Hence an extra guard. If already added to scheduling
6541 * queue or if scheduled and waiting for HQ FDBK, ignore */
6542 if ((ueCb->ccchSduLnk.node) ||
6543 ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
6544 ((hqP != NULLP) && (hqP->hqE->ccchSduProc))))
6546 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"RNTI:%d Unexpected CCCH SDU BO",
6551 ueCb->ccchSduLnk.node = (PTR)(ueCb);
6552 cmLListAdd2Tail(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
6560 * Function : rgSCHUtlUpdtBo
6562 * This function shall be invoked once it receives staRsp on CCCH
6564 * @param[in] RgSchCellCb *cell
6565 * @param[in] RgRguCmnStaRsp *staRsp
6573 RgInfCmnBoRpt *staRsp
6576 S16 rgSCHUtlUpdtBo(cell, staRsp)
6578 RgInfCmnBoRpt *staRsp;
6583 if ((ueCb = rgSCHDbmGetUeCb(cell, staRsp->u.rnti)) == NULLP)
6585 /* Handle Ue fetch failure */
6586 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid UEID:%d",staRsp->u.rnti);
6589 /* Update Bo in ueCb */
6590 ueCb->dlCcchInfo.bo = (U32)(staRsp->bo);
6594 rgSCHUtlAddUeToEmtcCcchSduLst(cell,ueCb);
6599 rgSCHUtlAddUeToCcchSduLst(cell, ueCb);
6603 } /* rgSCHUtlUpdtBo */
6609 * Function : rgSCHUtlHndlCcchBoUpdt
6611 * This function shall fetch the raCb with the given rnti and ask RAM to
6615 * @param[in] RgSchCellCb *cell
6616 * @param[in] RgInfCmnBoRpt *boRpt
6622 S16 rgSCHUtlHndlCcchBoUpdt
6625 RgInfCmnBoRpt *boRpt
6628 S16 rgSCHUtlHndlCcchBoUpdt(cell, boRpt)
6630 RgInfCmnBoRpt *boRpt;
6636 if ((raCb = rgSCHDbmGetRaCb(cell, boRpt->u.rnti)) == NULLP)
6639 /* CR timer implementation changes*/
6640 /*If no raCb, schedule ueCb, ueCb is extracted in rgSCHUtlUpdtBo*/
6641 return (rgSCHUtlUpdtBo(cell, boRpt));
6643 /* Handle RaCb fetch failure */
6644 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
6645 "Invalid RNTI:%d to fetch raCb",boRpt->u.rnti);
6652 /*Fix: If RaCb exists, then MSG4 is not completed yet*/
6653 /*Check if guard timer has expired, if not CR CE + CCCH SDU will be scheduled*/
6654 if((raCb->contResTmrLnk.node != NULLP) && \
6655 (raCb->schdLnk.node == NULLP) && (raCb->dlHqE->msg4Proc == NULLP))
6658 /*if contention resolution timer left ,Stop the Contention Resolution Guard Timer ,
6659 add in toBeSchduled list and update the Bo */
6660 if(TRUE == raCb->isEmtcRaCb)
6662 rgSCHRamEmtcUpdtBo(cell, raCb, boRpt);
6667 cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
6668 raCb->contResTmrLnk.node=NULLP;
6669 rgSCHRamUpdtBo(cell, raCb, boRpt);
6674 /*Fix:Guard timer has expired */
6675 /*Update the BO in UE CB but dont add it to the scheduling list.
6676 *Should be added to the list after MSG4 completion*/
6677 if ((ueCb = rgSCHDbmGetUeCb(cell, boRpt->u.rnti)) == NULLP)
6679 /* Handle Ue fetch failure */
6680 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid RNTI:%d",boRpt->u.rnti);
6683 /* Update Bo in ueCb */
6684 ueCb->dlCcchInfo.bo = (U32)(boRpt->bo);
6688 rgSCHRamUpdtBo(cell, raCb, boRpt);
6692 } /* rgSCHUtlHndlCcchBoUpdt */
6695 * @brief Validates BO received for BCCH or PCCH.
6699 * Function : rgSCHUtlGetAllwdCchTbSz
6701 * This function shall return the tbSz equal to or
6702 * the nearest greater value for a given bo.
6703 * If no such value found return -1. The nPrb value is
6708 * @param[out] U8 *nPrb
6714 S32 rgSCHUtlGetAllwdCchTbSz
6721 S32 rgSCHUtlGetAllwdCchTbSz(bo, nPrb, mcs)
6731 for (lt = 0, rt = 43; lt <= rt;)
6734 if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz == bo)
6736 *nPrb = rgSchUtlBcchPcchTbSzTbl[cn].rbIndex;
6737 *mcs = rgSchUtlBcchPcchTbSzTbl[cn].mcs;
6738 return (rgSchUtlBcchPcchTbSzTbl[cn].tbSz);
6740 else if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz < bo)
6749 *nPrb = rgSchUtlBcchPcchTbSzTbl[lt].rbIndex;
6750 *mcs = rgSchUtlBcchPcchTbSzTbl[lt].mcs;
6751 return (rgSchUtlBcchPcchTbSzTbl[lt].tbSz);
6755 * @brief Handler for BO Updt received for BCCH or PCCH.
6759 * Function : rgSCHUtlHndlBcchPcchBoUpdt
6761 * This function shall store the buffer and time to transmit in lcCb
6764 * @param[in] RgSchCellCb *cell
6765 * @param[in] RgInfCmnBoRpt *boRpt
6771 S16 rgSCHUtlHndlBcchPcchBoUpdt
6774 RgInfCmnBoRpt *boUpdt
6777 S16 rgSCHUtlHndlBcchPcchBoUpdt(cell, boUpdt)
6779 RgInfCmnBoRpt *boUpdt;
6782 RgSchClcDlLcCb *dlLc;
6783 RgSchClcBoRpt *boRpt;
6784 Inst inst = cell->instIdx;
6788 dlLc = rgSCHDbmGetBcchOnBch(cell);
6791 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6792 "No Logical Channel dlLc is NULLP for RNTI:%d LCID:%d",boUpdt->u.rnti,boUpdt->lcId);
6795 if (boUpdt->lcId != dlLc->lcId)
6797 /* Added for dropping paging Message*/
6799 if ((rgSCHChkBoUpdate(cell,boUpdt))== ROK) /* Checking if received BO falls within the window of 5120 slots*/
6801 if (rgSCHUtlGetAllwdCchTbSz(boUpdt->bo*8, &nPrb, &mcs)
6804 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,"[%ld]BO: does not match any "
6805 "valid TB Size RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6808 }/*end of rgSCHChkBoUpdate*/
6814 if ((dlLc = rgSCHDbmGetCmnLcCb(cell, boUpdt->lcId)) == NULLP)
6816 /* Handle lcCb fetch failure */
6817 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
6818 "LCID:%d Invalid for RNTI:%d",boUpdt->lcId,boUpdt->u.rnti);
6821 if (((rgSCHUtlAllocSBuf(inst, (Data **)(&boRpt), sizeof(RgSchClcBoRpt))) ==RFAILED) ||
6824 RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId, "Allocation of common bo %dreport "
6825 "failed RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
6829 boRpt->bo = boUpdt->bo;
6831 boRpt->timeToTx = boUpdt->u.timeToTx;
6834 if(cell->emtcEnable)
6836 boRpt->emtcDIReason = boUpdt->emtcDIReason;
6837 boRpt->pnb = boUpdt->pnb;
6840 RG_SCH_ADD_TO_CRNT_TIME(boRpt->timeToTx,
6841 boRpt->maxTimeToTx, cell->siCfg.siWinSize)
6842 if((NULLP != dlLc) && (dlLc->si))
6844 boRpt->retxCnt = cell->siCfg.retxCnt;
6850 rgSCHDbmInsCmnLcBoRpt(dlLc, boRpt);
6853 } /* rgSCHUtlHndlBcchPcchBoUpdt */
6856 * @brief API for sending bind confirm from Scheduler instance to RRM
6860 * Function: rgSCHUtlRgrBndCfm
6862 * This API is invoked to send bind confirm from Scheduler instance to RRM.
6863 * This API fills in Pst structure and SAP Ids and invokes
6864 * bind confirm API towards RRM.
6866 * @param[in] SuId suId
6867 * @param[in] U8 status
6873 S16 rgSCHUtlRgrBndCfm
6880 S16 rgSCHUtlRgrBndCfm(instId, suId, status)
6888 ret = RgUiRgrBndCfm(&rgSchCb[instId].rgrSap[suId].sapCfg.sapPst, rgSchCb[instId].rgrSap[suId].sapCfg.suId, status);
6891 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrBndCfm: RgUiRgrBndCfm Failed ");
6895 } /* rgSCHUtlRgrBndCfm*/
6898 * @brief API for sending bind confirm from Scheduler instance to RRM via RGM
6903 * Function: rgSCHUtlRgmBndCfm
6905 * This API is invoked to send bind confirm from Scheduler instance to RRM.
6906 * This API fills in Pst structure and SAP Ids and invokes
6908 * @param[in] SuId suId
6909 * @param[in] U8 status
6915 S16 rgSCHUtlRgmBndCfm
6922 S16 rgSCHUtlRgmBndCfm(instId, suId, status)
6930 ret = RgUiRgmBndCfm(&rgSchCb[instId].rgmSap[suId].sapCfg.sapPst, rgSchCb[instId].rgmSap[suId].sapCfg.suId, status);
6933 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgmBndCfm: RgUiRgrBndCfm Failed ");
6937 } /* rgSCHUtlRgmBndCfm*/
6942 * @brief API for sending configuration confirm from Scheduler to DU APP
6946 * Function: schSendCfgCfm
6948 * This API is invoked to send configuration confirm from Scheduler to DU
6951 * @param[in] Pst pst
6952 * @param[in] RgrCfgTransId transId
6953 * @param[in] U8 status
6963 RgrCfgTransId transId,
6967 S16 schSendCfgCfm(reg, pool, transId, status)
6970 RgrCfgTransId transId;
6977 memset((&cfmPst), 0, sizeof(Pst));
6979 cfmPst.srcEnt = (Ent)ENTDUAPP;
6980 cfmPst.srcInst = (Inst) 0;
6981 cfmPst.srcProcId = SFndProcId();
6982 cfmPst.dstEnt = (Ent)ENTMAC;
6983 cfmPst.dstInst = (Inst) 0;
6984 cfmPst.dstProcId = SFndProcId();
6985 cfmPst.selector = ODU_SELECTOR_LC;
6986 cfmPst.region = reg;
6989 if(RgUiRgrCfgCfm(&cfmPst,transId, status) != ROK)
6991 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"schSendCfgCfm: RgUiRgrCfgCfm Failed");
6992 printf("\nschSendCfgCfm: RgUiRgrCfgCfm Failed ");
6996 } /* schSendCfgCfm*/
6999 * @brief API for sending TTI indication from Scheduler to RRM.
7003 * Function: rgSCHUtlRgrTtiInd
7005 * This API is invoked to send TTI indication from Scheduler instance to RRM.
7006 * This API fills in Pst structure and RgrTtiIndInfo
7008 * @param[in] cell RgSchCellCb
7009 * @param[in] CmLteTimingInfo status
7015 S16 rgSCHUtlRgrTtiInd
7018 RgrTtiIndInfo *rgrTti
7021 S16 rgSCHUtlRgrTtiInd(cell, rgrTti)
7023 RgrTtiIndInfo *rgrTti;
7027 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
7029 extern Bool g_usettitmr;
7030 extern Void mtTmrHdlrPublic(void);
7033 rgrSap = cell->rgrSap;
7034 if (rgrSap->sapSta.sapState != LRG_BND)
7036 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
7037 "rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ",
7038 rgrSap->sapSta.sapState);
7041 RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst),
7042 cell->rgrSap->sapCfg.suId, rgrTti);
7050 } /* rgSCHUtlRgrTtiInd*/
7052 /** @brief This function is called by rgMacSchSfRecpInd. This function invokes the
7053 * scheduler with the information of the received Data and any Control Elements
7061 * - Retrieves the RaCb with the rnti provided, if it doesnt exist
7063 * - If UE exists then update the Schduler with any MAC CEs if present.
7064 * - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3
7066 * @param [in] RgSchCellCb *cellCb
7067 * @param [in] RgSchUeCb *ueCb
7068 * @param [in] CmLteRnti rnti
7069 * @param [in] RgMacPdu *pdu
7070 * @param [in] RgSchErrInfo *err
7077 S16 rgSCHUtlProcMsg3
7079 RgInfSfDatInd *subfrmInfo,
7080 RgSchCellCb *cellCb,
7087 S16 rgSCHUtlProcMsg3 (subfrmInfo, cellCb, ueCb, rnti, pdu, err)
7088 RgInfSfDatInd *subfrmInfo;
7089 RgSchCellCb *cellCb;
7099 /* must have an raCb for this case */
7100 raCb = rgSCHDbmGetRaCb (cellCb, rnti);
7103 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId, "RNTI:%d Received MSG3, unable to "
7108 /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that
7109 * effBsr of current case only will be considered in scheduling of ContResLst*/
7110 ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err);
7113 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,"Processing failed in the RAM "
7117 /* if ueCb is present */
7120 rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err);
7126 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7127 * scheduler with the information of the received Data.
7131 * Function: rgSCHUtlSpsRelInd
7136 * @param [in] RgSchCellCb *cellCb
7137 * @param [in] RgSchUeCb *ueCb
7138 * @param [in] Bool *isExplRel
7145 S16 rgSCHUtlSpsRelInd
7147 RgSchCellCb *cellCb,
7152 S16 rgSCHUtlSpsRelInd (cellCb, ueCb, isExplRel)
7153 RgSchCellCb *cellCb;
7158 cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel);
7160 } /* end of rgSCHUtlSpsRelInd */
7163 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
7164 * scheduler with the information of the received Data.
7168 * Function: rgSCHUtlSpsActInd
7173 * @param [in] RgSchCellCb *cellCb
7174 * @param [in] RgSchUeCb *ueCb
7175 * @param [in] U16 spsSduSize
7182 S16 rgSCHUtlSpsActInd
7184 RgSchCellCb *cellCb,
7189 S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize)
7190 RgSchCellCb *cellCb;
7195 cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize);
7197 } /* end of rgSCHUtlSpsActInd */
7200 #endif /* LTEMAC_SPS */
7204 * @brief This API is invoked to send uplink group power control request to PHY.
7208 * Function : rgSCHUtlTfuGrpPwrCntrlReq
7210 * This API is invoked to send uplink group power control request to PHY.
7211 * It fills in the Pst structure, spId value and invokes group power
7212 * control request primitive at TFU.
7214 * @param[in] TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7220 S16 rgSCHUtlTfuGrpPwrCntrlReq
7224 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
7227 S16 rgSCHUtlTfuGrpPwrCntrlReq(inst, sapId, grpPwrCntrlReq)
7230 TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq;
7234 RgSchLowSapCb *tfuSap;
7238 /* Get the lower SAP control block from the layer control block. */
7239 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7240 if (tfuSap->sapSta.sapState != LRG_BND)
7242 RLOG_ARG1(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7243 "rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState);
7246 memcpy (&pst, &(tfuSap->sapCfg.sapPst), sizeof(Pst));
7247 if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK)
7249 RLOG_ARG0(L_ERROR,DBG_CELLID,grpPwrCntrlReq->cellId,
7250 "rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed");
7253 } /* rgSCHUtlTfuGrpPwrCntrlReq */
7257 * @brief This API is invoked to send Control Info to PHY.
7261 * Function : rgSCHUtlTfuCntrlReq
7263 * This API is invoked to send Control Info to PHY. It
7264 * fills in the Pst structure, spId value and invokes Cntrl
7265 * request primitive at TFU.
7267 * @param[in] TfuCntrlReqInfo *cntrlReq
7273 S16 rgSCHUtlTfuCntrlReq
7277 TfuCntrlReqInfo *cntrlReq
7280 S16 rgSCHUtlTfuCntrlReq(inst, sapId, cntrlReq)
7283 TfuCntrlReqInfo *cntrlReq;
7287 RgSchLowSapCb *tfuSap;
7289 /* Get the lower SAP control block from the layer control block. */
7290 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7293 if (tfuSap->sapSta.sapState != LRG_BND)
7295 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Lower SAP not bound (%d) ",
7296 tfuSap->sapSta.sapState);
7297 RGSCH_FREE_MEM(cntrlReq);
7302 /* Using local variable for pst is unnecessary - for optimization */
7303 if((ret = RgLiTfuCntrlReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7306 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuCntrlReq() Call to RgLiTfuCntrlReq() failed");
7309 } /* rgSCHUtlTfuCntrlReq*/
7312 /* FOR ACK NACK REP */
7315 * @brief This API is invoked to tell the DL Scheduler to add the UE back into
7316 * its scheduling queues.
7320 * Function : rgSCHUtlDlActvtUe
7322 * This API is invoked from Measurement gap moduled.
7324 * @param[in] RgSchCellCb *cell
7325 * @param[in] RgSchUeCb *ueCb
7332 S16 rgSCHUtlDlActvtUe
7338 S16 rgSCHUtlDlActvtUe(cell, ue)
7343 cell->sc.apis->rgSCHActvtDlUe(cell, ue);
7348 * @brief This API is invoked to tell the UL Scheduler to add the UE back into
7349 * its scheduling queues.
7353 * Function : rgSCHUtlUlActvtUe
7355 * This API is invoked from Measurement gap moduled.
7357 * @param[in] RgSchCellCb *cell
7358 * @param[in] RgSchUeCb *ueCb
7365 S16 rgSCHUtlUlActvtUe
7371 S16 rgSCHUtlUlActvtUe(cell, ue)
7376 cell->sc.apis->rgSCHActvtUlUe(cell, ue);
7381 * @brief This API is invoked to send Reception Request Info to PHY.
7385 * Function : rgSCHUtlTfuRecpReq
7387 * This API is invoked to send Reception Request Info to PHY. It
7388 * fills in the Pst structure, spId value and invokes Reception
7389 * request primitive at TFU.
7391 * @param[in] TfuRecpReqInfo *recpReq
7397 S16 rgSCHUtlTfuRecpReq
7401 TfuRecpReqInfo *recpReq
7404 S16 rgSCHUtlTfuRecpReq(inst, sapId, recpReq)
7407 TfuRecpReqInfo *recpReq;
7411 RgSchLowSapCb *tfuSap;
7414 /* Get the lower SAP control block from the layer control block. */
7415 tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
7418 if (tfuSap->sapSta.sapState != LRG_BND)
7420 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Lower SAP not bound (%d) ",
7421 tfuSap->sapSta.sapState);
7422 RGSCH_FREE_MEM(recpReq);
7427 /* Using local variable for pst is unnecessary - for optimization */
7428 if((ret = RgLiTfuRecpReq(&tfuSap->sapCfg.sapPst, tfuSap->sapCfg.spId,
7431 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"rgSCHUtlTfuRecpReq() Call to RgLiTfuRecpReq() failed");
7434 } /* rgSCHUtlTfuRecpReq */
7436 /** @brief This function Validates the SAP information received along with the
7437 * primitive from the lower layer.
7439 * Function: rgSCHUtlValidateTfuSap
7441 * Validates SAP information.
7442 * @param suId The SAP Id
7448 S16 rgSCHUtlValidateTfuSap
7454 S16 rgSCHUtlValidateTfuSap(inst, suId)
7459 RgSchLowSapCb *tfuSap;
7461 if(suId >= rgSchCb[inst].numSaps)
7463 RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "Incorrect SuId");
7466 tfuSap = &(rgSchCb[inst].tfuSap[suId]);
7468 /* First lets check the suId */
7469 if( suId != tfuSap->sapCfg.suId)
7471 RLOG_ARG2(L_ERROR,DBG_INSTID,inst,"Incorrect SuId. Configured (%d) Recieved (%d)",
7472 tfuSap->sapCfg.suId, suId);
7475 if (tfuSap->sapSta.sapState != LRG_BND)
7477 RLOG_ARG1(L_ERROR,DBG_INSTID,inst,"Lower SAP not enabled SuId (%d)",
7478 tfuSap->sapCfg.suId);
7482 } /* end of rgSCHUtlValidateTfuSap */
7486 * Fun: rgSCHUtlAllocEventMem
7488 * Desc: This function allocates event memory
7490 * Ret: ROK - on success
7491 * RFAILED - on failure
7499 S16 rgSCHUtlAllocEventMem
7506 S16 rgSCHUtlAllocEventMem(inst, memPtr, memSize)
7513 VOLATILE U32 startTime=0;
7515 sMem.region = rgSchCb[inst].rgSchInit.region;
7516 sMem.pool = rgSchCb[inst].rgSchInit.pool;
7518 #if (ERRCLASS & ERRCLS_DEBUG)
7521 RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize,
7522 "rgAllocEventMem(): memSize invalid\n");
7525 #endif /* ERRCLASS & ERRCLS_DEBUG */
7527 SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
7529 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
7530 MS_BUF_ADD_ALLOC_CALLER();
7532 #ifdef TFU_ALLOC_EVENT_NO_INIT
7533 if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7535 if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7538 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed.");
7542 SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
7544 } /* end of rgSCHUtlAllocEventMem*/
7548 * Fun: rgGetEventMem
7550 * Desc: This function allocates event memory
7552 * Ret: ROK - on success
7553 * RFAILED - on failure
7561 S16 rgSCHUtlGetEventMem
7568 S16 rgSCHUtlGetEventMem(ptr, len, memCp)
7576 #ifdef TFU_ALLOC_EVENT_NO_INIT
7577 ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
7579 ret = cmGetMem(memCp, len, (Ptr *)ptr);
7582 } /* end of rgSCHUtlGetEventMem*/
7588 * @brief Handler to allocate memory for ACK/NACk feedback information
7592 * Function : rgSCHUtlAllocUeANFdbkInfo
7594 * It allocates memory for the UE related ACK NACK information.
7596 * @param[in] RgSchUeCb *ue
7600 S16 rgSCHUtlAllocUeANFdbkInfo
7606 S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx)
7613 if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
7614 (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
7615 ue->cell->ackNackFdbkArrSize) != ROK)
7620 for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
7622 rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
7625 /* Set it to the first index */
7626 ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
7628 } /* rgSCHUtlAllocUeANFdbkInfo */
7631 * @brief Handler to release memory for ACK/NACk feedback information
7635 * Function : rgSCHUtlDelUeANFdbkInfo
7637 * It releases memory for the UE related ACK NACK information.
7639 * @param[in] RgSchUeCb *ue
7643 Void rgSCHUtlDelUeANFdbkInfo
7649 Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx)
7655 /* ccpu00117052 - MOD - Passing double pointer
7656 for proper NULLP assignment*/
7657 rgSCHUtlFreeSBuf(ue->cell->instIdx,
7658 (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
7659 ue->cell->ackNackFdbkArrSize);
7662 } /* rgSCHUtlDelUeANFdbkInfo */
7665 * @brief Handler to initialise UE ACK/NACk feedback information
7669 * Function : rgSCHUtlInitUeANFdbkInfo
7671 * It initialises UE related ACK NACK information.
7673 * @param[in] RgSchTddANInfo *anFdInfo
7677 S16 rgSCHUtlInitUeANFdbkInfo
7679 RgSchTddANInfo *anFdInfo
7682 S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo)
7683 RgSchTddANInfo *anFdInfo;
7687 anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
7689 anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
7690 anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
7691 anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
7694 } /* rgSCHUtlInitUeANFdbkInfo */
7697 * @brief Handler to get UE related ACK NACK feedback information
7701 * Function : rgSCHUtlGetUeANFdbkInfo
7703 * It gets the UE related ACK NACK information based on
7704 * SFN and slot number.
7706 * @param[in] RgSchUeCb *ueCb
7707 * @param[in] CmLteTimingInfo *time
7708 * @return RgSchTddANInfo*
7711 RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo
7714 CmLteTimingInfo *timeInfo,
7718 RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx)
7720 CmLteTimingInfo *timeInfo;
7726 for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
7728 if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
7729 (timeInfo->slot == ueCb->cellInfo[servCellIdx]->anInfo[idx].slot))
7731 return (&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
7736 } /* rgSCHUtlGetUeANFdbkInfo */
7739 * @brief To get downlink slot index
7743 * Function: rgSCHUtlGetDlSfIdx
7744 * Purpose: Gets downlink slot index based on SFN and slot no
7746 * @param[in] CmLteTimingInfo *timeInfo
7747 * @param[in] RgSchCellCb *cell
7752 U8 rgSCHUtlGetDlSfIdx
7755 CmLteTimingInfo *timeInfo
7758 U8 rgSCHUtlGetDlSfIdx(cell, timeInfo)
7760 CmLteTimingInfo *timeInfo;
7765 idx = RGSCH_NUM_SUB_FRAMES - \
7766 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7767 idx = ((idx * timeInfo->sfn) + \
7768 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->slot]) - 1;
7769 idx = idx % cell->numDlSubfrms;
7775 * @brief To get the next downlink slot
7779 * Function: rgSCHUtlGetNxtDlSfInfo
7780 * Purpose: Gets next downlink slot based on current DL slot
7782 * @param[in] CmLteTimingInfo curDlTime
7783 * @param[in] RgSchCellCb *cell
7784 * @param[in] RgSchDlSf *dlSf
7785 * @param[in] RgSchDlSf **nxtDlsf
7786 * @param[in] CmLteTimingInfo *nxtDlTime
7791 Void rgSCHUtlGetNxtDlSfInfo
7793 CmLteTimingInfo curDlTime,
7796 RgSchDlSf **nxtDlsf,
7797 CmLteTimingInfo *nxtDlTime
7800 Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime)
7801 CmLteTimingInfo curDlTime;
7804 RgSchDlSf **nxtDlsf;
7805 CmLteTimingInfo *nxtDlTime;
7808 U16 idx = curDlTime.slot;
7815 idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
7817 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
7818 != RG_SCH_TDD_DL_slot);
7819 RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
7820 *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
7821 if(dlSf->dlFdbkInfo.slot != (*nxtDlsf)->dlFdbkInfo.slot)
7830 * @brief To get the previous downlink slot
7834 * Function: rgSCHUtlGetPrevDlSfInfo
7835 * Purpose: Gets previous downlink slot based on current DL slot
7837 * @param[in] RgSchCellCb *cell
7838 * @param[in] CmLteTimingInfo curDlTime
7839 * @param[in] CmLteTimingInfo *prevDlTime
7840 * @param[in] U8 *numSubfrm
7845 Void rgSCHUtlGetPrevDlSfInfo
7848 CmLteTimingInfo curDlTime,
7849 CmLteTimingInfo *prevDlTime,
7853 Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm)
7855 CmLteTimingInfo curDlTime;
7856 CmLteTimingInfo *prevDlTime;
7860 S16 idx = curDlTime.slot;
7868 idx = RGSCH_NUM_SUB_FRAMES-1;
7871 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
7872 != RG_SCH_TDD_DL_slot);
7874 RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
7879 /* Added Holes Management functions for Adaptive Re transmission */
7880 /******* </AllocHolesMemMgmnt>: START *****/
7881 /***********************************************************
7883 * Func : rgSCHUtlUlSfInit
7885 * Desc : UL slot init.
7893 **********************************************************/
7895 S16 rgSCHUtlUlSfInit
7903 S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf)
7918 if(cell->ulDlCfgIdx == 0)
7920 /* Store the Uplink slot number corresponding to the idx */
7921 sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6];
7924 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
7925 sizeof(RgSchUlAllocDb));
7930 ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
7933 /* ccpu00117052 - MOD - Passing double pointer
7934 for proper NULLP assignment*/
7935 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
7936 sizeof(RgSchUlAllocDb));
7939 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
7940 sizeof(RgSchUlHoleDb));
7943 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
7944 /* ccpu00117052 - MOD - Passing double pointer
7945 for proper NULLP assignment*/
7946 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
7947 sizeof(RgSchUlAllocDb));
7950 /* Initialize the hole with CFI 1 Pusch Bw Info */
7951 ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (U8)(maxUePerSf + 2), \
7952 0, cell->dynCfiCb.bwInfo[1].numSb);
7956 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
7957 /* ccpu00117052 - MOD - Passing double pointer
7958 for proper NULLP assignment*/
7959 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
7960 sizeof(RgSchUlAllocDb));
7961 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
7962 sizeof(RgSchUlHoleDb));
7965 cmLListInit(&sf->reTxLst);
7967 /* Fix ccpu00120610*/
7968 sf->allocCountRef = &sf->allocDb->count;
7970 /* initialize UL available subbands for current sub-frame */
7971 sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
7973 sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
7974 sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
7975 for(index = 0; index < MAX_5GTF_BEAMS; index++)
7977 sf->sfBeamInfo[index].totVrbgAllocated = 0;
7978 sf->sfBeamInfo[index].totVrbgRequired = 0;
7979 sf->sfBeamInfo[index].vrbgStart = 0;
7987 /***********************************************************
7989 * Func : rgSCHUtlUlSfDeinit
7991 * Desc : Deinitialises a slot
7999 **********************************************************/
8001 Void rgSCHUtlUlSfDeinit
8007 Void rgSCHUtlUlSfDeinit(cell, sf)
8014 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8015 /* ccpu00117052 - MOD - Passing double pointer
8016 for proper NULLP assignment*/
8017 /* ccpu00117052 - MOD - Passing double pointer
8018 for proper NULLP assignment*/
8019 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8020 sizeof(RgSchUlAllocDb));
8024 rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
8025 /* ccpu00117052 - MOD - Passing double pointer
8026 for proper NULLP assignment*/
8027 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8028 sizeof(RgSchUlHoleDb));
8033 /***********************************************************
8035 * Func : rgSCHUtlUlAllocDbInit
8037 * Desc : Initialise allocation DB
8039 * Ret : S16 (ROK/RFAILED)
8045 **********************************************************/
8047 PRIVATE S16 rgSCHUtlUlAllocDbInit
8050 RgSchUlAllocDb *allocDb,
8054 PRIVATE S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs)
8056 RgSchUlAllocDb *allocDb;
8060 S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
8066 allocDb->first = NULLP;
8070 /***********************************************************
8072 * Func : rgSCHUtlUlAllocDbDeinit
8074 * Desc : Deinitialises allocation DB
8075 * sent to UE, for a UE with accumulation disabled
8083 **********************************************************/
8085 PRIVATE Void rgSCHUtlUlAllocDbDeinit
8088 RgSchUlAllocDb *allocDb
8091 PRIVATE Void rgSCHUtlUlAllocDbDeinit(cell, allocDb)
8093 RgSchUlAllocDb *allocDb;
8096 rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
8098 allocDb->first = NULLP;
8102 /***********************************************************
8104 * Func : rgSCHUtlUlHoleDbInit
8106 * Desc : Initialise hole DB
8108 * Ret : S16 (ROK/RFAILED)
8114 **********************************************************/
8116 PRIVATE S16 rgSCHUtlUlHoleDbInit
8119 RgSchUlHoleDb *holeDb,
8125 PRIVATE S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num)
8127 RgSchUlHoleDb *holeDb;
8134 RgSchUlHole *hole = NULLP;
8136 ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
8142 holeDb->first = hole;
8143 hole->start = start;
8145 hole->prv = hole->nxt = NULLP;
8149 /***********************************************************
8151 * Func : rgSCHUtlUlHoleDbDeinit
8153 * Desc : Deinitialises hole DB
8161 **********************************************************/
8163 PRIVATE Void rgSCHUtlUlHoleDbDeinit
8166 RgSchUlHoleDb *holeDb
8169 PRIVATE Void rgSCHUtlUlHoleDbDeinit(cell, holeDb)
8171 RgSchUlHoleDb *holeDb;
8174 rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
8176 holeDb->first = NULLP;
8181 /***********************************************************
8183 * Func : rgSCHUtlUlAllocGetHole
8185 * Desc : Get allocation from hole
8187 * Ret : RgSchUlAlloc *
8193 **********************************************************/
8195 RgSchUlAlloc *rgSCHUtlUlAllocGetHole
8202 RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole)
8208 if (numSb < hole->num)
8210 return (rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
8214 return (rgSCHUtlUlAllocGetCompHole(sf, hole));
8219 /***********************************************************
8221 * Func : rgSCHUtlUlAllocGetCompHole
8223 * Desc : Get an allocation corresponding to an entire hole
8225 * Ret : RgSchUlAlloc *
8231 **********************************************************/
8233 RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole
8239 RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole)
8244 RgSchUlAlloc *alloc;
8245 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8246 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8247 * updated, causing another check for prv */
8248 RgSchUlAlloc *prv = hole->prvAlloc;
8249 RgSchUlAlloc *nxt = hole->nxtAlloc;
8253 if (hole->start == prv->nxtHole->start)
8255 prv->nxtHole = NULLP;
8257 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8261 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8264 RGSCH_NULL_CHECK( 0, alloc);
8265 alloc->prvHole = NULLP;
8266 alloc->nxtHole = NULLP;
8268 alloc->sbStart = hole->start;
8269 alloc->numSb = hole->num;
8273 nxt->prvHole = NULLP;
8276 rgSCHUtlUlHoleRls(sf->holeDb, hole);
8278 /* UL_ALLOC_CHANGES*/
8279 alloc->allocDbRef = (void*)sf->allocDb;
8280 alloc->holeDbRef = (void*)sf->holeDb;
8284 /***********************************************************
8286 * Func : rgSCHUtlUlAllocGetPartHole
8288 * Desc : Get an allocation corresponding to a part of a hole.
8289 * The initial 'numSb' part of the hole shall be taken
8290 * away for this alloc.
8292 * Ret : RgSchUlAlloc *
8298 **********************************************************/
8300 RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole
8307 RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)
8313 RgSchUlAlloc *alloc;
8314 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8315 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8316 * updated, causing another check for prv */
8317 RgSchUlAlloc *prv = hole->prvAlloc;
8321 if (hole->start == prv->nxtHole->start)
8323 prv->nxtHole = NULLP;
8325 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8329 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8332 RGSCH_NULL_CHECK( 0, alloc);
8333 alloc->prvHole = NULLP;
8334 alloc->nxtHole = hole;
8335 hole->prvAlloc = alloc;
8337 alloc->sbStart = hole->start;
8338 alloc->numSb = numSb;
8339 hole->start += numSb;
8342 rgSCHUtlUlHoleDecr(sf->holeDb, hole);
8344 /* UL_ALLOC_CHANGES*/
8345 alloc->allocDbRef = (void*)sf->allocDb;
8346 alloc->holeDbRef = (void*)sf->holeDb;
8351 /***********************************************************
8353 * Func : rgSCHUtlUlAllocFirst
8355 * Desc : Get first alloc in slot
8357 * Ret : RgSchUlAlloc *
8363 **********************************************************/
8365 RgSchUlAlloc *rgSCHUtlUlAllocFirst
8370 RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf)
8374 return (sf->allocDb->first);
8377 /***********************************************************
8379 * Func : rgSCHUtlUlAllocNxt
8381 * Desc : Get next alloc
8383 * Ret : RgSchUlAlloc *
8389 **********************************************************/
8391 RgSchUlAlloc *rgSCHUtlUlAllocNxt
8397 RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc)
8399 RgSchUlAlloc *alloc;
8403 return (alloc->nxt);
8406 /***********************************************************
8408 * Func : rgSCHUtlUlAllocGetAdjNxt
8410 * Desc : Get alloc which is immediately after the passed one.
8411 * 1. Gets alloc from mem.
8412 * 2. Inserts alloc into list (between prv and
8413 * prv->nxt, prv is not NULLP).
8414 * 3. Increments alloc count.
8415 * Note 1: Holes are not dealt with here.
8416 * Note 2: Assumes prv to be NULL.
8418 * Ret : RgSchUlAlloc *
8424 **********************************************************/
8426 RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt
8432 RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv)
8437 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8438 RgSchUlAlloc *nxt = prv->nxt;
8440 #if (ERRCLASS & ERRCLS_DEBUG)
8441 if ( alloc == NULLP )
8459 /***********************************************************
8461 * Func : rgSCHUtlUlAllocGetFirst
8463 * Desc : Get alloc which is to be the first one in the alloc list
8464 * 1. Gets alloc from mem.
8465 * 2. Inserts alloc as first element into list.
8466 * 3. Increments alloc count.
8467 * Note 1: Holes are not dealt with here.
8468 * Note 2: prv to necessarily NULLP.
8470 * Ret : RgSchUlAlloc *
8476 **********************************************************/
8478 RgSchUlAlloc *rgSCHUtlUlAllocGetFirst
8483 RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db)
8487 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8488 RgSchUlAlloc *nxt = db->first;
8490 #if (ERRCLASS & ERRCLS_DEBUG)
8491 if ( alloc == NULLP )
8510 /* UL_ALLOC_ENHANCEMENT */
8511 /***********************************************************
8513 * Func : rgSCHUtlUlHoleAddAllocation
8515 * Desc : On freeing an alloc, add to hole
8523 **********************************************************/
8525 Void rgSCHUtlUlHoleAddAllocation
8530 Void rgSCHUtlUlHoleAddAllocation(alloc)
8531 RgSchUlAlloc *alloc;
8534 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8535 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8536 * The excessive branching is meant to utilise the knowledge of whether prv
8537 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8538 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8539 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8540 RgSchUlHoleDb *db = alloc->holeDbRef;
8541 RgSchUlHole *prv = alloc->prvHole;
8542 RgSchUlHole *nxt = alloc->nxtHole;
8548 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8551 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8557 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8560 rgSCHUtlUlHoleNew(db, alloc);
8566 /***********************************************************
8568 * Func : rgSCHUtlUlAllocRelease
8570 * Desc : Releases an uplink allocation, only take alloc ptr
8578 **********************************************************/
8580 Void rgSCHUtlUlAllocRelease
8585 Void rgSCHUtlUlAllocRelease(alloc)
8586 RgSchUlAlloc *alloc;
8589 RgSchUlAllocDb *allocDb = alloc->allocDbRef;
8590 RgSchUlAlloc *prv = alloc->prv;
8591 RgSchUlAlloc *nxt = alloc->nxt;
8594 alloc->raCb = NULLP;
8595 alloc->isAdaptive = FALSE;
8600 if (nxt) /* general case: this allocation lies btw two */
8607 allocDb->first = nxt;
8614 rgSCHUtlUlHoleAddAllocation(alloc);
8615 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8621 /***********************************************************
8623 * Func : rgSCHUtlUlAllocRls
8625 * Desc : Releases an uplink allocation
8633 **********************************************************/
8635 Void rgSCHUtlUlAllocRls
8641 Void rgSCHUtlUlAllocRls(sf, alloc)
8643 RgSchUlAlloc *alloc;
8646 RgSchUlAllocDb *allocDb = sf->allocDb;
8647 RgSchUlAlloc *prv = alloc->prv;
8648 RgSchUlAlloc *nxt = alloc->nxt;
8651 alloc->raCb = NULLP;
8652 alloc->isAdaptive = FALSE;
8659 if (nxt) /* general case: this allocation lies btw two */
8666 allocDb->first = nxt;
8673 rgSCHUtlUlHoleAddAlloc(sf, alloc);
8674 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8679 printf("\nError: allocDb->count is ZERO ====\n");
8682 //printf("\nallocDb->count:%u\n",allocDb->count);
8687 /***********************************************************
8689 * Func : rgSCHUtlUlHoleFirst
8691 * Desc : Get first (largest) hole
8693 * Ret : RgSchUlHole *
8699 **********************************************************/
8701 RgSchUlHole *rgSCHUtlUlHoleFirst
8706 RgSchUlHole *rgSCHUtlUlHoleFirst(sf)
8710 return (sf->holeDb->first);
8713 /***********************************************************
8715 * Func : rgSCHUtlUlHoleNxt
8717 * Desc : Get next largest hole
8719 * Ret : RgSchUlHole *
8725 **********************************************************/
8727 RgSchUlHole *rgSCHUtlUlHoleNxt
8733 RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole)
8742 /***********************************************************
8744 * Func : rgSCHUtlUlHoleAddAlloc
8746 * Desc : On freeing an alloc, add to hole
8754 **********************************************************/
8756 Void rgSCHUtlUlHoleAddAlloc
8762 Void rgSCHUtlUlHoleAddAlloc(sf, alloc)
8764 RgSchUlAlloc *alloc;
8767 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8768 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8769 * The excessive branching is meant to utilise the knowledge of whether prv
8770 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8771 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8772 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8773 RgSchUlHoleDb *db = sf->holeDb;
8774 RgSchUlHole *prv = alloc->prvHole;
8775 RgSchUlHole *nxt = alloc->nxtHole;
8781 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8784 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8790 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8793 rgSCHUtlUlHoleNew(db, alloc);
8796 /* increment the number of subbands getting freed to total available list */
8797 sf->availSubbands += alloc->numSb;
8802 /***********************************************************
8804 * Func : rgSCHUtlUlHoleJoin
8806 * Desc : Join two holes (due to alloc being deleted)
8814 **********************************************************/
8816 Void rgSCHUtlUlHoleJoin
8824 Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc)
8828 RgSchUlAlloc *alloc;
8831 prv->num += alloc->numSb + nxt->num;
8832 rgSCHUtlUlHoleRls(db, nxt);
8833 rgSCHUtlUlHoleIncr(db, prv);
8834 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
8839 /***********************************************************
8841 * Func : rgSCHUtlUlHoleExtndRight
8843 * Desc : Extend hole due to alloc coming 'after' the hole
8852 **********************************************************/
8854 Void rgSCHUtlUlHoleExtndRight
8861 Void rgSCHUtlUlHoleExtndRight(db, prv, alloc)
8864 RgSchUlAlloc *alloc;
8867 prv->num += alloc->numSb;
8868 rgSCHUtlUlHoleIncr(db, prv);
8869 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
8873 /***********************************************************
8875 * Func : rgSCHUtlUlHoleExtndLeft
8877 * Desc : Extend hole due to alloc coming 'before' the hole
8886 **********************************************************/
8888 Void rgSCHUtlUlHoleExtndLeft
8895 Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc)
8898 RgSchUlAlloc *alloc;
8901 nxt->num += alloc->numSb;
8902 nxt->start = alloc->sbStart;
8903 rgSCHUtlUlHoleIncr(db, nxt);
8904 rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
8908 /***********************************************************
8910 * Func : rgSCHUtlUlHoleNew
8912 * Desc : Create new hole due to alloc being deleted
8920 **********************************************************/
8922 Void rgSCHUtlUlHoleNew
8928 Void rgSCHUtlUlHoleNew(db, alloc)
8930 RgSchUlAlloc *alloc;
8933 RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
8934 #if (ERRCLASS & ERRCLS_DEBUG)
8935 if ( hole == NULLP )
8940 hole->start = alloc->sbStart;
8941 hole->num = alloc->numSb;
8943 rgSCHUtlUlHoleIns(db, hole);
8944 rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
8948 /***********************************************************
8950 * Func : rgSCHUtlUlHoleUpdAllocLnks
8952 * Desc : Update alloc links in hole
8960 **********************************************************/
8962 Void rgSCHUtlUlHoleUpdAllocLnks
8965 RgSchUlAlloc *prvAlloc,
8966 RgSchUlAlloc *nxtAlloc
8969 Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc)
8971 RgSchUlAlloc *prvAlloc;
8972 RgSchUlAlloc *nxtAlloc;
8977 prvAlloc->nxtHole = hole;
8981 nxtAlloc->prvHole = hole;
8983 hole->prvAlloc = prvAlloc;
8984 hole->nxtAlloc = nxtAlloc;
8989 /***********************************************************
8991 * Func : rgSCHUtlUlHoleIns
8993 * Desc : Insert (newly created) hole in sorted list of holes.
8994 * Searches linearly, beginning with the largest hole.
9002 **********************************************************/
9004 Void rgSCHUtlUlHoleIns
9010 Void rgSCHUtlUlHoleIns(db, hole)
9017 if ((cur = db->first) != NULLP)
9020 if (cur->num < hole->num)
9030 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9032 if (nxt->num < hole->num)
9034 /* Insert hole: cur <-> hole <-> nxt */
9050 /* This is the first hole */
9052 hole->prv = NULLP; /* may not be needed */
9058 /***********************************************************
9060 * Func : rgSCHUtlUlHoleIncr
9062 * Desc : hole->num has increeased, reposition in sorted
9071 **********************************************************/
9073 Void rgSCHUtlUlHoleIncr
9079 Void rgSCHUtlUlHoleIncr(db, hole)
9086 if ((cur = hole->prv) != NULLP)
9090 if (cur->num > hole->num)
9095 /* Remove hole from current position */
9096 cur->nxt = hole->nxt;
9099 hole->nxt->prv = cur;
9102 for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
9104 if (prv->num > hole->num)
9106 /* Insert hole: prv <-> hole <-> cur */
9125 /***********************************************************
9127 * Func : rgSCHUtlUlHoleDecr
9129 * Desc : hole->num has decreeased, reposition in sorted
9138 **********************************************************/
9140 Void rgSCHUtlUlHoleDecr
9146 Void rgSCHUtlUlHoleDecr(db, hole)
9153 if ((cur = hole->nxt) != NULLP)
9157 if (cur->num < hole->num)
9162 /* Remove hole from current position */
9163 cur->prv = hole->prv;
9166 hole->prv->nxt = cur;
9168 else /* no prv, so cur to replace hole as first in list */
9173 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9175 if (nxt->num < hole->num)
9177 /* Insert hole: cur <-> hole <-> nxt */
9195 /***********************************************************
9197 * Func : rgSCHUtlUlHoleRls
9199 * Desc : Releases hole.
9200 * 1. Decrements hole count.
9201 * 2. Deletes hole from list.
9202 * 3. Frees hole (hole memory release).
9210 **********************************************************/
9212 Void rgSCHUtlUlHoleRls
9218 Void rgSCHUtlUlHoleRls(db, hole)
9223 RgSchUlHole *prv = hole->prv;
9224 RgSchUlHole *nxt = hole->nxt;
9244 rgSCHUtlUlHoleMemRls(&db->mem, hole);
9249 /***********************************************************
9251 * Func : rgSCHUtlUlAllocMemInit
9253 * Desc : Initialises alloc free pool
9255 * Ret : S16 (ROK/RFAILED)
9261 **********************************************************/
9263 S16 rgSCHUtlUlAllocMemInit
9266 RgSchUlAllocMem *mem,
9270 S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs)
9272 RgSchUlAllocMem *mem;
9277 RgSchUlAlloc *allocs;
9279 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
9280 maxAllocs * sizeof(*allocs));
9285 mem->allocs = allocs;
9286 mem->maxAllocs = maxAllocs;
9287 if (mem->maxAllocs == 1)
9289 allocs[0].prv = NULLP;
9290 allocs[0].nxt = NULLP;
9295 allocs[0].prv = NULLP;
9296 allocs[0].nxt = &allocs[1];
9297 for (i = 1; i < mem->maxAllocs - 1; ++i)
9299 allocs[i].prv = &allocs[i-1];
9300 allocs[i].nxt = &allocs[i+1];
9302 allocs[i].prv = &allocs[i-1];
9303 allocs[i].nxt = NULLP;
9305 mem->firstFree = &allocs[0];
9309 /***********************************************************
9311 * Func : rgSCHUtlUlAllocMemDeinit
9313 * Desc : Deinitialises alloc free pool
9321 **********************************************************/
9323 Void rgSCHUtlUlAllocMemDeinit
9326 RgSchUlAllocMem *mem
9329 Void rgSCHUtlUlAllocMemDeinit(cell, mem)
9331 RgSchUlAllocMem *mem;
9334 /* ccpu00117052 - MOD - Passing double pointer
9335 for proper NULLP assignment*/
9336 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
9337 mem->maxAllocs * sizeof(*mem->allocs));
9339 mem->firstFree = NULLP;
9343 /***********************************************************
9345 * Func : rgSCHUtlUlHoleMemInit
9347 * Desc : Initialises hole free pool. Assumes maxHoles
9350 * Ret : S16 (ROK/RFAILED)
9356 **********************************************************/
9358 S16 rgSCHUtlUlHoleMemInit
9361 RgSchUlHoleMem *mem,
9363 RgSchUlHole **holeRef
9366 S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef)
9368 RgSchUlHoleMem *mem;
9370 RgSchUlHole **holeRef;
9376 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
9377 maxHoles * sizeof(*holes));
9384 mem->maxHoles = maxHoles;
9386 /* first hole is taken up */
9387 holes[0].prv = NULLP; /* not needed */
9388 holes[0].nxt = NULLP; /* not needed */
9389 *holeRef = &holes[0];
9391 if (mem->maxHoles == 2)
9393 holes[1].prv = NULLP; /* may not be needed */
9394 holes[1].nxt = NULLP; /* may not be needed */
9399 holes[1].prv = NULLP;
9400 holes[0].nxt = &holes[1];
9401 for (i = 1; i < mem->maxHoles - 1; ++i)
9403 holes[i].prv = &holes[i-1];
9404 holes[i].nxt = &holes[i+1];
9406 holes[i].prv = &holes[i-1];
9407 holes[i].nxt = NULLP;
9409 mem->firstFree = &holes[1];
9414 /***********************************************************
9416 * Func : rgSCHUtlUlHoleMemDeinit
9418 * Desc : Deinitialises hole free pool
9426 **********************************************************/
9428 Void rgSCHUtlUlHoleMemDeinit
9434 Void rgSCHUtlUlHoleMemDeinit(cell, mem)
9436 RgSchUlHoleMem *mem;
9439 /* ccpu00117052 - MOD - Passing double pointer
9440 for proper NULLP assignment*/
9441 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
9442 mem->maxHoles * sizeof(*mem->holes));
9444 mem->firstFree = NULLP;
9448 /***********************************************************
9450 * Func : rgSCHUtlUlAllocMemGet
9452 * Desc : Gets an 'alloc' from the free pool
9454 * Ret : RgSchUlAlloc *
9460 **********************************************************/
9462 RgSchUlAlloc *rgSCHUtlUlAllocMemGet
9464 RgSchUlAllocMem *mem
9467 RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem)
9468 RgSchUlAllocMem *mem;
9471 RgSchUlAlloc *alloc;
9473 #if (ERRCLASS & ERRCLS_DEBUG)
9474 if (mem->firstFree == NULLP)
9480 alloc = mem->firstFree;
9481 mem->firstFree = alloc->nxt;
9482 alloc->nxt = NULLP; /* probably not needed */
9483 /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
9488 /***********************************************************
9490 * Func : rgSCHUtlUlAllocMemRls
9492 * Desc : Returns an 'alloc' to the free pool
9500 **********************************************************/
9502 Void rgSCHUtlUlAllocMemRls
9504 RgSchUlAllocMem *mem,
9508 Void rgSCHUtlUlAllocMemRls(mem, alloc)
9509 RgSchUlAllocMem *mem;
9510 RgSchUlAlloc *alloc;
9515 alloc->nxt = mem->firstFree;
9516 if (mem->firstFree != NULLP)
9518 mem->firstFree->prv = alloc;
9520 mem->firstFree = alloc;
9524 /***********************************************************
9526 * Func : rgSCHUtlUlHoleMemGet
9528 * Desc : Gets a 'hole' from the free pool
9530 * Ret : RgSchUlHole *
9536 **********************************************************/
9538 RgSchUlHole *rgSCHUtlUlHoleMemGet
9543 RgSchUlHole *rgSCHUtlUlHoleMemGet(mem)
9544 RgSchUlHoleMem *mem;
9549 #if (ERRCLASS & ERRCLS_DEBUG)
9550 if (mem->firstFree == NULLP)
9556 hole = mem->firstFree;
9557 mem->firstFree = hole->nxt;
9558 mem->firstFree->prv = NULLP; /* may not be needed, under error class */
9559 hole->nxt = NULLP; /* probably not needed */
9560 /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
9565 /***********************************************************
9567 * Func : rgSCHUtlUlHoleMemRls
9569 * Desc : Returns a 'hole' to the free pool
9577 **********************************************************/
9579 Void rgSCHUtlUlHoleMemRls
9581 RgSchUlHoleMem *mem,
9585 Void rgSCHUtlUlHoleMemRls(mem, hole)
9586 RgSchUlHoleMem *mem;
9592 hole->nxt = mem->firstFree;
9593 if (mem->firstFree != NULLP)
9595 mem->firstFree->prv = hole;
9597 mem->firstFree = hole;
9602 * @brief Get an alloc from the specified position in the BW.
9606 * Function : rgSCHUtlUlGetSpfcAlloc
9608 * - Return an alloc from the specified position in the BW.
9609 * Note: This function assumes there is always a hole
9610 * Existing which completely has the specified
9611 * allocation. The reason for such an assumption is
9612 * the function's usage as of now guarantees that there
9613 * will always be such hole. And also for efficiency.
9615 * @param[in] RgSchUlSf *sf
9616 * @param[in] U8 startSb
9617 * @param[in] U8 numSb
9618 * @return RgSchUlAlloc*
9621 RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc
9628 RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb)
9634 RgSchUlHole *hole, *nxtHole;
9635 RgSchUlAlloc *alloc = NULLP;
9637 if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
9643 nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
9644 if ((startSb >= hole->start) &&
9645 (startSb+numSb <= hole->start+hole->num))
9647 if (startSb != hole->start)
9649 /* Create a new hole to accomodate Subbands between
9650 * hole start and req alloc start */
9651 RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
9653 #if (ERRCLASS & ERRCLS_DEBUG)
9654 if ( newHole == NULLP )
9659 newHole->start = hole->start;
9660 newHole->num = startSb - hole->start;
9661 hole->start = startSb;
9662 /* [ccpu00122847]-MOD- Correctly updating the hole->num */
9663 hole->num -= newHole->num;
9664 ++(sf->holeDb->count);
9665 rgSCHUtlUlHoleIns(sf->holeDb, newHole);
9666 newHole->prvAlloc = hole->prvAlloc;
9667 if (newHole->prvAlloc)
9669 newHole->prvAlloc->nxtHole = newHole;
9671 if (numSb == hole->num)
9673 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9677 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9679 alloc->prvHole = newHole;
9680 newHole->nxtAlloc = alloc;
9682 else /* Hole start and req alloc start are same */
9684 if (numSb == hole->num)
9686 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9690 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9695 } while ((hole = nxtHole) != NULLP);
9700 * @brief Validates the qci values
9704 * Function :rgSCHUtlValidateQci
9706 * @param[in] RgSchCellCb *cellCb
9707 * @param[in] U8 numQci
9708 * @param[out] U8 *qci
9714 PRIVATE S16 rgSCHUtlValidateQci
9716 RgSchCellCb *cellCb,
9721 PRIVATE S16 rgSCHUtlValidateQci(cellCb, numQci, qci)
9722 RgSchCellCb *cellCb;
9731 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
9733 qciVal = qci[qciIdx];
9734 if(qciVal == 0 || qciVal > 9)
9738 if(qciVal != cellCb->qciArray[qciVal].qci)
9745 }/* rgSCHUtlValidateQci */
9747 * @brief Validates the measurement request parameters.
9751 * Function :rgSCHUtlValidateMeasReq
9753 * @param[in] RgSchCellCb *cellCb
9754 * @param[in] LrgSchMeasReqInfo *schL2MeasInfo
9755 * @param[out] RgSchErrInfo *err
9756 * @return RgSchUlAlloc*
9759 S16 rgSCHUtlValidateMeasReq
9761 RgSchCellCb *cellCb,
9762 LrgSchMeasReqInfo *schL2MeasInfo,
9766 S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err)
9767 RgSchCellCb *cellCb;
9768 LrgSchMeasReqInfo *schL2MeasInfo;
9776 measType = schL2MeasInfo->measType;
9778 if((measType == 0) ||
9781 err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
9782 err->errCause = RGSCHERR_SCH_L2MEAS;
9785 if((schL2MeasInfo->timePrd !=0) &&
9786 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
9787 ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
9788 (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
9790 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9791 err->errCause = RGSCHERR_SCH_L2MEAS;
9794 if((schL2MeasInfo->timePrd !=0) &&
9795 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
9796 (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ))
9798 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9799 err->errCause = RGSCHERR_SCH_L2MEAS;
9802 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
9803 ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
9804 (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
9805 ((schL2MeasInfo->timePrd !=0)&&
9806 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
9807 (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
9809 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9810 err->errCause = RGSCHERR_SCH_L2MEAS;
9813 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
9814 ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
9815 (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
9816 ((schL2MeasInfo->timePrd !=0) &&
9817 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
9818 (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
9820 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9821 err->errCause = RGSCHERR_SCH_L2MEAS;
9824 if((schL2MeasInfo->timePrd !=0) &&
9825 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
9827 RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \
9828 (schL2MeasInfo->avgPrbQciDl.numQci));
9829 ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
9830 schL2MeasInfo->avgPrbQciDl.qci);
9833 err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
9834 err->errCause = RGSCHERR_SCH_L2MEAS;
9839 }/* rgSCHUtlValidateMeasReq */
9840 #endif /* LTE_L2_MEAS */
9841 /******* </AllocHolesMemMgmnt>: END *****/
9844 * @brief API for sending SI configuration confirm from Scheduler to RRM
9848 * Function: rgSCHUtlRgrSiCfgCfm
9850 * This API is invoked to send SI configuration confirm from Scheduler
9852 * This API fills in Pst structure and SAP Ids and invokes
9853 * config confirm API towards RRM.
9855 * @param[in] RgrCfgTransId transId
9856 * @param[in] U8 status
9862 S16 rgSCHUtlRgrSiCfgCfm
9866 RgrCfgTransId transId,
9870 S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status)
9873 RgrCfgTransId transId;
9877 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
9880 memcpy(prntTrans, transId.trans, RGR_CFG_TRANSID_SIZE);
9881 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
9884 if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
9885 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
9886 transId, status) != ROK)
9888 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
9889 "RgUiRgrSiCfgCfm Failed ");
9894 } /* rgSCHUtlRgrSiCfgCfm */
9898 * @brief API for sending Warning SI configuration confirm from
9904 * This API is invoked to send Warning SI configuration confirm
9905 * from Scheduler to RRM.
9906 * This API fills in Pst structure and SAP Ids and invokes
9907 * config confirm API towards RRM.
9909 * @param[in] RgrCfgTransId transId
9910 * @param[in] U8 status
9916 S16 rgSCHUtlRgrWarningSiCfgCfm
9921 RgrCfgTransId transId,
9925 S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status)
9929 RgrCfgTransId transId;
9933 U8 prntTrans[RGR_CFG_TRANSID_SIZE+1];
9936 memcpy(prntTrans, transId.trans, RGR_CFG_TRANSID_SIZE);
9937 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
9940 if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
9941 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
9942 transId, siId, status) != ROK)
9944 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
9945 "RgUiRgrSiCfgCfm Failed ");
9950 } /* rgSCHUtlRgrWarningSiCfgCfm */
9952 /***********************************************************
9954 * Func : rgSCHUtlPutSiInfo
9956 * Desc : Utility Function to deallocate SI information
9964 **********************************************************/
9966 Void rgSCHUtlPutSiInfo
9971 Void rgSCHUtlPutSiInfo(cell)
9976 U32 sizeOfSiInfo = 0;
9977 /*Free the buffers in crntSiInfo*/
9978 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
9979 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
9981 sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
9983 for(idx=0; idx < sizeOfSiInfo; idx++)
9985 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
9988 /*Free the buffers in newSiInfo */
9989 RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
9990 RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
9992 sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
9994 for(idx=0; idx < sizeOfSiInfo; idx++)
9996 RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
10001 #endif /*RGR_SI_SCH */
10005 /***********************************************************
10007 * Func : rgSCHUtlGetDrxSchdUesInDl
10009 * Desc : Utility Function to fill the get the list of
10010 * scheduled UEs. On these UE's, drx-inactivity
10011 * timer will be started/restarted.
10020 **********************************************************/
10022 S16 rgSCHUtlGetDrxSchdUesInDl
10024 RgSchCellCb *cellCb,
10026 RgSchDlHqProcCb *dlHq,
10027 RgInfUeAlloc *allocInfo,
10028 CmLListCp *dlDrxInactvTmrLst,
10029 CmLListCp *dlInActvLst,
10030 CmLListCp *ulInActvLst
10033 S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
10034 RgSchCellCb *cellCb;
10036 RgSchDlHqProcCb *dlHq;
10037 RgInfUeAlloc *allocInfo;
10038 CmLListCp *dlDrxInactvTmrLst;
10039 CmLListCp *dlInActvLst;
10040 CmLListCp *ulInActvLst;
10043 Bool isNewTx = FALSE;
10045 RgSchDrxDlHqProcCb *drxHq;
10046 RgSchDRXCellCb *drxCell = cellCb->drxCb;
10047 RgSchDrxUeCb *drxUe;
10049 Inst inst = cellCb->instIdx;
10051 U8 cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
10055 for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
10057 if(allocInfo->tbInfo[idx].isReTx == FALSE)
10060 /* Removing break here, since in 2 TB case if 2nd TB is proceeding with
10061 retx then drxretx timer should be stopped.*/
10065 /*Stop the DRX retransmission timer as UE scheduled for retx. Here
10066 * we stop the timer and inactivate the UE for both UL and DL.
10067 * This may result in loss of one slot for UL but this trade
10068 * off is taken to avoid the overhead of maintaining a list of UEs
10069 * to be inactivated in the next slot.*/
10070 drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
10071 drxUe = RG_SCH_DRX_GET_UE(ueCb);
10072 if(drxHq->reTxIndx != DRX_INVALID)
10074 /* This condition should never occur */
10075 if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
10077 RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]"
10078 "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
10079 drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId));
10082 drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10083 drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10085 dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10086 ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10088 for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
10090 dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
10091 ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
10094 drxUe->drxDlInactvMask |= dlInactvMask;
10095 drxUe->drxUlInactvMask |= ulInactvMask;
10097 /* if no other condition is keeping ue active,
10098 * inactivate the Ue
10100 if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
10102 /* BUG 2 : HARQ_RTT, changed for consistency */
10103 ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
10105 /* Add to DL inactive list */
10106 cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
10107 ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
10110 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
10112 /*BUG 2: HARQ_RTT changed for consistency */
10113 ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
10115 cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
10116 ueCb->ulDrxInactvLnk.node = (PTR)ueCb;
10119 /* Deleting entry from HARQ RTT queue for the same HARQ proc,
10120 * if exist. This is the special case which can happen iF UL
10121 * scheduling is done later. */
10122 if(drxHq->rttIndx != DRX_INVALID)
10124 cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
10125 &(drxHq->harqRTTEnt));
10127 drxHq->rttIndx = DRX_INVALID;
10130 cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
10131 &(drxHq->harqRetxEnt));
10132 drxHq->reTxIndx = DRX_INVALID;
10137 if(isNewTx == TRUE)
10139 if(ueCb->drxCb->raRcvd == TRUE)
10141 ueCb->drxCb->raRcvd = FALSE;
10143 /* mark the ra bit */
10144 ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10145 ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10147 }/*if(ra->rcvd) == TRUE */
10149 if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
10151 cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
10152 ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
10154 }/*if(isNewTx == TRUE) */
10157 }/* rgSCHUtlGetSchdUes*/
10159 /* ccpu00117452 - MOD - Changed macro name from
10160 RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
10161 #ifdef RGR_CQI_REPT
10163 * @brief This function fills StaInd struct
10167 * Function: rgSCHUtlFillSndStaInd
10168 * Purpose: Fills StaInd struct and sends the
10171 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10172 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10173 * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled
10174 * @param[in] U8 numCqiRept NUmber of reports to be filled
10179 S16 rgSCHUtlFillSndStaInd
10183 RgrStaIndInfo *staInfo,
10187 S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept)
10190 RgrStaIndInfo *staInfo;
10196 /* Fill StaInd for sending collated Latest N CQI rpeorts */
10197 /* Find index in the array from where Latest N
10198 reports needs to be fetched. Use this value to index in the array
10199 and copy the reports into staInfo */
10201 /* Fill the Cell Id of PCC of the UE */
10202 staInfo->cellId = ue->cell->cellId;
10203 staInfo->crnti = ue->ueId;
10205 idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
10207 memcpy (&(staInfo->ueCqiInfo.cqiRept),
10208 &(ue->schCqiInfo.cqiRept[idxStart]),
10209 numCqiRept * sizeof(RgrUeCqiRept));
10211 staInfo->ueCqiInfo.numCqiRept = numCqiRept;
10213 ue->schCqiInfo.cqiCount = 0;
10215 /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
10216 if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
10218 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10219 "CQI reports for RNTI:%d",ue->ueId);
10225 }/* End of rgSCHUtlFillSndStaInd */
10230 * @brief API for sending STA indication from Scheduler to RRM.
10234 * Function: rgSCHUtlRgrStaInd
10236 * This API is invoked to send STA indication from Scheduler instance to RRM.
10237 * This API fills in Pst structure and RgrStaIndInfo
10238 * and calls the Sta primitive API towards RRM.
10240 * @param[in] cell RgSchCellCb
10241 * @param[in] RgrStsIndInfo *rgrSta
10247 S16 rgSCHUtlRgrStaInd
10250 RgrStaIndInfo *rgrSta
10253 S16 rgSCHUtlRgrStaInd(cell, rgrSta)
10255 RgrStaIndInfo *rgrSta;
10259 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10263 rgrSap = cell->rgrSap;
10264 if (rgrSap->sapSta.sapState != LRG_BND)
10266 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10267 "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
10268 rgrSap->sapSta.sapState);
10271 RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
10272 cell->rgrSap->sapCfg.suId, rgrSta);
10274 } /* rgSCHUtlRgrStaInd*/
10275 #endif /* End of RGR_CQI_REPT */
10277 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
10279 * @brief Indicates MAC to release any rnti context it has.
10282 * Function : rgSCHUtlIndRntiRls2Mac
10283 * This function indicates MAC for this rnti release.
10284 * In case of ueId change it will indicate MAC
10285 * about the new rnti to be updated.
10286 * It will post a release RNTI indication to MAC.
10290 * @param[in] RgSchCellCb *cell
10291 * @param[in] CmLteRnti rnti
10292 * @param[in] Bool ueIdChng
10293 * @param[in] CmLteRnti newRnti
10298 Void rgSCHUtlIndRntiRls2Mac
10306 Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti)
10314 Inst inst = cell->instIdx;
10315 RgInfRlsRnti rntiInfo;
10318 /* Copy the info to rntiInfo */
10319 rntiInfo.cellId = cell->cellId;
10320 rntiInfo.rnti = rnti;
10321 /* Fix : syed ueId change as part of reestablishment.
10322 * Now SCH to trigger this. CRG ueRecfg for ueId change
10324 rntiInfo.ueIdChng = ueIdChng;
10325 rntiInfo.newRnti = newRnti;
10327 rntiInfo.isUeSCellDel = FALSE;
10329 /* Invoke MAC to release the rnti */
10330 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
10331 RgSchMacRlsRnti(&pst, &rntiInfo);
10335 /* LTE_ADV_FLAG_REMOVED_START */
10337 * @brief API for sending LOAD INF indication from Scheduler to RRM.
10340 * Function: rgSCHUtlRgrLoadInfInd
10342 * This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
10343 * This API fills in Pst structure and RgrLoadInfIndInfo
10344 * and calls the Sta primitive API towards RRM.
10346 * @param[in] cell RgSchCellCb
10347 * @param[in] RgrLoadInfIndInfo *rgrLoadInf
10353 S16 rgSCHUtlRgrLoadInfInd
10356 RgrLoadInfIndInfo *rgrLoadInf
10359 S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf)
10361 RgrLoadInfIndInfo *rgrLoadInf;
10365 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10367 rgrSap = cell->rgrSap;
10368 if (rgrSap->sapSta.sapState != LRG_BND)
10370 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10371 "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
10372 rgrSap->sapSta.sapState);
10375 RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
10376 cell->rgrSap->sapCfg.suId, rgrLoadInf);
10378 } /* rgSCHUtlRgrLoadInfInd*/
10379 /* LTE_ADV_FLAG_REMOVED_END */
10381 /* MS_FIX : syed SCH to act as MASTER in maintaining
10382 * rnti related context. Trigger to rnti del/Chng at SCH
10383 * will result in a Indication to MAC to release its
10384 * RNTI context. MAC inturn indicates the context cleared
10385 * indication to SCH, upon which SCH would set this
10387 * @brief API for sending STA indication from Scheduler to RRM.
10391 * Function: rgSCHUtlRlsRnti
10393 * This API is invoked to indicate MAC to release rnti
10395 * @param[in] RgSchCellCb *cellCb
10396 * @param[in] RgSchRntiLnk *rntiLnk,
10397 * @param[in] Bool ueIdChngd,
10398 * @param[in] CmLteRnti newRnti
10403 Void rgSCHUtlRlsRnti
10406 RgSchRntiLnk *rntiLnk,
10411 Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti)
10413 RgSchRntiLnk *rntiLnk;
10421 if(cell->emtcEnable)
10423 rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
10428 /*Add to Guard Pool*/
10429 cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
10430 rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
10432 /* Fix: syed Explicitly Inidcate MAC to release RNTI */
10433 rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
10440 * @brief This function fills StaInd struct
10444 * Function: rgSCHUtlFillSndUeStaInd
10445 * Purpose: Fills StaInd struct and sends the
10448 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10449 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10450 * @param[in] U8 numCqiRept NUmber of reports to be filled
10455 S16 rgSCHUtlFillSndUeStaInd
10459 RgrUeStaIndInfo *ueStaInfo
10462 S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo)
10465 RgrUeStaIndInfo *ueStaInfo;
10469 ueStaInfo->cellId = cell->cellId;
10470 ueStaInfo->crnti = ue->ueId;
10472 /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
10473 if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
10475 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10476 "UE Sta reports CRNTI:%d",ue->ueId);
10482 }/* End of rgSCHUtlFillSndStaInd */
10487 * @brief API for sending STA indication from Scheduler to RRM.
10491 * Function: rgSCHUtlRgrStaInd
10493 * This API is invoked to send STA indication from Scheduler instance to RRM.
10494 * This API fills in Pst structure and RgrStaIndInfo
10495 * and calls the Sta primitive API towards RRM.
10497 * @param[in] cell RgSchCellCb
10498 * @param[in] RgrStsIndInfo *rgrSta
10504 S16 rgSCHUtlRgrUeStaInd
10507 RgrUeStaIndInfo *rgrUeSta
10510 S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta)
10512 RgrUeStaIndInfo *rgrUeSta;
10516 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10518 rgrSap = cell->rgrSap;
10519 if (rgrSap->sapSta.sapState != LRG_BND)
10521 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10522 "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
10523 rgrSap->sapSta.sapState);
10526 RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
10527 cell->rgrSap->sapCfg.suId, rgrUeSta);
10529 } /* rgSCHUtlRgrStaInd*/
10533 * @brief function to report DL and UL PRB usage to RRM.
10536 * Function: rgSCHUtlUpdAvgPrbUsage
10537 * This function sends the PRB usage report to
10538 * RRM with the interval configured by RRM.
10540 * @param[in] cell *RgSchCellCb
10546 S16 rgSCHUtlUpdAvgPrbUsage
10551 S16 rgSCHUtlUpdAvgPrbUsage(cell)
10555 CmLteTimingInfo frm;
10556 RgmPrbRprtInd *prbRprtInd;
10559 #ifdef DBG_MAC_RRM_PRB_PRINT
10560 static U32 count = 0;
10561 const U32 reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
10566 frm = cell->crntTime;
10567 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
10573 if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
10575 /* Get the total number of DL and UL slots within the reporting period*/
10576 numDlSf = (cell->prbUsage.rprtPeriod *
10577 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10578 / RGSCH_NUM_SUB_FRAMES;
10579 numUlSf = (cell->prbUsage.rprtPeriod *
10580 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10581 / RGSCH_NUM_SUB_FRAMES;
10585 /* Get the total number of DL and UL slots < 10 ms interval */
10586 numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10587 numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10590 numDlSf = cell->prbUsage.rprtPeriod;
10591 numUlSf = cell->prbUsage.rprtPeriod;
10594 if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
10595 cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd,
10596 sizeof(RgmPrbRprtInd)) != ROK)
10601 memset(&prbRprtInd->stQciPrbRpts[0],
10603 (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
10605 prbRprtInd->bCellId = cell->cellId;
10609 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL;
10610 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10612 prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage =
10613 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
10614 (numDlSf * cell->bwCfg.dlTotalBw));
10615 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10616 cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
10622 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL;
10623 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10625 prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage =
10626 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
10627 (numUlSf * cell->ulAvailBw));
10628 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10629 cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
10633 #ifdef DBG_MAC_RRM_PRB_PRINT
10634 if((count % reprotForEvery20Sec) == 0 )
10636 printf("\n====================================================================");
10637 printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n");
10638 printf("======================================================================\n");
10639 printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n",
10640 prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
10641 prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
10642 prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
10643 prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
10644 prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
10645 prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
10646 prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
10647 prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
10650 RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst),
10651 cell->rgmSap->sapCfg.suId, prbRprtInd);
10659 * @brief This function resends the Ta in case of
10660 * max retx failure or DTX for the Ta transmitted
10664 * Function: rgSCHUtlReTxTa
10667 * @param[in] RgSchCellCb *cell
10668 * @param[in] RgSchUeCb *ue
10673 Void rgSCHUtlReTxTa
10675 RgSchCellCb *cellCb,
10679 Void rgSCHUtlReTxTa(cellCb, ueCb)
10680 RgSchCellCb *cellCb;
10685 /* If TA Timer is running. Stop it */
10686 if (ueCb->taTmr.tmrEvnt != TMR_NONE)
10688 rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
10690 /*[ccpu00121813]-ADD-If maxretx is reached then
10691 * use outstanding TA val for scheduling again */
10692 if(ueCb->dl.taCb.outStndngTa == TRUE)
10694 ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
10695 ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
10696 ueCb->dl.taCb.outStndngTa = FALSE;
10699 /* Fix : syed TA state updation missing */
10700 ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
10701 rgSCHUtlDlTARpt(cellCb, ueCb);
10706 /* Added function for dropping Paging Message*/
10708 * @brief Handler for BO Updt received for BCCH or PCCH.
10712 * Function : rgSCHChkBoUpdate
10714 * This function shall check for BO received falls within the scheduling window or not
10717 * @param[in] RgSchCellCb *cell
10723 PRIVATE S16 rgSCHChkBoUpdate
10726 RgInfCmnBoRpt *boUpdt
10729 PRIVATE S16 rgSCHChkBoUpdate (cell, boUpdt)
10731 RgInfCmnBoRpt *boUpdt;
10735 U32 crntTimeInSubFrms = 0;
10736 U32 boUpdTimeInSubFrms = 0;
10739 crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.slot +
10740 RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI
10741 so incrementing with +1 more */
10742 boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.slot;
10745 distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
10746 boUpdTimeInSubFrms - crntTimeInSubFrms : \
10747 (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
10749 if (distance > RGSCH_PCCHBCCH_WIN)
10755 }/*rgSCHChkBoUpdate*/
10760 * @brief Utility function to calculate the UL reTxIdx in TDD cfg0
10764 * Function : rgSchUtlCfg0ReTxIdx
10766 * Update the reTxIdx according to the rules mentioned
10767 * in 3GPP TS 36.213 section 8 for TDD Cfg0
10769 * @param[in] RgSchCellCb *cell
10770 * @param[in] CmLteTimingInfo phichTime
10771 * @param[in] U8 hqFdbkIdx
10775 U8 rgSchUtlCfg0ReTxIdx
10778 CmLteTimingInfo phichTime,
10782 U8 rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx)
10784 CmLteTimingInfo phichTime;
10788 U8 reTxIdx = RGSCH_INVALID_INFO;
10790 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
10792 U8 ulSF; /* UL SF in the TDD frame */
10794 ulSf = &cellUl->ulSfArr[hqFdbkIdx];
10795 ulSF = ulSf->ulSfIdx;
10797 /* Check for the UL SF 4 or 9 */
10798 if(ulSF == 9 || ulSF == 4)
10802 if(phichTime.slot == 0 || phichTime.slot == 5)
10806 /* Retx will happen according to the Pusch k table */
10807 reTxIdx = cellUl->schdIdx;
10811 /* Retx will happen at n+7 */
10812 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
10813 /* Fetch the corresponding UL slot Idx in UL sf array */
10814 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
10817 else if(phichTime.slot == 1 || phichTime.slot == 6)
10819 /* Retx will happen at n+7 */
10820 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
10821 /* Fetch the corresponding UL slot Idx in UL sf array */
10822 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
10829 * @brief Utility function to calculate total num of PRBs required to
10830 * satisfy DL BO for TM1/TM2/TM6/TM7
10834 * Function : rgSchUtlDlCalc1CwPrb
10836 * Calculate PRBs required for UE to satisfy BO in DL
10838 * Note : Total calculated PRBs will be assigned to *prbReqrd
10841 * @param[in] RgSchCellCb *cell
10842 * @param[in] RgSchUeCb *ue
10843 * @param[in] U32 bo
10844 * @param[out] U32 *prbReqrd
10848 Void rgSchUtlDlCalc1CwPrb
10856 Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd)
10863 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
10864 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
10868 U8 cfi = dlCell->currCfi;
10870 iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0];
10871 eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
10873 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
10874 * i.e, << 3 and multiply with 1024 i.e, << 10 */
10875 noRes = ((U64)((bo << 3) << 10)) / (eff);
10876 /* Get the number of RBs needed for this transmission */
10877 /* Number of RBs = No of REs / No of REs per RB */
10878 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
10881 } /* rgSchUtlDlCalc1CwPrb*/
10884 * @brief Utility function to calculate total num of PRBs required to
10885 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
10890 * Function : rgSchUtlDlCalc2CwPrb
10892 * Calculate PRBs required for UE to satisfy BO in DL
10894 * Note : Total calculated PRBs will be assigned to *prbReqrd
10897 * @param[in] RgSchCellCb *cell
10898 * @param[in] RgSchUeCb *ue
10899 * @param[in] U32 bo
10900 * @param[out] U32 *prbReqrd
10904 Void rgSchUtlDlCalc2CwPrb
10912 Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd)
10919 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
10920 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
10925 U8 cfi = dlCell->currCfi;
10927 if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
10928 (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
10930 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0];
10931 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
10933 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
10934 * i.e, << 3 and multiply with 1024 i.e, << 10 */
10935 noRes = ((U64)((bo << 3) << 10)) / (eff1);
10936 /* Get the number of RBs needed for this transmission */
10937 /* Number of RBs = No of REs / No of REs per RB */
10938 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
10942 noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
10943 noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
10944 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
10945 iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
10946 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
10947 eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
10949 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
10950 * i.e, << 3 and multiply with 1024 i.e, << 10 */
10951 noRes = ((U64)((bo << 3) << 10)) / (eff1 + eff2);
10952 /* Get the number of RBs needed for this transmission */
10953 /* Number of RBs = No of REs / No of REs per RB */
10954 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
10957 } /* rgSchUtlDlCalc2CwPrb */
10960 * @brief Utility function to calculate total num of PRBs required to
10961 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
10965 * Function : rgSchUtlCalcTotalPrbReq
10967 * This function calls TM specific routine to calculate PRB
10970 * @param[in] RgSchCellCb *cell
10971 * @param[in] RgSchUeCb *ue
10972 * @param[in] U32 bo
10973 * @param[out] U32 *prbReqrd
10977 Void rgSchUtlCalcTotalPrbReq
10985 Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd)
10992 /* Call TM specific Prb calculation routine */
10993 (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
10996 } /* rgSchUtlCalcTotalPrbReq */
10999 /***********************************************************
11001 * Func : rgSCHUtlFetchPcqiBitSz
11004 * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
11013 **********************************************************/
11015 PRIVATE U8 rgSCHUtlFetchPcqiBitSz
11022 PRIVATE U8 rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt)
11031 RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
11033 confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
11034 if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) &&
11035 (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
11041 ri = cqiCb->perRiVal;
11043 switch(confRepMode)
11045 case RGR_PRD_CQI_MOD10:
11051 case RGR_PRD_CQI_MOD11:
11064 else if(numTxAnt == 4)
11077 /* This is number of antenna case 1.
11078 * This is not applicable for Mode 1-1.
11079 * So setting it to invalid value */
11085 case RGR_PRD_CQI_MOD20:
11093 pcqiSz = 4 + cqiCb->label;
11098 case RGR_PRD_CQI_MOD21:
11113 else if(numTxAnt == 4)
11126 /* This might be number of antenna case 1.
11127 * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
11128 * So setting invalid value.*/
11136 pcqiSz = 4 + cqiCb->label;
11140 pcqiSz = 7 + cqiCb->label;
11156 * @brief Utility function to returns the number of subbands based on the
11161 * Function : rgSchUtlGetNumSbs
11163 * Calculate the number of PRBs
11164 * Update the subbandRequired based on the nPrbs and subband size
11166 * @param[in] RgSchCellCb *cell
11167 * @param[in] RgSchUeCb *ue
11168 * @param[in] U32 *numSbs
11172 U8 rgSchUtlGetNumSbs
11179 U8 rgSchUtlGetNumSbs (cell, ue, numSbs)
11186 //Currently hardcoding MAX prb for each UE
11187 nPrb = ue->ue5gtfCb.maxPrb;
11188 (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
11193 * @brief Utility function to insert the UE node into UE Lst based on the
11194 * number of subbands allocated for the UE for the current TTI.
11198 * Function : rgSchUtlSortInsUeLst
11200 * If subbandRequired < Min, then insert at head
11201 * Else If subbandRequired > Max, then insert at tail
11202 * Else, traverse the list and place the node at the appropriate place
11204 * @param[in] RgSchCellCb *cell
11205 * @param[in] RgSchUeCb *ue
11209 U8 rgSchUtlSortInsUeLst
11217 U8 rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired)
11225 CmLList *firstUeInLst;
11226 CmLList *lastUeInLst;
11228 RgSchCmnUlUe *ueUl;
11230 //firstUeInLst = cmLListFirst(ueLst);
11231 CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
11232 if(NULLP == firstUeInLst)
11234 /* first node to be added to the list */
11235 cmLListAdd2Tail(ueLst, node);
11239 /* Sb Required for the UE is less than the first node in the list */
11240 tempUe = (RgSchUeCb *)(firstUeInLst->node);
11241 ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
11243 if(vrbgRequired <= ueUl->vrbgRequired)
11245 cmLListInsCrnt(ueLst, (node));
11249 /* Sb Required for this UE is higher than the UEs in the list */
11250 lastUeInLst = cmLListLast(ueLst);
11251 tempUe = (RgSchUeCb *)(lastUeInLst->node);
11252 if(vrbgRequired >= ueUl->vrbgRequired)
11254 cmLListAdd2Tail(ueLst, (node));
11258 /* This UE needs to be in the middle. Search and insert the UE */
11259 ueInLst = cmLListFirst(ueLst);
11262 tempUe = (RgSchUeCb *)(ueInLst->node);
11264 if(vrbgRequired <= ueUl->vrbgRequired)
11266 cmLListInsCrnt(ueLst, (node));
11270 ueInLst = cmLListNext(ueLst);
11272 } while(NULLP != ueInLst && ueInLst != firstUeInLst);
11281 * @brief Function to Send LCG GBR register to MAC
11285 * Function: rgSCHUtlBuildNSendLcgReg
11287 * Handler for sending LCG GBR registration
11292 * Processing Steps:
11294 * @param[in] RgSchCellCb *cell
11295 * @param[in] CmLteRnti crnti
11296 * @param[in] U8 lcgId
11297 * @param[in] Bool isGbr
11302 S16 rgSCHUtlBuildNSendLcgReg
11310 S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr)
11318 RgInfLcgRegReq lcgRegReq;
11320 memset(&pst, 0, sizeof(Pst));
11321 lcgRegReq.isGbr = isGbr;
11322 lcgRegReq.cellId = cell->cellId;
11323 lcgRegReq.crnti = crnti;
11324 lcgRegReq.lcgId = lcgId;
11325 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
11326 /* code Coverage portion of the test case */
11327 RgSchMacLcgReg(&pst, &lcgRegReq);
11336 * @brief Function to map RGR pucch type to TFU type
11340 * Function: rgSchUtlGetFdbkMode
11346 * Processing Steps:
11348 * @param[in] RgrSchFrmt1b3TypEnum
11349 * @return TfuAckNackMode
11353 TfuAckNackMode rgSchUtlGetFdbkMode
11355 RgrSchFrmt1b3TypEnum fdbkType
11358 TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType)
11359 RgrSchFrmt1b3TypEnum fdbkType;
11363 TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
11367 case RG_SCH_UCI_FORMAT_NON_CA:
11368 case RG_SCH_UCI_FORMAT1A_1B:
11370 mode = TFU_UCI_FORMAT_1A_1B;
11373 case RG_SCH_UCI_FORMAT1B_CS:
11375 mode = TFU_UCI_FORMAT_1B_CS;
11378 case RG_SCH_UCI_FORMAT3:
11380 mode = TFU_UCI_FORMAT_3;
11386 #endif /* TFU_TDD */
11387 #endif /* LTE_ADV */
11388 #endif /*TFU_UPGRADE */
11392 * @brief Send Ue SCell delete to SMAC.
11396 * Function : rgSCHUtlSndUeSCellDel2Mac
11397 * This function populates the struct RgInfRlsRnti and
11398 * get the pst for SMac and mark field isUeSCellDel to TRUE which
11399 * indicates that it is a Ue SCell delete.
11403 * @param[in] RgSchCellCb *cell
11404 * @param[in] CmLteRnti rnti
11409 Void rgSCHUtlSndUeSCellDel2Mac
11415 Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti)
11421 Inst inst = cell->instIdx;
11422 RgInfRlsRnti rntiInfo;
11424 RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti));
11425 /* Copy the info to rntiInfo */
11426 rntiInfo.cellId = cell->cellId;
11427 rntiInfo.rnti = rnti;
11428 /* Fix : syed ueId change as part of reestablishment.
11429 * Now SCH to trigger this. CRG ueRecfg for ueId change
11431 rntiInfo.ueIdChng = FALSE;
11432 rntiInfo.newRnti = rnti;
11433 rntiInfo.isUeSCellDel = TRUE;
11434 /* Invoke MAC to release the rnti */
11435 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
11436 RgSchMacRlsRnti(&pst, &rntiInfo);
11441 * @brief Returns max TB supported by a given txMode
11445 * Function : rgSCHUtlGetMaxTbSupp
11446 * Max TB supported for TM Modes (1,2,5,6 and 7) is 1
11450 * @param[in] RgrTxMode txMode
11451 * @return U8 maxTbCount;
11455 U8 rgSCHUtlGetMaxTbSupp
11460 U8 rgSCHUtlGetMaxTbSupp(txMode)
11488 return (maxTbCount);
11492 * @brief Send Ue SCell delete to SMAC.
11496 * Function : rgSCHTomUtlGetTrigSet
11497 * This function gets the triggerset based on cqiReq
11499 * @param[in] RgSchCellCb *cell
11500 * @param[in] RgSchUeCb ueCb
11501 * @param[in] U8 cqiReq,
11502 * @param[out] U8 *triggerSet
11508 Void rgSCHTomUtlGetTrigSet
11516 PRIVATE S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet)
11523 RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
11526 case RG_SCH_APCQI_SERVING_CC:
11528 /* APeriodic CQI request for Current Carrier.*/
11529 U8 sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
11530 *triggerSet = 1 << (7 - sCellIdx);
11533 case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
11535 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
11538 case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
11540 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
11553 * @brief This function updates the value of UE specific DCI sizes
11557 * Function: rgSCHUtlUpdUeDciSize
11558 * Purpose: This function calculates and updates DCI Sizes in bits.
11560 * Invoked by: Scheduler
11562 * @param[in] RgSchCellCb *cell
11563 * @param[in] RgSchUeCb *ueCb
11564 * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI
11569 Void rgSCHUtlUpdUeDciSize
11576 Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit)
11582 U8 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11583 U8 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11584 if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
11586 dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
11587 dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
11589 if (isCsi2Bit == TRUE)
11591 dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
11595 dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
11598 /* Common CSI is always 1 bit DCI 0 */
11599 dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
11601 /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
11602 if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11604 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11606 if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11608 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11611 /* 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 */
11612 dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
11613 dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
11615 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize;
11616 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
11618 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize;
11619 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
11621 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11623 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11624 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11625 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11626 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11627 if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
11629 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
11632 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11633 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11634 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11635 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11636 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
11637 } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
11639 /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
11640 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11641 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11642 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11643 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11645 /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource
11646 * on a secondary cell without an uplink configuration associated with the secondary cell */
11647 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11648 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
11649 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11651 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11652 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11653 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11654 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11655 if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
11657 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
11660 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11661 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11662 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11663 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11664 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
11665 } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
11667 rgSCHEmtcUtlUpdUeDciSize(cell, ueCb);
11672 * @brief This function initialises the DCI Size table
11676 * Function: rgSCHUtlCalcDciSizes
11677 * Purpose: This function calculates and initialises DCI Sizes in bits.
11679 * Invoked by: Scheduler
11681 * @param[in] RgSchCellCb *cell
11686 Void rgSCHUtlCalcDciSizes
11691 Void rgSCHUtlCalcDciSizes(cell)
11697 U32 bits = 0, idx = 0;
11699 switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
11701 case TFU_DCI_FORMAT_0:
11703 /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
11705 /*-- Calculate resource block assignment bits need to be set
11706 Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
11707 bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
11708 while ((bits & 0x8000) == 0)
11715 dciSize = 1 /* DCI 0 bit indicator */ + \
11716 1 /* Frequency hoping enable bit field */ + \
11717 (U8)bits /* For frequency Hopping */ + \
11724 2 /* UL Index Config 0 or DAI Config 1-6 */
11728 cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
11730 /* If hoping flag is enabled */
11731 if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
11733 cell->dciSize.dci0HopSize = 1;
11737 cell->dciSize.dci0HopSize = 2;
11740 /* Update common non-CRNTI scrambled DCI 0/1A flag */
11741 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
11743 case TFU_DCI_FORMAT_1A:
11745 /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
11748 /* Calculate resource block assignment bits need to be set
11749 Which is ln(N(N+1)/2) */
11750 bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
11751 while ((bits & 0x8000) == 0)
11758 dciSize += 1 /* Format 1A */ + \
11759 1 /* Local or Distributed */ + \
11760 (U8)bits /* Resource block Assignment */ + \
11763 4 /* HARQ Proc Id */ +
11765 3 /* HARQ Proc Id */ +
11775 cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
11777 /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI,
11778 * and the number of information bits in format 1A is less than that of format 0,
11779 * zeros shall be appended to format 1A until the payload size equals that of format 0. */
11780 /* Compare the size with DCI 1A and DCI 0 and consider the greater one */
11781 if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11783 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11785 /* If the number of information bits in format 1A belongs to one of the sizes in
11786 * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
11787 dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
11788 cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
11790 case TFU_DCI_FORMAT_1:
11792 /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
11794 if (cell->bwCfg.dlTotalBw > 10)
11796 dciSize = 1; /* Resource Allocation header bit */
11799 /* Resouce allocation bits Type 0 and Type 1 */
11800 bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
11801 if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
11806 dciSize += (U8)bits /* Resource Allocation bits */ + \
11814 2 /* Redunancy Version */ + \
11823 cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
11825 cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
11828 /* If the UE is not configured to decode PDCCH with CRC
11829 * scrambled by the C-RNTI and the number of information bits in format 1
11830 * is equal to that for format 0/1A, one bit of value zero shall be appended
11832 if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
11834 cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
11837 /* If the number of information bits in format 1 belongs to one of the sizes in
11838 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until
11839 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1
11840 * and is not equal to that of format 0/1A mapped onto the same search space. */
11841 cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
11842 } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
11844 case TFU_DCI_FORMAT_2:
11846 /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
11848 if (cell->bwCfg.dlTotalBw > 10)
11850 dciSize = 1; /* Resource Allocation bit */
11853 dciSize += (U8)bits /* Resource Allocation bits */ + \
11861 1 /* CW Swap Flag */ + \
11862 5 /* MCS for TB1 */+ \
11863 1 /* NDI for TB1 */+ \
11864 2 /* RV for TB1 */ + \
11865 5 /* MCS for TB2 */+ \
11866 1 /* NDI for TB2 */+ \
11867 2 /* RV for TB2 */;
11868 if (cell->numTxAntPorts == 2)
11872 else if (cell->numTxAntPorts == 4)
11876 cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
11877 cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
11879 case TFU_DCI_FORMAT_2A:
11881 /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
11883 if (cell->bwCfg.dlTotalBw > 10)
11885 dciSize = 1; /* Resource Allocation bit */
11888 dciSize += (U8)bits /* Resource Allocation bits */ + \
11896 1 /* CW Swap Flag */ + \
11897 5 /* MCS for TB1 */+ \
11898 1 /* NDI for TB1 */+ \
11899 2 /* RV for TB1 */ + \
11900 5 /* MCS for TB2 */+ \
11901 1 /* NDI for TB2 */+ \
11902 2 /* RV for TB2 */;
11903 if (cell->numTxAntPorts == 4)
11907 cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
11908 cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
11909 rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
11911 case TFU_DCI_FORMAT_3:
11913 /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
11914 cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
11915 if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
11917 cell->dciSize.size[TFU_DCI_FORMAT_3]++;
11920 case TFU_DCI_FORMAT_3A:
11922 /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
11923 cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
11926 case TFU_DCI_FORMAT_6_0A:
11928 rgSCHEmtcGetDciFrmt60ASize(cell);
11930 case TFU_DCI_FORMAT_6_1A:
11932 rgSCHEmtcGetDciFrmt61ASize(cell);
11937 /* DCI format not supported */
11944 * @brief Handler for the CPU OvrLd related state adjustment.
11948 * Function : rgSCHUtlCpuOvrLdAdjItbsCap
11950 * Processing Steps:
11951 * - Record dl/ulTpts
11952 * - Adjust maxItbs to acheive target throughputs
11954 * @param[in] RgSchCellCb *cell
11958 Void rgSCHUtlCpuOvrLdAdjItbsCap
11963 Void rgSCHUtlCpuOvrLdAdjItbsCap(cell)
11969 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP |
11970 RGR_CPU_OVRLD_DL_TPT_DOWN))
11972 /* Regulate DL Tpt for CPU overload */
11973 if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
11975 tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
11976 /* Upto 0.5% drift in measured vs target tpt is ignored */
11977 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
11979 cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
11984 tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
11985 /* Upto 0.5% drift in measured vs target tpt is ignored */
11986 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
11988 cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
11991 #ifdef CPU_OL_DBG_PRINTS
11992 printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt,
11993 cell->thresholds.maxDlItbs);
11997 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP |
11998 RGR_CPU_OVRLD_UL_TPT_DOWN))
12000 /* Regualte DL Tpt for CPU overload */
12001 if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
12003 tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
12004 /* Upto 1% drift in measured vs target tpt is ignored */
12005 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12007 cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
12012 tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
12013 /* Upto 1% drift in measured vs target tpt is ignored */
12014 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12016 cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
12019 #ifdef CPU_OL_DBG_PRINTS
12020 printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt,
12021 cell->thresholds.maxUlItbs);
12028 * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
12032 * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12034 * Processing Steps:
12035 * - Validate the config params.
12036 * - Update numUEperTTi CPU OL related information.
12037 * - If successful, return ROK else RFAILED.
12039 * @param[in] RgSchCellCb *cell
12040 * @param[in] U8 cnrtCpuOvrLdIns
12044 PRIVATE Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12050 PRIVATE S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns)
12052 U8 crntCpuOvrLdIns;
12055 RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl);
12056 RgSchCmnCell *cellSch;
12057 U8 maxUeNewDlTxPerTti;
12058 U8 maxUeNewUlTxPerTti;
12060 #ifdef CPU_OL_DBG_PRINTS
12066 cellSch = RG_SCH_CMN_GET_CELL(cell);
12068 maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti;
12069 maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
12071 /* Calculate Maximum Decremen */
12072 maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12073 maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12075 /* Check for DL CPU Commands */
12076 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI )
12078 /* Decrement till 90% of maxUeNewDlTxPerTti */
12079 if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
12081 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12082 cpuInstr->dlNxtIndxDecNumUeTti++;
12083 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] > 1 )
12085 cpuInstr->maxUeNewTxPerTti[tmpslot]--;
12089 #ifdef CPU_OL_DBG_PRINTS
12090 printf("CPU_OL_TTI__ERROR\n");
12092 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12095 #ifdef CPU_OL_DBG_PRINTS
12096 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12098 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12099 cpuInstr->dlNxtIndxDecNumUeTti);
12101 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
12103 if ( cpuInstr->dlNxtIndxDecNumUeTti > 0)
12105 cpuInstr->dlNxtIndxDecNumUeTti--;
12106 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12107 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] < maxUeNewDlTxPerTti )
12109 cpuInstr->maxUeNewTxPerTti[tmpslot]++;
12113 #ifdef CPU_OL_DBG_PRINTS
12114 printf("CPU_OL_TTI__ERROR\n");
12116 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12119 #ifdef CPU_OL_DBG_PRINTS
12120 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12122 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12123 cpuInstr->dlNxtIndxDecNumUeTti);
12125 /* Check for UL CPU commands */
12126 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
12128 /* Decrement till 90% of maxUeNewDlTxPerTti */
12129 if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
12131 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12132 cpuInstr->ulNxtIndxDecNumUeTti++;
12133 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] > 1 )
12135 cpuInstr->maxUeNewRxPerTti[tmpslot]--;
12139 #ifdef CPU_OL_DBG_PRINTS
12140 printf("CPU_OL_TTI__ERROR\n");
12142 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12145 #ifdef CPU_OL_DBG_PRINTS
12146 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12148 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12149 cpuInstr->dlNxtIndxDecNumUeTti);
12151 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
12153 if ( cpuInstr->ulNxtIndxDecNumUeTti > 0)
12155 cpuInstr->ulNxtIndxDecNumUeTti--;
12156 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12157 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] < maxUeNewUlTxPerTti )
12159 cpuInstr->maxUeNewRxPerTti[tmpslot]++;
12163 #ifdef CPU_OL_DBG_PRINTS
12164 printf("CPU_OL_TTI__ERROR\n");
12166 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12169 #ifdef CPU_OL_DBG_PRINTS
12170 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12172 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12173 cpuInstr->dlNxtIndxDecNumUeTti);
12175 #ifdef CPU_OL_DBG_PRINTS
12176 /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
12177 printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
12178 printf("DL Sf numUePerTti:");
12179 for ( idx = 0; idx < 10 ; idx ++ )
12181 printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]);
12183 printf("\nUL Sf numUePerTti:");
12184 for ( idx = 0; idx < 10 ; idx ++ )
12186 printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]);
12192 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
12195 * @brief Handler for the CPU OvrLd related cell Recfg.
12199 * Function : rgSCHUtlResetCpuOvrLdState
12201 * Processing Steps:
12202 * - Validate the config params.
12203 * - Update CPU OL related state information.
12204 * - If successful, return ROK else RFAILED.
12206 * @param[in] RgSchCellCb *cell
12207 * @param[in] U8 cnrtCpuOvrLdIns
12213 S16 rgSCHUtlResetCpuOvrLdState
12219 S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns)
12221 U8 crntCpuOvrLdIns;
12226 RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
12229 #ifdef CPU_OL_DBG_PRINTS
12230 printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
12232 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd");
12234 if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
12236 /* The CPU OL instruction received with RESET (0), hence reset it */
12237 #ifdef CPU_OL_DBG_PRINTS
12238 printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
12240 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD");
12241 cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
12242 /* Reset the max UL and DL itbs to 26 */
12243 cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
12244 cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
12245 /* Reset the num UE per TTI intructions */
12246 cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
12247 cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
12248 for ( idx = 0; idx < 10; idx++ )
12250 cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] =
12251 schCmnCell->dl.maxUeNewTxPerTti;
12252 cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] =
12253 schCmnCell->ul.maxUeNewTxPerTti;
12258 /* Check and Update numUEPer TTI based CPU overload instruction before
12259 * going for TP based CPU OL
12260 * TTI based intrcuctions shall be > 0xF */
12261 if ( crntCpuOvrLdIns > 0xF )
12263 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
12264 /* If need to have both TP and numUePerTti instrcution together in
12265 * one command then dont return from here */
12269 crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
12270 (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
12271 if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) &&
12272 (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
12274 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12277 crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
12278 (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
12279 if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) &&
12280 (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
12282 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12285 if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
12287 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12291 cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
12295 if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
12297 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
12298 (cell->measurements.ulTpt * 3 )/100;
12302 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
12303 (cell->measurements.ulTpt * 2 )/100;
12305 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to "
12306 "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
12307 #ifdef CPU_OL_DBG_PRINTS
12308 printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
12309 cell->measurements.ulTpt);
12315 if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
12317 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
12318 (cell->measurements.dlTpt * 1 )/100;
12322 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
12323 (cell->measurements.dlTpt * 1 )/100;
12325 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to "
12326 "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
12328 #ifdef CPU_OL_DBG_PRINTS
12329 printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
12330 cell->measurements.dlTpt);
12333 rgSCHUtlCpuOvrLdAdjItbsCap(cell);
12337 S16 rgSCHUtlAddToResLst
12340 RgSchIotRes *iotRes
12343 cmLListAdd2Tail(cp, &iotRes->resLnk);
12344 iotRes->resLnk.node = (PTR)iotRes;
12347 S16 rgSCHUtlDelFrmResLst
12350 RgSchIotRes *iotRes
12353 CmLListCp *cp = NULLP;
12354 RgSchEmtcUeInfo *emtcUe = NULLP;
12355 emtcUe = RG_GET_EMTC_UE_CB(ue);
12356 if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
12358 cp = &emtcUe->ulResLst;
12359 }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
12361 cp = &emtcUe->dlResLst;
12364 RLOG0(L_INFO, "*****restype mismatch");
12370 RLOG0(L_INFO,"****error count*****\n");
12374 cmLListDelFrm(cp, &iotRes->resLnk);
12375 iotRes->resLnk.node = NULLP;
12379 /**********************************************************************
12382 **********************************************************************/