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 uint32_t rgNumPrachRecvd =0; /* Num of Rach Req received including dedicated preambles */
68 uint32_t rgNumRarSched =0; /* Num of RARs sent */
69 uint32_t rgNumBI =0; /* Num of BackOff Ind sent */
70 uint32_t rgNumMsg3CrcPassed =0; /* Num of CRC success for Msg3 */
71 uint32_t rgNumMsg3CrcFailed =0; /* Num of CRC fail for Msg 3 */
72 uint32_t rgNumMsg3FailMaxRetx =0; /* Num of Msg3 fail after Max Retx attempts */
73 uint32_t rgNumMsg4Ack =0; /* Num of Acks for Msg4 Tx */
74 uint32_t rgNumMsg4Nack =0;
75 /* Num of Nacks for Msg4 Tx */
76 uint32_t rgNumMsg4FailMaxRetx =0; /* Num of Msg4 Tx failed after Max Retx attempts */
77 uint32_t rgNumSrRecvd =0; /* Num of Sched Req received */
78 uint32_t rgNumSrGrant =0; /* Num of Sched Req Grants sent */
79 uint32_t rgNumMsg3CrntiCE =0; /* Num of Msg 3 CRNTI CE received */
80 uint32_t rgNumDedPream =0; /* Num of Dedicated Preambles recvd */
81 uint32_t rgNumMsg3CCCHSdu =0; /* Num of Msg 3 CCCH Sdus recvd */
82 uint32_t rgNumCCCHSduCrntiNotFound =0; /*UE Ctx not found for CCCH SDU Msg 3 */
83 uint32_t rgNumCrntiCeCrntiNotFound =0; /*UE Ctx not found for CRNTI CE Msg 3 */
84 uint32_t rgNumMsg4WithCCCHSdu =0; /* Num of Msg4 with CCCH Sdu */
85 uint32_t rgNumMsg4WoCCCHSdu =0; /* Num of Msg4 without CCCH Sdu */
86 uint32_t rgNumMsg4Dtx =0; /* Num of DTX received for Msg 4 */
87 uint32_t rgNumMsg3AckSent =0; /* Num of PHICH Ack sent for Msg 3 */
88 uint32_t rgNumMsg3NackSent =0; /* Num of PHICH Nack sent for Msg 3 */
89 uint32_t rgNumMsg4PdcchWithCrnti =0; /* Num of PDCCH for CRNTI based contention resolution */
90 uint32_t rgNumRarFailDuetoRntiExhaustion =0; /* Num of RACH Failures due to RNTI pool exhaution */
91 uint32_t rgNumTAModified =0; /* Num of times TA received is different from prev value */
92 uint32_t rgNumTASent =0; /* Num of TA Command sent */
93 uint32_t rgNumMsg4ToBeTx =0; /* Num of times MSG4 that should be sent */
94 uint32_t rgNumMsg4Txed =0; /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */
95 uint32_t rgNumMsg3DtxRcvd =0; /* CRC Fail with SINR < 0 */
97 uint32_t rgNumDedPreamUECtxtFound =0; /* Num of Dedicated Preambles recvd */
99 static uint8_t 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 uint32_t rgSchCmnBetaCqiOffstTbl[16];
109 uint32_t rgSchCmnBetaRiOffstTbl[16];
110 RgSchdApis rgSchCmnApis;
111 S16 RgUiRgmSendPrbRprtInd ARGS((
114 RgmPrbRprtInd *prbRprtInd
117 S16 RgUiRgmSendTmModeChangeInd ARGS((
120 RgmTransModeInd *txModeChngInd
123 S16 rgSCHEmtcUtlGetSfAlloc ARGS((
126 S16 rgSCHEmtcUtlPutSfAlloc ARGS((
129 Void rgSCHEmtcUtlUpdUeDciSize ARGS((
133 Void rgSCHEmtcGetDciFrmt61ASize ARGS((
136 Void rgSCHEmtcGetDciFrmt60ASize ARGS((
139 S16 rgSCHEmtcUtlFillPdschDciInfo ARGS((
140 TfuPdschDciInfo *pdsch,
143 Void rgSCHEmtcUtlRlsRnti ARGS((
145 RgSchRntiLnk *rntiLnk,
148 S16 rgSCHEmtcPdcchAlloc ARGS((
152 Void rgSCHEmtcPdcchFree ARGS((
157 /* Functions specific to TM1/TM2/TM6/TM7 for PRB calculation*/
158 Void rgSchUtlDlCalc1CwPrb ARGS(( RgSchCellCb *cell,
161 uint32_t *prbReqrd));
163 /* Functions specific to TM3/TM4 for PRB calculation*/
164 Void rgSchUtlDlCalc2CwPrb ARGS(( RgSchCellCb *cell,
167 uint32_t *prbReqrd));
170 RgSchCellCb* rgSchUtlGetCellCb ARGS(( Inst inst,
175 typedef Void (*RgSchUtlDlCalcPrbFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
176 uint32_t bo, uint32_t *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 static uint8_t rgSchTddCfg0UlSfTbl[] = {2, 3, 4, 7, 8, 9};
197 static S16 rgSCHUtlUlAllocDbInit ARGS((
202 static Void rgSCHUtlUlAllocDbDeinit ARGS((
206 static S16 rgSCHUtlUlHoleDbInit ARGS((
213 static Void rgSCHUtlUlHoleDbDeinit ARGS((
218 static S16 rgSCHChkBoUpdate ARGS((
220 RgInfCmnBoRpt *boUpdt
224 static uint8_t rgSCHUtlFetchPcqiBitSz ARGS((
231 /* sorted in ascending order of tbSz */
232 const struct rgSchUtlBcchPcchTbSz
234 uint8_t rbIndex; /* RB index {2,3} */
235 uint16_t tbSz; /* one of the Transport block size in bits of
237 /* Corrected allocation for common channels */
238 uint8_t mcs; /* imcs */
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 static 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) ((((uint8_t*)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
357 uint32_t rgSCHUtlParse
365 uint32_t rgSCHUtlParse(buff, startPos, endPos, buffSize)
372 uint8_t pointToChar,pointToEnd, loop;
373 uint8_t 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 ((uint32_t)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
403 uint8_t rgSCHUtlFindDist
409 uint8_t 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
451 * @param[in] uint8_t loc
452 * @param[in] uint8_t 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;
481 uint16_t offsetStepMask;
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
579 * @param[in] uint8_t loc
580 * @param[in] uint8_t 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 static 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 static 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(uint8_t)))) != 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 static 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(uint8_t)));
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 static Void rgSchSFRResetPoolVariables
1083 RgSchSFRPoolInfo *pool
1086 static 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 static Void rgSCHSFRUtlTotalPoolReset
1126 static 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] uint8_t hqFeedBack
1184 * @param[in] uint8_t nDmrs
1185 * @param[in] uint8_t 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 static Void rgSCHUtlPhichReset
1279 static 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
1482 * @param[in] uint32_t n
1487 uint8_t rgSCHUtlLog32bitNbase2
1492 uint8_t rgSCHUtlLog32bitNbase2(n)
1496 uint32_t b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
1497 uint32_t 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] uint8_t 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 (uint16_t)
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 static uint16_t rgSCHUtlCalcTotalRegs
1643 static uint16_t 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 (uint8_t)
1695 * Notes: ng6 is Ng multiplied by 6
1699 **********************************************************/
1701 static uint16_t rgSCHUtlCalcPhichRegs
1707 static uint16_t 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
1730 * @param[in] uint8_t bw
1731 * @param[in] uint8_t ng6
1732 * @param[in] uint8_t cfi
1733 * @param[in] uint8_t mPhich
1734 * @param[in] uint8_t numAntna
1735 * @param[in] Bool isEcp
1736 * @return N_cce (uint8_t)
1740 uint8_t rgSCHUtlCalcNCce
1750 uint8_t 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 ((uint8_t)(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
1804 * @param[in] uint8_t bw
1805 * @param[in] uint8_t ng6
1806 * @param[in] uint8_t cfi
1807 * @param[in] uint8_t numAntna
1808 * @return N_cce (uint8_t)
1812 uint8_t rgSCHUtlCalcNCce
1821 uint8_t 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 ((uint8_t)(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] uint8_t *rbStartRef
1874 * @param[out] uint8_t *nDmrsRef
1879 S16 rgSCHUtlGetPhichInfo
1881 RgSchUlHqProcCb *hqProc,
1882 uint8_t *rbStartRef,
1887 S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef, iPhich)
1888 RgSchUlHqProcCb *hqProc;
1889 uint8_t *rbStartRef;
1895 S16 rgSCHUtlGetPhichInfo
1897 RgSchUlHqProcCb *hqProc,
1898 uint8_t *rbStartRef,
1902 S16 rgSCHUtlGetPhichInfo(hqProc, rbStartRef, nDmrsRef)
1903 RgSchUlHqProcCb *hqProc;
1904 uint8_t *rbStartRef;
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] uint8_t *rbStartRef
1940 * @param[out] uint8_t *numRbRef
1941 * @param[out] uint8_t *rvRef
1942 * @param[out] uint16_t *size
1943 * @param[out] TfuModScheme *modType
1944 * @param[out] Bool *isRtx
1945 * @param[out] uint8_t *nDmrs
1946 * @param[out] Bool *ndi
1947 * @param[out] uint8_t *hqPId
1951 S16 rgSCHUtlAllocRcptInfo
1953 RgSchUlAlloc *alloc,
1956 uint8_t *rbStartRef,
1960 TfuModScheme *modType,
1967 S16 rgSCHUtlAllocRcptInfo(alloc, rnti, iMcsRef, rbStartRef, numRbRef,
1968 rvRef, size, modType, isRtx, nDmrs, ndi,
1970 RgSchUlAlloc *alloc;
1973 uint8_t *rbStartRef;
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] uint8_t *rbStartRef
2041 * @param[out] uint8_t *numRbRef
2042 * @param[out] uint8_t *rvRef
2043 * @param[out] uint16_t *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 static Void rgSCHUtlUpdPrachOcc
2164 RgrTddPrachInfo *cellCfg
2167 static 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 uint8_t ulDlCfgIdx = cellCfg->ulDlCfgIdx;
2323 uint16_t 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 = (uint16_t)((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(uint8_t)))) != 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] uint8_t 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] uint8_t isAck
3358 Void rgSCHUtlUpdACqiTrigWt
3361 RgSchUeCellInfo *cellInfo,
3365 Void rgSCHUtlUpdACqiTrigWt(ue,cellInfo, isAck)
3367 RgSchUeCellInfo *cellInfo;
3372 uint8_t triggerSet = 0;
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] uint8_t 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 uint32_t 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] uint8_t 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 uint8_t servCellIdx
3773 uint8_t rgSchUtlGetServCellIdx
3780 uint8_t rgSchUtlGetServCellIdx(inst,cellId,ue)
3786 uint8_t servCellIdx;
3787 uint16_t strtCellId;
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] uint8_t lcgId
4190 * @param[in] uint8_t bsr
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] uint8_t lcgId
4232 * @param[in] uint8_t bsr
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] uint8_t bsr0
4276 * @param[in] uint8_t bsr1
4277 * @param[in] uint8_t bsr2
4278 * @param[in] uint8_t 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
4327 * @param[in] uint8_t phr
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
4365 * @param[in] uint8_t phr
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] uint8_t 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
4607 * @param[in] uint8_t idx
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 = (uint8_t) 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 static 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 static Void rgSCHUtlFillRgInfTbInfo
5909 RgSchDlHqProcCb *hqP,
5910 RgInfUeAlloc *allocInfo,
5914 static Void rgSCHUtlFillRgInfTbInfo (hqP, allocInfo, cell)
5915 RgSchDlHqProcCb *hqP;
5916 RgInfUeAlloc *allocInfo;
5922 RgInfUeTbInfo *tbInfo;
5924 /* LTE_ADV_FLAG_REMOVED_START */
5926 static uint32_t tmpCnt = 0;
5927 Bool isAllUePwrHigh = FALSE;
5929 /* LTE_ADV_FLAG_REMOVED_END */
5930 RgSchDlLcCb *dlLcCb = NULLP;
5931 uint16_t rlcHdrEstmt;
5935 uint8_t prbUsed = 0;
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 = (uint8_t)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 = (uint8_t)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 (uint8_t)(pdu->ceInfo.ces.bsr.truncBsr >> 6),
6471 (uint8_t)(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 (uint8_t)(pdu->ceInfo.ces.bsr.shortBsr >> 6),
6482 (uint8_t)(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 = (uint32_t)(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 = (uint32_t)(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
6707 * @param[in] uint32_t bo
6708 * @param[out] uint8_t *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] uint8_t 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] uint8_t 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] uint8_t 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 */
7030 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] uint16_t spsSduSize
7182 S16 rgSCHUtlSpsActInd
7184 RgSchCellCb *cellCb,
7189 S16 rgSCHUtlSpsActInd (cellCb, ueCb, spsSduSize)
7190 RgSchCellCb *cellCb;
7192 uint16_t spsSduSize;
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 uint32_t startTime=0;
7516 sMem.region = rgSchCb[inst].rgSchInit.region;
7517 sMem.pool = rgSchCb[inst].rgSchInit.pool;
7519 #if (ERRCLASS & ERRCLS_DEBUG)
7522 RGSCHLOGERROR(inst, ERRCLS_INT_PAR, ERG022, memSize,
7523 "rgAllocEventMem(): memSize invalid\n");
7526 #endif /* ERRCLASS & ERRCLS_DEBUG */
7528 SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
7530 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
7531 MS_BUF_ADD_ALLOC_CALLER();
7533 #ifdef TFU_ALLOC_EVENT_NO_INIT
7534 if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7536 if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
7539 RLOG_ARG0(L_ERROR,DBG_INSTID,inst,"cmAllocEvnt Failed.");
7543 SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
7545 } /* end of rgSCHUtlAllocEventMem*/
7549 * Fun: rgGetEventMem
7551 * Desc: This function allocates event memory
7553 * Ret: ROK - on success
7554 * RFAILED - on failure
7562 S16 rgSCHUtlGetEventMem
7569 S16 rgSCHUtlGetEventMem(ptr, len, memCp)
7577 #ifdef TFU_ALLOC_EVENT_NO_INIT
7578 ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
7580 ret = cmGetMem(memCp, len, (Ptr *)ptr);
7583 } /* end of rgSCHUtlGetEventMem*/
7589 * @brief Handler to allocate memory for ACK/NACk feedback information
7593 * Function : rgSCHUtlAllocUeANFdbkInfo
7595 * It allocates memory for the UE related ACK NACK information.
7597 * @param[in] RgSchUeCb *ue
7601 S16 rgSCHUtlAllocUeANFdbkInfo
7607 S16 rgSCHUtlAllocUeANFdbkInfo(ue,servCellIdx)
7609 uint8_t servCellIdx;
7614 if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
7615 (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
7616 ue->cell->ackNackFdbkArrSize) != ROK)
7621 for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
7623 rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
7626 /* Set it to the first index */
7627 ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
7629 } /* rgSCHUtlAllocUeANFdbkInfo */
7632 * @brief Handler to release memory for ACK/NACk feedback information
7636 * Function : rgSCHUtlDelUeANFdbkInfo
7638 * It releases memory for the UE related ACK NACK information.
7640 * @param[in] RgSchUeCb *ue
7644 Void rgSCHUtlDelUeANFdbkInfo
7650 Void rgSCHUtlDelUeANFdbkInfo(ue,servCellIdx)
7652 uint8_t servCellIdx;
7656 /* ccpu00117052 - MOD - Passing double pointer
7657 for proper NULLP assignment*/
7658 rgSCHUtlFreeSBuf(ue->cell->instIdx,
7659 (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
7660 ue->cell->ackNackFdbkArrSize);
7663 } /* rgSCHUtlDelUeANFdbkInfo */
7666 * @brief Handler to initialise UE ACK/NACk feedback information
7670 * Function : rgSCHUtlInitUeANFdbkInfo
7672 * It initialises UE related ACK NACK information.
7674 * @param[in] RgSchTddANInfo *anFdInfo
7678 S16 rgSCHUtlInitUeANFdbkInfo
7680 RgSchTddANInfo *anFdInfo
7683 S16 rgSCHUtlInitUeANFdbkInfo(anFdInfo)
7684 RgSchTddANInfo *anFdInfo;
7688 anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
7690 anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
7691 anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
7692 anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
7695 } /* rgSCHUtlInitUeANFdbkInfo */
7698 * @brief Handler to get UE related ACK NACK feedback information
7702 * Function : rgSCHUtlGetUeANFdbkInfo
7704 * It gets the UE related ACK NACK information based on
7705 * SFN and slot number.
7707 * @param[in] RgSchUeCb *ueCb
7708 * @param[in] CmLteTimingInfo *time
7709 * @return RgSchTddANInfo*
7712 RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo
7715 CmLteTimingInfo *timeInfo,
7719 RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(ueCb, timeInfo,servCellIdx)
7721 CmLteTimingInfo *timeInfo;
7722 uint8_t servCellIdx;
7727 for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
7729 if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
7730 (timeInfo->slot == ueCb->cellInfo[servCellIdx]->anInfo[idx].slot))
7732 return (&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
7737 } /* rgSCHUtlGetUeANFdbkInfo */
7740 * @brief To get downlink slot index
7744 * Function: rgSCHUtlGetDlSfIdx
7745 * Purpose: Gets downlink slot index based on SFN and slot no
7747 * @param[in] CmLteTimingInfo *timeInfo
7748 * @param[in] RgSchCellCb *cell
7753 uint8_t rgSCHUtlGetDlSfIdx
7756 CmLteTimingInfo *timeInfo
7759 uint8_t rgSCHUtlGetDlSfIdx(cell, timeInfo)
7761 CmLteTimingInfo *timeInfo;
7766 idx = RGSCH_NUM_SUB_FRAMES - \
7767 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
7768 idx = ((idx * timeInfo->sfn) + \
7769 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->slot]) - 1;
7770 idx = idx % cell->numDlSubfrms;
7772 return ((uint8_t)idx);
7776 * @brief To get the next downlink slot
7780 * Function: rgSCHUtlGetNxtDlSfInfo
7781 * Purpose: Gets next downlink slot based on current DL slot
7783 * @param[in] CmLteTimingInfo curDlTime
7784 * @param[in] RgSchCellCb *cell
7785 * @param[in] RgSchDlSf *dlSf
7786 * @param[in] RgSchDlSf **nxtDlsf
7787 * @param[in] CmLteTimingInfo *nxtDlTime
7792 Void rgSCHUtlGetNxtDlSfInfo
7794 CmLteTimingInfo curDlTime,
7797 RgSchDlSf **nxtDlsf,
7798 CmLteTimingInfo *nxtDlTime
7801 Void rgSCHUtlGetNxtDlSfInfo(curDlTime, cell, dlSf, nxtDlsf, nxtDlTime)
7802 CmLteTimingInfo curDlTime;
7805 RgSchDlSf **nxtDlsf;
7806 CmLteTimingInfo *nxtDlTime;
7809 uint16_t idx = curDlTime.slot;
7816 idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
7818 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
7819 != RG_SCH_TDD_DL_slot);
7820 RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
7821 *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
7822 if(dlSf->dlFdbkInfo.slot != (*nxtDlsf)->dlFdbkInfo.slot)
7831 * @brief To get the previous downlink slot
7835 * Function: rgSCHUtlGetPrevDlSfInfo
7836 * Purpose: Gets previous downlink slot based on current DL slot
7838 * @param[in] RgSchCellCb *cell
7839 * @param[in] CmLteTimingInfo curDlTime
7840 * @param[in] CmLteTimingInfo *prevDlTime
7841 * @param[in] uint8_t *numSubfrm
7846 Void rgSCHUtlGetPrevDlSfInfo
7849 CmLteTimingInfo curDlTime,
7850 CmLteTimingInfo *prevDlTime,
7854 Void rgSCHUtlGetPrevDlSfInfo(cell, curDlTime, prevDlTime, numSubfrm)
7856 CmLteTimingInfo curDlTime;
7857 CmLteTimingInfo *prevDlTime;
7861 S16 idx = curDlTime.slot;
7869 idx = RGSCH_NUM_SUB_FRAMES-1;
7872 }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
7873 != RG_SCH_TDD_DL_slot);
7875 RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
7880 /* Added Holes Management functions for Adaptive Re transmission */
7881 /******* </AllocHolesMemMgmnt>: START *****/
7882 /***********************************************************
7884 * Func : rgSCHUtlUlSfInit
7886 * Desc : UL slot init.
7894 **********************************************************/
7896 S16 rgSCHUtlUlSfInit
7904 S16 rgSCHUtlUlSfInit(cell, sf, idx, maxUePerSf)
7919 if(cell->ulDlCfgIdx == 0)
7921 /* Store the Uplink slot number corresponding to the idx */
7922 sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6];
7925 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
7926 sizeof(RgSchUlAllocDb));
7931 ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
7934 /* ccpu00117052 - MOD - Passing double pointer
7935 for proper NULLP assignment*/
7936 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
7937 sizeof(RgSchUlAllocDb));
7940 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
7941 sizeof(RgSchUlHoleDb));
7944 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
7945 /* ccpu00117052 - MOD - Passing double pointer
7946 for proper NULLP assignment*/
7947 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
7948 sizeof(RgSchUlAllocDb));
7951 /* Initialize the hole with CFI 1 Pusch Bw Info */
7952 ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (uint8_t)(maxUePerSf + 2), \
7953 0, cell->dynCfiCb.bwInfo[1].numSb);
7957 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
7958 /* ccpu00117052 - MOD - Passing double pointer
7959 for proper NULLP assignment*/
7960 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
7961 sizeof(RgSchUlAllocDb));
7962 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
7963 sizeof(RgSchUlHoleDb));
7966 cmLListInit(&sf->reTxLst);
7968 /* Fix ccpu00120610*/
7969 sf->allocCountRef = &sf->allocDb->count;
7971 /* initialize UL available subbands for current sub-frame */
7972 sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
7974 sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
7975 sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
7976 for(index = 0; index < MAX_5GTF_BEAMS; index++)
7978 sf->sfBeamInfo[index].totVrbgAllocated = 0;
7979 sf->sfBeamInfo[index].totVrbgRequired = 0;
7980 sf->sfBeamInfo[index].vrbgStart = 0;
7988 /***********************************************************
7990 * Func : rgSCHUtlUlSfDeinit
7992 * Desc : Deinitialises a slot
8000 **********************************************************/
8002 Void rgSCHUtlUlSfDeinit
8008 Void rgSCHUtlUlSfDeinit(cell, sf)
8015 rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
8016 /* ccpu00117052 - MOD - Passing double pointer
8017 for proper NULLP assignment*/
8018 /* ccpu00117052 - MOD - Passing double pointer
8019 for proper NULLP assignment*/
8020 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
8021 sizeof(RgSchUlAllocDb));
8025 rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
8026 /* ccpu00117052 - MOD - Passing double pointer
8027 for proper NULLP assignment*/
8028 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
8029 sizeof(RgSchUlHoleDb));
8034 /***********************************************************
8036 * Func : rgSCHUtlUlAllocDbInit
8038 * Desc : Initialise allocation DB
8040 * Ret : S16 (ROK/RFAILED)
8046 **********************************************************/
8048 static S16 rgSCHUtlUlAllocDbInit
8051 RgSchUlAllocDb *allocDb,
8055 static S16 rgSCHUtlUlAllocDbInit(cell, allocDb, maxAllocs)
8057 RgSchUlAllocDb *allocDb;
8061 S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
8067 allocDb->first = NULLP;
8071 /***********************************************************
8073 * Func : rgSCHUtlUlAllocDbDeinit
8075 * Desc : Deinitialises allocation DB
8076 * sent to UE, for a UE with accumulation disabled
8084 **********************************************************/
8086 static Void rgSCHUtlUlAllocDbDeinit
8089 RgSchUlAllocDb *allocDb
8092 static Void rgSCHUtlUlAllocDbDeinit(cell, allocDb)
8094 RgSchUlAllocDb *allocDb;
8097 rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
8099 allocDb->first = NULLP;
8103 /***********************************************************
8105 * Func : rgSCHUtlUlHoleDbInit
8107 * Desc : Initialise hole DB
8109 * Ret : S16 (ROK/RFAILED)
8115 **********************************************************/
8117 static S16 rgSCHUtlUlHoleDbInit
8120 RgSchUlHoleDb *holeDb,
8126 static S16 rgSCHUtlUlHoleDbInit(cell, holeDb, maxHoles, start, num)
8128 RgSchUlHoleDb *holeDb;
8135 RgSchUlHole *hole = NULLP;
8137 ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
8143 holeDb->first = hole;
8144 hole->start = start;
8146 hole->prv = hole->nxt = NULLP;
8150 /***********************************************************
8152 * Func : rgSCHUtlUlHoleDbDeinit
8154 * Desc : Deinitialises hole DB
8162 **********************************************************/
8164 static Void rgSCHUtlUlHoleDbDeinit
8167 RgSchUlHoleDb *holeDb
8170 static Void rgSCHUtlUlHoleDbDeinit(cell, holeDb)
8172 RgSchUlHoleDb *holeDb;
8175 rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
8177 holeDb->first = NULLP;
8182 /***********************************************************
8184 * Func : rgSCHUtlUlAllocGetHole
8186 * Desc : Get allocation from hole
8188 * Ret : RgSchUlAlloc *
8194 **********************************************************/
8196 RgSchUlAlloc *rgSCHUtlUlAllocGetHole
8203 RgSchUlAlloc *rgSCHUtlUlAllocGetHole(sf, numSb, hole)
8209 if (numSb < hole->num)
8211 return (rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
8215 return (rgSCHUtlUlAllocGetCompHole(sf, hole));
8220 /***********************************************************
8222 * Func : rgSCHUtlUlAllocGetCompHole
8224 * Desc : Get an allocation corresponding to an entire hole
8226 * Ret : RgSchUlAlloc *
8232 **********************************************************/
8234 RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole
8240 RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(sf, hole)
8245 RgSchUlAlloc *alloc;
8246 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8247 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8248 * updated, causing another check for prv */
8249 RgSchUlAlloc *prv = hole->prvAlloc;
8250 RgSchUlAlloc *nxt = hole->nxtAlloc;
8254 if (hole->start == prv->nxtHole->start)
8256 prv->nxtHole = NULLP;
8258 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8262 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8265 RGSCH_NULL_CHECK( 0, alloc);
8266 alloc->prvHole = NULLP;
8267 alloc->nxtHole = NULLP;
8269 alloc->sbStart = hole->start;
8270 alloc->numSb = hole->num;
8274 nxt->prvHole = NULLP;
8277 rgSCHUtlUlHoleRls(sf->holeDb, hole);
8279 /* UL_ALLOC_CHANGES*/
8280 alloc->allocDbRef = (void*)sf->allocDb;
8281 alloc->holeDbRef = (void*)sf->holeDb;
8285 /***********************************************************
8287 * Func : rgSCHUtlUlAllocGetPartHole
8289 * Desc : Get an allocation corresponding to a part of a hole.
8290 * The initial 'numSb' part of the hole shall be taken
8291 * away for this alloc.
8293 * Ret : RgSchUlAlloc *
8299 **********************************************************/
8301 RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole
8308 RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(sf, numSb, hole)
8314 RgSchUlAlloc *alloc;
8315 /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
8316 /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
8317 * updated, causing another check for prv */
8318 RgSchUlAlloc *prv = hole->prvAlloc;
8322 if (hole->start == prv->nxtHole->start)
8324 prv->nxtHole = NULLP;
8326 alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
8330 alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
8333 RGSCH_NULL_CHECK( 0, alloc);
8334 alloc->prvHole = NULLP;
8335 alloc->nxtHole = hole;
8336 hole->prvAlloc = alloc;
8338 alloc->sbStart = hole->start;
8339 alloc->numSb = numSb;
8340 hole->start += numSb;
8343 rgSCHUtlUlHoleDecr(sf->holeDb, hole);
8345 /* UL_ALLOC_CHANGES*/
8346 alloc->allocDbRef = (void*)sf->allocDb;
8347 alloc->holeDbRef = (void*)sf->holeDb;
8352 /***********************************************************
8354 * Func : rgSCHUtlUlAllocFirst
8356 * Desc : Get first alloc in slot
8358 * Ret : RgSchUlAlloc *
8364 **********************************************************/
8366 RgSchUlAlloc *rgSCHUtlUlAllocFirst
8371 RgSchUlAlloc *rgSCHUtlUlAllocFirst(sf)
8375 return (sf->allocDb->first);
8378 /***********************************************************
8380 * Func : rgSCHUtlUlAllocNxt
8382 * Desc : Get next alloc
8384 * Ret : RgSchUlAlloc *
8390 **********************************************************/
8392 RgSchUlAlloc *rgSCHUtlUlAllocNxt
8398 RgSchUlAlloc *rgSCHUtlUlAllocNxt(sf, alloc)
8400 RgSchUlAlloc *alloc;
8404 return (alloc->nxt);
8407 /***********************************************************
8409 * Func : rgSCHUtlUlAllocGetAdjNxt
8411 * Desc : Get alloc which is immediately after the passed one.
8412 * 1. Gets alloc from mem.
8413 * 2. Inserts alloc into list (between prv and
8414 * prv->nxt, prv is not NULLP).
8415 * 3. Increments alloc count.
8416 * Note 1: Holes are not dealt with here.
8417 * Note 2: Assumes prv to be NULL.
8419 * Ret : RgSchUlAlloc *
8425 **********************************************************/
8427 RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt
8433 RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(db, prv)
8438 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8439 RgSchUlAlloc *nxt = prv->nxt;
8441 #if (ERRCLASS & ERRCLS_DEBUG)
8442 if ( alloc == NULLP )
8460 /***********************************************************
8462 * Func : rgSCHUtlUlAllocGetFirst
8464 * Desc : Get alloc which is to be the first one in the alloc list
8465 * 1. Gets alloc from mem.
8466 * 2. Inserts alloc as first element into list.
8467 * 3. Increments alloc count.
8468 * Note 1: Holes are not dealt with here.
8469 * Note 2: prv to necessarily NULLP.
8471 * Ret : RgSchUlAlloc *
8477 **********************************************************/
8479 RgSchUlAlloc *rgSCHUtlUlAllocGetFirst
8484 RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(db)
8488 RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
8489 RgSchUlAlloc *nxt = db->first;
8491 #if (ERRCLASS & ERRCLS_DEBUG)
8492 if ( alloc == NULLP )
8511 /* UL_ALLOC_ENHANCEMENT */
8512 /***********************************************************
8514 * Func : rgSCHUtlUlHoleAddAllocation
8516 * Desc : On freeing an alloc, add to hole
8524 **********************************************************/
8526 Void rgSCHUtlUlHoleAddAllocation
8531 Void rgSCHUtlUlHoleAddAllocation(alloc)
8532 RgSchUlAlloc *alloc;
8535 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8536 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8537 * The excessive branching is meant to utilise the knowledge of whether prv
8538 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8539 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8540 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8541 RgSchUlHoleDb *db = alloc->holeDbRef;
8542 RgSchUlHole *prv = alloc->prvHole;
8543 RgSchUlHole *nxt = alloc->nxtHole;
8549 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8552 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8558 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8561 rgSCHUtlUlHoleNew(db, alloc);
8567 /***********************************************************
8569 * Func : rgSCHUtlUlAllocRelease
8571 * Desc : Releases an uplink allocation, only take alloc ptr
8579 **********************************************************/
8581 Void rgSCHUtlUlAllocRelease
8586 Void rgSCHUtlUlAllocRelease(alloc)
8587 RgSchUlAlloc *alloc;
8590 RgSchUlAllocDb *allocDb = alloc->allocDbRef;
8591 RgSchUlAlloc *prv = alloc->prv;
8592 RgSchUlAlloc *nxt = alloc->nxt;
8595 alloc->raCb = NULLP;
8596 alloc->isAdaptive = FALSE;
8601 if (nxt) /* general case: this allocation lies btw two */
8608 allocDb->first = nxt;
8615 rgSCHUtlUlHoleAddAllocation(alloc);
8616 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8622 /***********************************************************
8624 * Func : rgSCHUtlUlAllocRls
8626 * Desc : Releases an uplink allocation
8634 **********************************************************/
8636 Void rgSCHUtlUlAllocRls
8642 Void rgSCHUtlUlAllocRls(sf, alloc)
8644 RgSchUlAlloc *alloc;
8647 RgSchUlAllocDb *allocDb = sf->allocDb;
8648 RgSchUlAlloc *prv = alloc->prv;
8649 RgSchUlAlloc *nxt = alloc->nxt;
8652 alloc->raCb = NULLP;
8653 alloc->isAdaptive = FALSE;
8660 if (nxt) /* general case: this allocation lies btw two */
8667 allocDb->first = nxt;
8674 rgSCHUtlUlHoleAddAlloc(sf, alloc);
8675 rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
8680 printf("\nError: allocDb->count is ZERO ====\n");
8683 //printf("\nallocDb->count:%u\n",allocDb->count);
8688 /***********************************************************
8690 * Func : rgSCHUtlUlHoleFirst
8692 * Desc : Get first (largest) hole
8694 * Ret : RgSchUlHole *
8700 **********************************************************/
8702 RgSchUlHole *rgSCHUtlUlHoleFirst
8707 RgSchUlHole *rgSCHUtlUlHoleFirst(sf)
8711 return (sf->holeDb->first);
8714 /***********************************************************
8716 * Func : rgSCHUtlUlHoleNxt
8718 * Desc : Get next largest hole
8720 * Ret : RgSchUlHole *
8726 **********************************************************/
8728 RgSchUlHole *rgSCHUtlUlHoleNxt
8734 RgSchUlHole *rgSCHUtlUlHoleNxt(sf, hole)
8743 /***********************************************************
8745 * Func : rgSCHUtlUlHoleAddAlloc
8747 * Desc : On freeing an alloc, add to hole
8755 **********************************************************/
8757 Void rgSCHUtlUlHoleAddAlloc
8763 Void rgSCHUtlUlHoleAddAlloc(sf, alloc)
8765 RgSchUlAlloc *alloc;
8768 /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
8769 * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
8770 * The excessive branching is meant to utilise the knowledge of whether prv
8771 * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
8772 * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
8773 * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
8774 RgSchUlHoleDb *db = sf->holeDb;
8775 RgSchUlHole *prv = alloc->prvHole;
8776 RgSchUlHole *nxt = alloc->nxtHole;
8782 rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
8785 rgSCHUtlUlHoleExtndRight(db, prv, alloc);
8791 rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
8794 rgSCHUtlUlHoleNew(db, alloc);
8797 /* increment the number of subbands getting freed to total available list */
8798 sf->availSubbands += alloc->numSb;
8803 /***********************************************************
8805 * Func : rgSCHUtlUlHoleJoin
8807 * Desc : Join two holes (due to alloc being deleted)
8815 **********************************************************/
8817 Void rgSCHUtlUlHoleJoin
8825 Void rgSCHUtlUlHoleJoin(db, prv, nxt, alloc)
8829 RgSchUlAlloc *alloc;
8832 prv->num += alloc->numSb + nxt->num;
8833 rgSCHUtlUlHoleRls(db, nxt);
8834 rgSCHUtlUlHoleIncr(db, prv);
8835 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
8840 /***********************************************************
8842 * Func : rgSCHUtlUlHoleExtndRight
8844 * Desc : Extend hole due to alloc coming 'after' the hole
8853 **********************************************************/
8855 Void rgSCHUtlUlHoleExtndRight
8862 Void rgSCHUtlUlHoleExtndRight(db, prv, alloc)
8865 RgSchUlAlloc *alloc;
8868 prv->num += alloc->numSb;
8869 rgSCHUtlUlHoleIncr(db, prv);
8870 rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
8874 /***********************************************************
8876 * Func : rgSCHUtlUlHoleExtndLeft
8878 * Desc : Extend hole due to alloc coming 'before' the hole
8887 **********************************************************/
8889 Void rgSCHUtlUlHoleExtndLeft
8896 Void rgSCHUtlUlHoleExtndLeft(db, nxt, alloc)
8899 RgSchUlAlloc *alloc;
8902 nxt->num += alloc->numSb;
8903 nxt->start = alloc->sbStart;
8904 rgSCHUtlUlHoleIncr(db, nxt);
8905 rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
8909 /***********************************************************
8911 * Func : rgSCHUtlUlHoleNew
8913 * Desc : Create new hole due to alloc being deleted
8921 **********************************************************/
8923 Void rgSCHUtlUlHoleNew
8929 Void rgSCHUtlUlHoleNew(db, alloc)
8931 RgSchUlAlloc *alloc;
8934 RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
8935 #if (ERRCLASS & ERRCLS_DEBUG)
8936 if ( hole == NULLP )
8941 hole->start = alloc->sbStart;
8942 hole->num = alloc->numSb;
8944 rgSCHUtlUlHoleIns(db, hole);
8945 rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
8949 /***********************************************************
8951 * Func : rgSCHUtlUlHoleUpdAllocLnks
8953 * Desc : Update alloc links in hole
8961 **********************************************************/
8963 Void rgSCHUtlUlHoleUpdAllocLnks
8966 RgSchUlAlloc *prvAlloc,
8967 RgSchUlAlloc *nxtAlloc
8970 Void rgSCHUtlUlHoleUpdAllocLnks(hole, prvAlloc, nxtAlloc)
8972 RgSchUlAlloc *prvAlloc;
8973 RgSchUlAlloc *nxtAlloc;
8978 prvAlloc->nxtHole = hole;
8982 nxtAlloc->prvHole = hole;
8984 hole->prvAlloc = prvAlloc;
8985 hole->nxtAlloc = nxtAlloc;
8990 /***********************************************************
8992 * Func : rgSCHUtlUlHoleIns
8994 * Desc : Insert (newly created) hole in sorted list of holes.
8995 * Searches linearly, beginning with the largest hole.
9003 **********************************************************/
9005 Void rgSCHUtlUlHoleIns
9011 Void rgSCHUtlUlHoleIns(db, hole)
9018 if ((cur = db->first) != NULLP)
9021 if (cur->num < hole->num)
9031 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9033 if (nxt->num < hole->num)
9035 /* Insert hole: cur <-> hole <-> nxt */
9051 /* This is the first hole */
9053 hole->prv = NULLP; /* may not be needed */
9059 /***********************************************************
9061 * Func : rgSCHUtlUlHoleIncr
9063 * Desc : hole->num has increeased, reposition in sorted
9072 **********************************************************/
9074 Void rgSCHUtlUlHoleIncr
9080 Void rgSCHUtlUlHoleIncr(db, hole)
9087 if ((cur = hole->prv) != NULLP)
9091 if (cur->num > hole->num)
9096 /* Remove hole from current position */
9097 cur->nxt = hole->nxt;
9100 hole->nxt->prv = cur;
9103 for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
9105 if (prv->num > hole->num)
9107 /* Insert hole: prv <-> hole <-> cur */
9126 /***********************************************************
9128 * Func : rgSCHUtlUlHoleDecr
9130 * Desc : hole->num has decreeased, reposition in sorted
9139 **********************************************************/
9141 Void rgSCHUtlUlHoleDecr
9147 Void rgSCHUtlUlHoleDecr(db, hole)
9154 if ((cur = hole->nxt) != NULLP)
9158 if (cur->num < hole->num)
9163 /* Remove hole from current position */
9164 cur->prv = hole->prv;
9167 hole->prv->nxt = cur;
9169 else /* no prv, so cur to replace hole as first in list */
9174 for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
9176 if (nxt->num < hole->num)
9178 /* Insert hole: cur <-> hole <-> nxt */
9196 /***********************************************************
9198 * Func : rgSCHUtlUlHoleRls
9200 * Desc : Releases hole.
9201 * 1. Decrements hole count.
9202 * 2. Deletes hole from list.
9203 * 3. Frees hole (hole memory release).
9211 **********************************************************/
9213 Void rgSCHUtlUlHoleRls
9219 Void rgSCHUtlUlHoleRls(db, hole)
9224 RgSchUlHole *prv = hole->prv;
9225 RgSchUlHole *nxt = hole->nxt;
9245 rgSCHUtlUlHoleMemRls(&db->mem, hole);
9250 /***********************************************************
9252 * Func : rgSCHUtlUlAllocMemInit
9254 * Desc : Initialises alloc free pool
9256 * Ret : S16 (ROK/RFAILED)
9262 **********************************************************/
9264 S16 rgSCHUtlUlAllocMemInit
9267 RgSchUlAllocMem *mem,
9271 S16 rgSCHUtlUlAllocMemInit(cell, mem, maxAllocs)
9273 RgSchUlAllocMem *mem;
9278 RgSchUlAlloc *allocs;
9280 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
9281 maxAllocs * sizeof(*allocs));
9286 mem->allocs = allocs;
9287 mem->maxAllocs = maxAllocs;
9288 if (mem->maxAllocs == 1)
9290 allocs[0].prv = NULLP;
9291 allocs[0].nxt = NULLP;
9296 allocs[0].prv = NULLP;
9297 allocs[0].nxt = &allocs[1];
9298 for (i = 1; i < mem->maxAllocs - 1; ++i)
9300 allocs[i].prv = &allocs[i-1];
9301 allocs[i].nxt = &allocs[i+1];
9303 allocs[i].prv = &allocs[i-1];
9304 allocs[i].nxt = NULLP;
9306 mem->firstFree = &allocs[0];
9310 /***********************************************************
9312 * Func : rgSCHUtlUlAllocMemDeinit
9314 * Desc : Deinitialises alloc free pool
9322 **********************************************************/
9324 Void rgSCHUtlUlAllocMemDeinit
9327 RgSchUlAllocMem *mem
9330 Void rgSCHUtlUlAllocMemDeinit(cell, mem)
9332 RgSchUlAllocMem *mem;
9335 /* ccpu00117052 - MOD - Passing double pointer
9336 for proper NULLP assignment*/
9337 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
9338 mem->maxAllocs * sizeof(*mem->allocs));
9340 mem->firstFree = NULLP;
9344 /***********************************************************
9346 * Func : rgSCHUtlUlHoleMemInit
9348 * Desc : Initialises hole free pool. Assumes maxHoles
9351 * Ret : S16 (ROK/RFAILED)
9357 **********************************************************/
9359 S16 rgSCHUtlUlHoleMemInit
9362 RgSchUlHoleMem *mem,
9364 RgSchUlHole **holeRef
9367 S16 rgSCHUtlUlHoleMemInit(cell, mem, maxHoles, holeRef)
9369 RgSchUlHoleMem *mem;
9371 RgSchUlHole **holeRef;
9377 ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
9378 maxHoles * sizeof(*holes));
9385 mem->maxHoles = maxHoles;
9387 /* first hole is taken up */
9388 holes[0].prv = NULLP; /* not needed */
9389 holes[0].nxt = NULLP; /* not needed */
9390 *holeRef = &holes[0];
9392 if (mem->maxHoles == 2)
9394 holes[1].prv = NULLP; /* may not be needed */
9395 holes[1].nxt = NULLP; /* may not be needed */
9400 holes[1].prv = NULLP;
9401 holes[0].nxt = &holes[1];
9402 for (i = 1; i < mem->maxHoles - 1; ++i)
9404 holes[i].prv = &holes[i-1];
9405 holes[i].nxt = &holes[i+1];
9407 holes[i].prv = &holes[i-1];
9408 holes[i].nxt = NULLP;
9410 mem->firstFree = &holes[1];
9415 /***********************************************************
9417 * Func : rgSCHUtlUlHoleMemDeinit
9419 * Desc : Deinitialises hole free pool
9427 **********************************************************/
9429 Void rgSCHUtlUlHoleMemDeinit
9435 Void rgSCHUtlUlHoleMemDeinit(cell, mem)
9437 RgSchUlHoleMem *mem;
9440 /* ccpu00117052 - MOD - Passing double pointer
9441 for proper NULLP assignment*/
9442 rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
9443 mem->maxHoles * sizeof(*mem->holes));
9445 mem->firstFree = NULLP;
9449 /***********************************************************
9451 * Func : rgSCHUtlUlAllocMemGet
9453 * Desc : Gets an 'alloc' from the free pool
9455 * Ret : RgSchUlAlloc *
9461 **********************************************************/
9463 RgSchUlAlloc *rgSCHUtlUlAllocMemGet
9465 RgSchUlAllocMem *mem
9468 RgSchUlAlloc *rgSCHUtlUlAllocMemGet(mem)
9469 RgSchUlAllocMem *mem;
9472 RgSchUlAlloc *alloc;
9474 #if (ERRCLASS & ERRCLS_DEBUG)
9475 if (mem->firstFree == NULLP)
9481 alloc = mem->firstFree;
9482 mem->firstFree = alloc->nxt;
9483 alloc->nxt = NULLP; /* probably not needed */
9484 /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
9489 /***********************************************************
9491 * Func : rgSCHUtlUlAllocMemRls
9493 * Desc : Returns an 'alloc' to the free pool
9501 **********************************************************/
9503 Void rgSCHUtlUlAllocMemRls
9505 RgSchUlAllocMem *mem,
9509 Void rgSCHUtlUlAllocMemRls(mem, alloc)
9510 RgSchUlAllocMem *mem;
9511 RgSchUlAlloc *alloc;
9516 alloc->nxt = mem->firstFree;
9517 if (mem->firstFree != NULLP)
9519 mem->firstFree->prv = alloc;
9521 mem->firstFree = alloc;
9525 /***********************************************************
9527 * Func : rgSCHUtlUlHoleMemGet
9529 * Desc : Gets a 'hole' from the free pool
9531 * Ret : RgSchUlHole *
9537 **********************************************************/
9539 RgSchUlHole *rgSCHUtlUlHoleMemGet
9544 RgSchUlHole *rgSCHUtlUlHoleMemGet(mem)
9545 RgSchUlHoleMem *mem;
9550 #if (ERRCLASS & ERRCLS_DEBUG)
9551 if (mem->firstFree == NULLP)
9557 hole = mem->firstFree;
9558 mem->firstFree = hole->nxt;
9559 mem->firstFree->prv = NULLP; /* may not be needed, under error class */
9560 hole->nxt = NULLP; /* probably not needed */
9561 /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
9566 /***********************************************************
9568 * Func : rgSCHUtlUlHoleMemRls
9570 * Desc : Returns a 'hole' to the free pool
9578 **********************************************************/
9580 Void rgSCHUtlUlHoleMemRls
9582 RgSchUlHoleMem *mem,
9586 Void rgSCHUtlUlHoleMemRls(mem, hole)
9587 RgSchUlHoleMem *mem;
9593 hole->nxt = mem->firstFree;
9594 if (mem->firstFree != NULLP)
9596 mem->firstFree->prv = hole;
9598 mem->firstFree = hole;
9603 * @brief Get an alloc from the specified position in the BW.
9607 * Function : rgSCHUtlUlGetSpfcAlloc
9609 * - Return an alloc from the specified position in the BW.
9610 * Note: This function assumes there is always a hole
9611 * Existing which completely has the specified
9612 * allocation. The reason for such an assumption is
9613 * the function's usage as of now guarantees that there
9614 * will always be such hole. And also for efficiency.
9616 * @param[in] RgSchUlSf *sf
9617 * @param[in] uint8_t startSb
9618 * @param[in] uint8_t numSb
9619 * @return RgSchUlAlloc*
9622 RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc
9629 RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(sf, startSb, numSb)
9635 RgSchUlHole *hole, *nxtHole;
9636 RgSchUlAlloc *alloc = NULLP;
9638 if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
9644 nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
9645 if ((startSb >= hole->start) &&
9646 (startSb+numSb <= hole->start+hole->num))
9648 if (startSb != hole->start)
9650 /* Create a new hole to accomodate Subbands between
9651 * hole start and req alloc start */
9652 RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
9654 #if (ERRCLASS & ERRCLS_DEBUG)
9655 if ( newHole == NULLP )
9660 newHole->start = hole->start;
9661 newHole->num = startSb - hole->start;
9662 hole->start = startSb;
9663 /* [ccpu00122847]-MOD- Correctly updating the hole->num */
9664 hole->num -= newHole->num;
9665 ++(sf->holeDb->count);
9666 rgSCHUtlUlHoleIns(sf->holeDb, newHole);
9667 newHole->prvAlloc = hole->prvAlloc;
9668 if (newHole->prvAlloc)
9670 newHole->prvAlloc->nxtHole = newHole;
9672 if (numSb == hole->num)
9674 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9678 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9680 alloc->prvHole = newHole;
9681 newHole->nxtAlloc = alloc;
9683 else /* Hole start and req alloc start are same */
9685 if (numSb == hole->num)
9687 alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
9691 alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
9696 } while ((hole = nxtHole) != NULLP);
9701 * @brief Validates the qci values
9705 * Function :rgSCHUtlValidateQci
9707 * @param[in] RgSchCellCb *cellCb
9708 * @param[in] uint8_t numQci
9709 * @param[out] uint8_t *qci
9715 static S16 rgSCHUtlValidateQci
9717 RgSchCellCb *cellCb,
9722 static S16 rgSCHUtlValidateQci(cellCb, numQci, qci)
9723 RgSchCellCb *cellCb;
9732 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
9734 qciVal = qci[qciIdx];
9735 if(qciVal == 0 || qciVal > 9)
9739 if(qciVal != cellCb->qciArray[qciVal].qci)
9746 }/* rgSCHUtlValidateQci */
9748 * @brief Validates the measurement request parameters.
9752 * Function :rgSCHUtlValidateMeasReq
9754 * @param[in] RgSchCellCb *cellCb
9755 * @param[in] LrgSchMeasReqInfo *schL2MeasInfo
9756 * @param[out] RgSchErrInfo *err
9757 * @return RgSchUlAlloc*
9760 S16 rgSCHUtlValidateMeasReq
9762 RgSchCellCb *cellCb,
9763 LrgSchMeasReqInfo *schL2MeasInfo,
9767 S16 rgSCHUtlValidateMeasReq(cellCb, schL2MeasInfo, err)
9768 RgSchCellCb *cellCb;
9769 LrgSchMeasReqInfo *schL2MeasInfo;
9777 measType = schL2MeasInfo->measType;
9779 if((measType == 0) ||
9782 err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
9783 err->errCause = RGSCHERR_SCH_L2MEAS;
9786 if((schL2MeasInfo->timePrd !=0) &&
9787 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
9788 ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
9789 (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
9791 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9792 err->errCause = RGSCHERR_SCH_L2MEAS;
9795 if((schL2MeasInfo->timePrd !=0) &&
9796 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
9797 (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ))
9799 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9800 err->errCause = RGSCHERR_SCH_L2MEAS;
9803 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
9804 ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
9805 (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
9806 ((schL2MeasInfo->timePrd !=0)&&
9807 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
9808 (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
9810 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9811 err->errCause = RGSCHERR_SCH_L2MEAS;
9814 if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
9815 ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
9816 (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
9817 ((schL2MeasInfo->timePrd !=0) &&
9818 (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
9819 (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
9821 err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
9822 err->errCause = RGSCHERR_SCH_L2MEAS;
9825 if((schL2MeasInfo->timePrd !=0) &&
9826 (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
9828 RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci, \
9829 (schL2MeasInfo->avgPrbQciDl.numQci));
9830 ret = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
9831 schL2MeasInfo->avgPrbQciDl.qci);
9834 err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
9835 err->errCause = RGSCHERR_SCH_L2MEAS;
9840 }/* rgSCHUtlValidateMeasReq */
9841 #endif /* LTE_L2_MEAS */
9842 /******* </AllocHolesMemMgmnt>: END *****/
9845 * @brief API for sending SI configuration confirm from Scheduler to RRM
9849 * Function: rgSCHUtlRgrSiCfgCfm
9851 * This API is invoked to send SI configuration confirm from Scheduler
9853 * This API fills in Pst structure and SAP Ids and invokes
9854 * config confirm API towards RRM.
9856 * @param[in] RgrCfgTransId transId
9857 * @param[in] uint8_t status
9863 S16 rgSCHUtlRgrSiCfgCfm
9867 RgrCfgTransId transId,
9871 S16 rgSCHUtlRgrSiCfgCfm(instId, spId, transId, status)
9874 RgrCfgTransId transId;
9878 uint8_t prntTrans[RGR_CFG_TRANSID_SIZE+1];
9881 memcpy(prntTrans, transId.trans, RGR_CFG_TRANSID_SIZE);
9882 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
9885 if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
9886 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
9887 transId, status) != ROK)
9889 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
9890 "RgUiRgrSiCfgCfm Failed ");
9895 } /* rgSCHUtlRgrSiCfgCfm */
9899 * @brief API for sending Warning SI configuration confirm from
9905 * This API is invoked to send Warning SI configuration confirm
9906 * from Scheduler to RRM.
9907 * This API fills in Pst structure and SAP Ids and invokes
9908 * config confirm API towards RRM.
9910 * @param[in] RgrCfgTransId transId
9911 * @param[in] uint8_t status
9917 S16 rgSCHUtlRgrWarningSiCfgCfm
9922 RgrCfgTransId transId,
9926 S16 rgSCHUtlRgrWarningSiCfgCfm(instId, spId, siId, transId, status)
9930 RgrCfgTransId transId;
9934 uint8_t prntTrans[RGR_CFG_TRANSID_SIZE+1];
9937 memcpy(prntTrans, transId.trans, RGR_CFG_TRANSID_SIZE);
9938 prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
9941 if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
9942 rgSchCb[instId].rgrSap[spId].sapCfg.suId,
9943 transId, siId, status) != ROK)
9945 RLOG_ARG0(L_ERROR,DBG_INSTID,instId,"rgSCHUtlRgrSiCfgCfm: "
9946 "RgUiRgrSiCfgCfm Failed ");
9951 } /* rgSCHUtlRgrWarningSiCfgCfm */
9953 /***********************************************************
9955 * Func : rgSCHUtlPutSiInfo
9957 * Desc : Utility Function to deallocate SI information
9965 **********************************************************/
9967 Void rgSCHUtlPutSiInfo
9972 Void rgSCHUtlPutSiInfo(cell)
9977 uint32_t sizeOfSiInfo = 0;
9978 /*Free the buffers in crntSiInfo*/
9979 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
9980 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
9982 sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
9984 for(idx=0; idx < sizeOfSiInfo; idx++)
9986 RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
9989 /*Free the buffers in newSiInfo */
9990 RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
9991 RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
9993 sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
9995 for(idx=0; idx < sizeOfSiInfo; idx++)
9997 RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
10002 #endif /*RGR_SI_SCH */
10006 /***********************************************************
10008 * Func : rgSCHUtlGetDrxSchdUesInDl
10010 * Desc : Utility Function to fill the get the list of
10011 * scheduled UEs. On these UE's, drx-inactivity
10012 * timer will be started/restarted.
10021 **********************************************************/
10023 S16 rgSCHUtlGetDrxSchdUesInDl
10025 RgSchCellCb *cellCb,
10027 RgSchDlHqProcCb *dlHq,
10028 RgInfUeAlloc *allocInfo,
10029 CmLListCp *dlDrxInactvTmrLst,
10030 CmLListCp *dlInActvLst,
10031 CmLListCp *ulInActvLst
10034 S16 rgSCHUtlGetDrxSchdUesInDl(cellCb, ueCb, dlHq, allocInfo, dlDrxInactvTmrLst, dlInActvLst, ulInActvLst)
10035 RgSchCellCb *cellCb;
10037 RgSchDlHqProcCb *dlHq;
10038 RgInfUeAlloc *allocInfo;
10039 CmLListCp *dlDrxInactvTmrLst;
10040 CmLListCp *dlInActvLst;
10041 CmLListCp *ulInActvLst;
10044 Bool isNewTx = FALSE;
10046 RgSchDrxDlHqProcCb *drxHq;
10047 RgSchDRXCellCb *drxCell = cellCb->drxCb;
10048 RgSchDrxUeCb *drxUe;
10050 Inst inst = cellCb->instIdx;
10052 uint8_t cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
10053 uint32_t dlInactvMask;
10054 uint32_t ulInactvMask;
10056 for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
10058 if(allocInfo->tbInfo[idx].isReTx == FALSE)
10061 /* Removing break here, since in 2 TB case if 2nd TB is proceeding with
10062 retx then drxretx timer should be stopped.*/
10066 /*Stop the DRX retransmission timer as UE scheduled for retx. Here
10067 * we stop the timer and inactivate the UE for both UL and DL.
10068 * This may result in loss of one slot for UL but this trade
10069 * off is taken to avoid the overhead of maintaining a list of UEs
10070 * to be inactivated in the next slot.*/
10071 drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
10072 drxUe = RG_SCH_DRX_GET_UE(ueCb);
10073 if(drxHq->reTxIndx != DRX_INVALID)
10075 /* This condition should never occur */
10076 if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
10078 RGSCHDBGERRNEW(inst,(rgSchPBuf(inst),"[%d]UE:DRXUE RETX IDX[%d]"
10079 "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
10080 drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId));
10083 drxUe->drxDlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10084 drxUe->drxUlInactvMaskPerCell[cellIdx] |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
10086 dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10087 ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
10089 for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
10091 dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
10092 ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
10095 drxUe->drxDlInactvMask |= dlInactvMask;
10096 drxUe->drxUlInactvMask |= ulInactvMask;
10098 /* if no other condition is keeping ue active,
10099 * inactivate the Ue
10101 if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
10103 /* BUG 2 : HARQ_RTT, changed for consistency */
10104 ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
10106 /* Add to DL inactive list */
10107 cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
10108 ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
10111 if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
10113 /*BUG 2: HARQ_RTT changed for consistency */
10114 ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
10116 cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
10117 ueCb->ulDrxInactvLnk.node = (PTR)ueCb;
10120 /* Deleting entry from HARQ RTT queue for the same HARQ proc,
10121 * if exist. This is the special case which can happen iF UL
10122 * scheduling is done later. */
10123 if(drxHq->rttIndx != DRX_INVALID)
10125 cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
10126 &(drxHq->harqRTTEnt));
10128 drxHq->rttIndx = DRX_INVALID;
10131 cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
10132 &(drxHq->harqRetxEnt));
10133 drxHq->reTxIndx = DRX_INVALID;
10138 if(isNewTx == TRUE)
10140 if(ueCb->drxCb->raRcvd == TRUE)
10142 ueCb->drxCb->raRcvd = FALSE;
10144 /* mark the ra bit */
10145 ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10146 ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
10148 }/*if(ra->rcvd) == TRUE */
10150 if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
10152 cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
10153 ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
10155 }/*if(isNewTx == TRUE) */
10158 }/* rgSCHUtlGetSchdUes*/
10160 /* ccpu00117452 - MOD - Changed macro name from
10161 RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
10162 #ifdef RGR_CQI_REPT
10164 * @brief This function fills StaInd struct
10168 * Function: rgSCHUtlFillSndStaInd
10169 * Purpose: Fills StaInd struct and sends the
10172 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10173 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10174 * @param[in] RgrStaIndInfo *staInfo Sta Ind struct to be filled
10175 * @param[in] uint8_t numCqiRept NUmber of reports to be filled
10180 S16 rgSCHUtlFillSndStaInd
10184 RgrStaIndInfo *staInfo,
10188 S16 rgSCHUtlFillSndStaInd(cell, ue, staInfo, numCqiRept)
10191 RgrStaIndInfo *staInfo;
10192 uint8_t numCqiRept;
10197 /* Fill StaInd for sending collated Latest N CQI rpeorts */
10198 /* Find index in the array from where Latest N
10199 reports needs to be fetched. Use this value to index in the array
10200 and copy the reports into staInfo */
10202 /* Fill the Cell Id of PCC of the UE */
10203 staInfo->cellId = ue->cell->cellId;
10204 staInfo->crnti = ue->ueId;
10206 idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
10208 memcpy (&(staInfo->ueCqiInfo.cqiRept),
10209 &(ue->schCqiInfo.cqiRept[idxStart]),
10210 numCqiRept * sizeof(RgrUeCqiRept));
10212 staInfo->ueCqiInfo.numCqiRept = numCqiRept;
10214 ue->schCqiInfo.cqiCount = 0;
10216 /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
10217 if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
10219 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10220 "CQI reports for RNTI:%d",ue->ueId);
10226 }/* End of rgSCHUtlFillSndStaInd */
10231 * @brief API for sending STA indication from Scheduler to RRM.
10235 * Function: rgSCHUtlRgrStaInd
10237 * This API is invoked to send STA indication from Scheduler instance to RRM.
10238 * This API fills in Pst structure and RgrStaIndInfo
10239 * and calls the Sta primitive API towards RRM.
10241 * @param[in] cell RgSchCellCb
10242 * @param[in] RgrStsIndInfo *rgrSta
10248 S16 rgSCHUtlRgrStaInd
10251 RgrStaIndInfo *rgrSta
10254 S16 rgSCHUtlRgrStaInd(cell, rgrSta)
10256 RgrStaIndInfo *rgrSta;
10260 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10264 rgrSap = cell->rgrSap;
10265 if (rgrSap->sapSta.sapState != LRG_BND)
10267 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10268 "rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
10269 rgrSap->sapSta.sapState);
10272 RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
10273 cell->rgrSap->sapCfg.suId, rgrSta);
10275 } /* rgSCHUtlRgrStaInd*/
10276 #endif /* End of RGR_CQI_REPT */
10278 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
10280 * @brief Indicates MAC to release any rnti context it has.
10283 * Function : rgSCHUtlIndRntiRls2Mac
10284 * This function indicates MAC for this rnti release.
10285 * In case of ueId change it will indicate MAC
10286 * about the new rnti to be updated.
10287 * It will post a release RNTI indication to MAC.
10291 * @param[in] RgSchCellCb *cell
10292 * @param[in] CmLteRnti rnti
10293 * @param[in] Bool ueIdChng
10294 * @param[in] CmLteRnti newRnti
10299 Void rgSCHUtlIndRntiRls2Mac
10307 Void rgSCHUtlIndRntiRls2Mac(cell, rnti, ueIdChng, newRnti)
10315 Inst inst = cell->instIdx;
10316 RgInfRlsRnti rntiInfo;
10319 /* Copy the info to rntiInfo */
10320 rntiInfo.cellId = cell->cellId;
10321 rntiInfo.rnti = rnti;
10322 /* Fix : syed ueId change as part of reestablishment.
10323 * Now SCH to trigger this. CRG ueRecfg for ueId change
10325 rntiInfo.ueIdChng = ueIdChng;
10326 rntiInfo.newRnti = newRnti;
10328 rntiInfo.isUeSCellDel = FALSE;
10330 /* Invoke MAC to release the rnti */
10331 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
10332 RgSchMacRlsRnti(&pst, &rntiInfo);
10336 /* LTE_ADV_FLAG_REMOVED_START */
10338 * @brief API for sending LOAD INF indication from Scheduler to RRM.
10341 * Function: rgSCHUtlRgrLoadInfInd
10343 * This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
10344 * This API fills in Pst structure and RgrLoadInfIndInfo
10345 * and calls the Sta primitive API towards RRM.
10347 * @param[in] cell RgSchCellCb
10348 * @param[in] RgrLoadInfIndInfo *rgrLoadInf
10354 S16 rgSCHUtlRgrLoadInfInd
10357 RgrLoadInfIndInfo *rgrLoadInf
10360 S16 rgSCHUtlRgrLoadInfInd(cell, rgrLoadInf)
10362 RgrLoadInfIndInfo *rgrLoadInf;
10366 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10368 rgrSap = cell->rgrSap;
10369 if (rgrSap->sapSta.sapState != LRG_BND)
10371 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10372 "rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
10373 rgrSap->sapSta.sapState);
10376 RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
10377 cell->rgrSap->sapCfg.suId, rgrLoadInf);
10379 } /* rgSCHUtlRgrLoadInfInd*/
10380 /* LTE_ADV_FLAG_REMOVED_END */
10382 /* MS_FIX : syed SCH to act as MASTER in maintaining
10383 * rnti related context. Trigger to rnti del/Chng at SCH
10384 * will result in a Indication to MAC to release its
10385 * RNTI context. MAC inturn indicates the context cleared
10386 * indication to SCH, upon which SCH would set this
10388 * @brief API for sending STA indication from Scheduler to RRM.
10392 * Function: rgSCHUtlRlsRnti
10394 * This API is invoked to indicate MAC to release rnti
10396 * @param[in] RgSchCellCb *cellCb
10397 * @param[in] RgSchRntiLnk *rntiLnk,
10398 * @param[in] Bool ueIdChngd,
10399 * @param[in] CmLteRnti newRnti
10404 Void rgSCHUtlRlsRnti
10407 RgSchRntiLnk *rntiLnk,
10412 Void rgSCHUtlRlsRnti(cell, rntiLnk, ueIdChngd, newRnti)
10414 RgSchRntiLnk *rntiLnk;
10420 uint8_t isLegacy = 0;
10422 if(cell->emtcEnable)
10424 rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
10429 /*Add to Guard Pool*/
10430 cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
10431 rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
10433 /* Fix: syed Explicitly Inidcate MAC to release RNTI */
10434 rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
10441 * @brief This function fills StaInd struct
10445 * Function: rgSCHUtlFillSndUeStaInd
10446 * Purpose: Fills StaInd struct and sends the
10449 * @param[in] RgSchCellCb *cell pointer to Cell Control block
10450 * @param[in] RgSchUeCb *ue pointer to Ue Control block
10451 * @param[in] uint8_t numCqiRept NUmber of reports to be filled
10456 S16 rgSCHUtlFillSndUeStaInd
10460 RgrUeStaIndInfo *ueStaInfo
10463 S16 rgSCHUtlFillSndUeStaInd(cell, ue, ueStaInfo)
10466 RgrUeStaIndInfo *ueStaInfo;
10470 ueStaInfo->cellId = cell->cellId;
10471 ueStaInfo->crnti = ue->ueId;
10473 /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
10474 if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
10476 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Could not send "
10477 "UE Sta reports CRNTI:%d",ue->ueId);
10483 }/* End of rgSCHUtlFillSndStaInd */
10488 * @brief API for sending STA indication from Scheduler to RRM.
10492 * Function: rgSCHUtlRgrStaInd
10494 * This API is invoked to send STA indication from Scheduler instance to RRM.
10495 * This API fills in Pst structure and RgrStaIndInfo
10496 * and calls the Sta primitive API towards RRM.
10498 * @param[in] cell RgSchCellCb
10499 * @param[in] RgrStsIndInfo *rgrSta
10505 S16 rgSCHUtlRgrUeStaInd
10508 RgrUeStaIndInfo *rgrUeSta
10511 S16 rgSCHUtlRgrUeStaInd(cell, rgrUeSta)
10513 RgrUeStaIndInfo *rgrUeSta;
10517 RgSchUpSapCb *rgrSap; /*!< RGR SAP Control Block */
10519 rgrSap = cell->rgrSap;
10520 if (rgrSap->sapSta.sapState != LRG_BND)
10522 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,
10523 "rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
10524 rgrSap->sapSta.sapState);
10527 RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
10528 cell->rgrSap->sapCfg.suId, rgrUeSta);
10530 } /* rgSCHUtlRgrStaInd*/
10534 * @brief function to report DL and UL PRB usage to RRM.
10537 * Function: rgSCHUtlUpdAvgPrbUsage
10538 * This function sends the PRB usage report to
10539 * RRM with the interval configured by RRM.
10541 * @param[in] cell *RgSchCellCb
10547 S16 rgSCHUtlUpdAvgPrbUsage
10552 S16 rgSCHUtlUpdAvgPrbUsage(cell)
10556 CmLteTimingInfo frm;
10557 RgmPrbRprtInd *prbRprtInd;
10560 #ifdef DBG_MAC_RRM_PRB_PRINT
10561 static uint32_t count = 0;
10562 const uint32_t reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
10567 frm = cell->crntTime;
10568 RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
10574 if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
10576 /* Get the total number of DL and UL slots within the reporting period*/
10577 numDlSf = (cell->prbUsage.rprtPeriod *
10578 rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10579 / RGSCH_NUM_SUB_FRAMES;
10580 numUlSf = (cell->prbUsage.rprtPeriod *
10581 rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
10582 / RGSCH_NUM_SUB_FRAMES;
10586 /* Get the total number of DL and UL slots < 10 ms interval */
10587 numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10588 numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
10591 numDlSf = cell->prbUsage.rprtPeriod;
10592 numUlSf = cell->prbUsage.rprtPeriod;
10595 if(SGetSBuf(cell->rgmSap->sapCfg.sapPst.region,
10596 cell->rgmSap->sapCfg.sapPst.pool, (Data**)&prbRprtInd,
10597 sizeof(RgmPrbRprtInd)) != ROK)
10602 memset(&prbRprtInd->stQciPrbRpts[0],
10604 (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
10606 prbRprtInd->bCellId = cell->cellId;
10610 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL;
10611 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10613 prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage =
10614 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
10615 (numDlSf * cell->bwCfg.dlTotalBw));
10616 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10617 cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
10623 prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL;
10624 for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
10626 prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage =
10627 RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
10628 (numUlSf * cell->ulAvailBw));
10629 prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
10630 cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
10634 #ifdef DBG_MAC_RRM_PRB_PRINT
10635 if((count % reprotForEvery20Sec) == 0 )
10637 printf("\n====================================================================");
10638 printf("\nMAC: QCI-1[DL:UL] | QCI-2[DL:UL] | QCI-3[DL:UL] | QCI-4[DL:UL] \n");
10639 printf("======================================================================\n");
10640 printf(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n",
10641 prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
10642 prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
10643 prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
10644 prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
10645 prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
10646 prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
10647 prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
10648 prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
10651 RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst),
10652 cell->rgmSap->sapCfg.suId, prbRprtInd);
10660 * @brief This function resends the Ta in case of
10661 * max retx failure or DTX for the Ta transmitted
10665 * Function: rgSCHUtlReTxTa
10668 * @param[in] RgSchCellCb *cell
10669 * @param[in] RgSchUeCb *ue
10674 Void rgSCHUtlReTxTa
10676 RgSchCellCb *cellCb,
10680 Void rgSCHUtlReTxTa(cellCb, ueCb)
10681 RgSchCellCb *cellCb;
10686 /* If TA Timer is running. Stop it */
10687 if (ueCb->taTmr.tmrEvnt != TMR_NONE)
10689 rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
10691 /*[ccpu00121813]-ADD-If maxretx is reached then
10692 * use outstanding TA val for scheduling again */
10693 if(ueCb->dl.taCb.outStndngTa == TRUE)
10695 ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
10696 ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
10697 ueCb->dl.taCb.outStndngTa = FALSE;
10700 /* Fix : syed TA state updation missing */
10701 ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
10702 rgSCHUtlDlTARpt(cellCb, ueCb);
10707 /* Added function for dropping Paging Message*/
10709 * @brief Handler for BO Updt received for BCCH or PCCH.
10713 * Function : rgSCHChkBoUpdate
10715 * This function shall check for BO received falls within the scheduling window or not
10718 * @param[in] RgSchCellCb *cell
10724 static S16 rgSCHChkBoUpdate
10727 RgInfCmnBoRpt *boUpdt
10730 static S16 rgSCHChkBoUpdate (cell, boUpdt)
10732 RgInfCmnBoRpt *boUpdt;
10736 uint32_t crntTimeInSubFrms = 0;
10737 uint32_t boUpdTimeInSubFrms = 0;
10738 uint32_t distance = 0;
10740 crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) + cell->crntTime.slot +
10741 RG_SCH_CMN_DL_DELTA + 2; /* As bo received will scheduled in next TTI
10742 so incrementing with +1 more */
10743 boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.slot;
10746 distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
10747 boUpdTimeInSubFrms - crntTimeInSubFrms : \
10748 (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
10750 if (distance > RGSCH_PCCHBCCH_WIN)
10756 }/*rgSCHChkBoUpdate*/
10761 * @brief Utility function to calculate the UL reTxIdx in TDD cfg0
10765 * Function : rgSchUtlCfg0ReTxIdx
10767 * Update the reTxIdx according to the rules mentioned
10768 * in 3GPP TS 36.213 section 8 for TDD Cfg0
10770 * @param[in] RgSchCellCb *cell
10771 * @param[in] CmLteTimingInfo phichTime
10772 * @param[in] uint8_t hqFdbkIdx
10776 uint8_t rgSchUtlCfg0ReTxIdx
10779 CmLteTimingInfo phichTime,
10783 uint8_t rgSchUtlCfg0ReTxIdx (cell, phichTime, hqFdbkIdx)
10785 CmLteTimingInfo phichTime;
10789 uint8_t reTxIdx = RGSCH_INVALID_INFO;
10790 uint8_t iPhich = 0;
10791 RgSchCmnUlCell *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
10793 uint8_t ulSF; /* UL SF in the TDD frame */
10795 ulSf = &cellUl->ulSfArr[hqFdbkIdx];
10796 ulSF = ulSf->ulSfIdx;
10798 /* Check for the UL SF 4 or 9 */
10799 if(ulSF == 9 || ulSF == 4)
10803 if(phichTime.slot == 0 || phichTime.slot == 5)
10807 /* Retx will happen according to the Pusch k table */
10808 reTxIdx = cellUl->schdIdx;
10812 /* Retx will happen at n+7 */
10813 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
10814 /* Fetch the corresponding UL slot Idx in UL sf array */
10815 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
10818 else if(phichTime.slot == 1 || phichTime.slot == 6)
10820 /* Retx will happen at n+7 */
10821 RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
10822 /* Fetch the corresponding UL slot Idx in UL sf array */
10823 reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
10830 * @brief Utility function to calculate total num of PRBs required to
10831 * satisfy DL BO for TM1/TM2/TM6/TM7
10835 * Function : rgSchUtlDlCalc1CwPrb
10837 * Calculate PRBs required for UE to satisfy BO in DL
10839 * Note : Total calculated PRBs will be assigned to *prbReqrd
10842 * @param[in] RgSchCellCb *cell
10843 * @param[in] RgSchUeCb *ue
10844 * @param[in] uint32_t bo
10845 * @param[out] uint32_t *prbReqrd
10849 Void rgSchUtlDlCalc1CwPrb
10857 Void rgSchUtlDlCalc1CwPrb(cell, ue, bo, prbReqrd)
10861 uint32_t *prbReqrd;
10864 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
10865 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
10869 uint8_t cfi = dlCell->currCfi;
10871 iTbs = dlUe->mimoInfo.cwInfo[0].iTbs[0];
10872 eff = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
10874 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
10875 * i.e, << 3 and multiply with 1024 i.e, << 10 */
10876 noRes = ((uint64_t)((bo << 3) << 10)) / (eff);
10877 /* Get the number of RBs needed for this transmission */
10878 /* Number of RBs = No of REs / No of REs per RB */
10879 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
10882 } /* rgSchUtlDlCalc1CwPrb*/
10885 * @brief Utility function to calculate total num of PRBs required to
10886 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
10891 * Function : rgSchUtlDlCalc2CwPrb
10893 * Calculate PRBs required for UE to satisfy BO in DL
10895 * Note : Total calculated PRBs will be assigned to *prbReqrd
10898 * @param[in] RgSchCellCb *cell
10899 * @param[in] RgSchUeCb *ue
10900 * @param[in] uint32_t bo
10901 * @param[out] uint32_t *prbReqrd
10905 Void rgSchUtlDlCalc2CwPrb
10913 Void rgSchUtlDlCalc2CwPrb(cell, ue, bo, prbReqrd)
10917 uint32_t *prbReqrd;
10920 RgSchCmnDlCell *dlCell = RG_SCH_CMN_GET_DL_CELL(cell);
10921 RgSchCmnDlUe *dlUe = RG_SCH_CMN_GET_DL_UE(ue, cell);
10922 uint32_t eff1, eff2;
10924 uint8_t noLyr1, noLyr2;
10925 uint8_t iTbs1, iTbs2;
10926 uint8_t cfi = dlCell->currCfi;
10928 if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
10929 (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
10931 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[0];
10932 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
10934 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
10935 * i.e, << 3 and multiply with 1024 i.e, << 10 */
10936 noRes = ((uint64_t)((bo << 3) << 10)) / (eff1);
10937 /* Get the number of RBs needed for this transmission */
10938 /* Number of RBs = No of REs / No of REs per RB */
10939 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
10943 noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
10944 noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
10945 iTbs1 = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
10946 iTbs2 = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
10947 eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
10948 eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
10950 /* Optimization to convert totalBo (which is in-terms of bytes) to bits
10951 * i.e, << 3 and multiply with 1024 i.e, << 10 */
10952 noRes = ((uint64_t)((bo << 3) << 10)) / (eff1 + eff2);
10953 /* Get the number of RBs needed for this transmission */
10954 /* Number of RBs = No of REs / No of REs per RB */
10955 *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
10958 } /* rgSchUtlDlCalc2CwPrb */
10961 * @brief Utility function to calculate total num of PRBs required to
10962 * satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
10966 * Function : rgSchUtlCalcTotalPrbReq
10968 * This function calls TM specific routine to calculate PRB
10971 * @param[in] RgSchCellCb *cell
10972 * @param[in] RgSchUeCb *ue
10973 * @param[in] uint32_t bo
10974 * @param[out] uint32_t *prbReqrd
10978 Void rgSchUtlCalcTotalPrbReq
10986 Void rgSchUtlCalcTotalPrbReq(cell, ue, bo, prbReqrd)
10990 uint32_t *prbReqrd;
10993 /* Call TM specific Prb calculation routine */
10994 (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
10997 } /* rgSchUtlCalcTotalPrbReq */
11000 /***********************************************************
11002 * Func : rgSCHUtlFetchPcqiBitSz
11005 * Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
11014 **********************************************************/
11016 static uint8_t rgSCHUtlFetchPcqiBitSz
11023 static uint8_t rgSCHUtlFetchPcqiBitSz (cell, ueCb, numTxAnt)
11029 uint8_t confRepMode;
11032 RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
11034 confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
11035 if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) &&
11036 (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
11042 ri = cqiCb->perRiVal;
11044 switch(confRepMode)
11046 case RGR_PRD_CQI_MOD10:
11052 case RGR_PRD_CQI_MOD11:
11065 else if(numTxAnt == 4)
11078 /* This is number of antenna case 1.
11079 * This is not applicable for Mode 1-1.
11080 * So setting it to invalid value */
11086 case RGR_PRD_CQI_MOD20:
11094 pcqiSz = 4 + cqiCb->label;
11099 case RGR_PRD_CQI_MOD21:
11114 else if(numTxAnt == 4)
11127 /* This might be number of antenna case 1.
11128 * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
11129 * So setting invalid value.*/
11137 pcqiSz = 4 + cqiCb->label;
11141 pcqiSz = 7 + cqiCb->label;
11157 * @brief Utility function to returns the number of subbands based on the
11162 * Function : rgSchUtlGetNumSbs
11164 * Calculate the number of PRBs
11165 * Update the subbandRequired based on the nPrbs and subband size
11167 * @param[in] RgSchCellCb *cell
11168 * @param[in] RgSchUeCb *ue
11169 * @param[in] uint32_t *numSbs
11173 uint8_t rgSchUtlGetNumSbs
11180 uint8_t rgSchUtlGetNumSbs (cell, ue, numSbs)
11187 //Currently hardcoding MAX prb for each UE
11188 nPrb = ue->ue5gtfCb.maxPrb;
11189 (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
11194 * @brief Utility function to insert the UE node into UE Lst based on the
11195 * number of subbands allocated for the UE for the current TTI.
11199 * Function : rgSchUtlSortInsUeLst
11201 * If subbandRequired < Min, then insert at head
11202 * Else If subbandRequired > Max, then insert at tail
11203 * Else, traverse the list and place the node at the appropriate place
11205 * @param[in] RgSchCellCb *cell
11206 * @param[in] RgSchUeCb *ue
11210 uint8_t rgSchUtlSortInsUeLst
11215 uint8_t vrbgRequired
11218 uint8_t rgSchUtlSortInsUeLst (cell, ueLst, node, vrbgRequired)
11222 uint8_t vrbgRequired;
11226 CmLList *firstUeInLst;
11227 CmLList *lastUeInLst;
11229 RgSchCmnUlUe *ueUl;
11231 //firstUeInLst = cmLListFirst(ueLst);
11232 CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
11233 if(NULLP == firstUeInLst)
11235 /* first node to be added to the list */
11236 cmLListAdd2Tail(ueLst, node);
11240 /* Sb Required for the UE is less than the first node in the list */
11241 tempUe = (RgSchUeCb *)(firstUeInLst->node);
11242 ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
11244 if(vrbgRequired <= ueUl->vrbgRequired)
11246 cmLListInsCrnt(ueLst, (node));
11250 /* Sb Required for this UE is higher than the UEs in the list */
11251 lastUeInLst = cmLListLast(ueLst);
11252 tempUe = (RgSchUeCb *)(lastUeInLst->node);
11253 if(vrbgRequired >= ueUl->vrbgRequired)
11255 cmLListAdd2Tail(ueLst, (node));
11259 /* This UE needs to be in the middle. Search and insert the UE */
11260 ueInLst = cmLListFirst(ueLst);
11263 tempUe = (RgSchUeCb *)(ueInLst->node);
11265 if(vrbgRequired <= ueUl->vrbgRequired)
11267 cmLListInsCrnt(ueLst, (node));
11271 ueInLst = cmLListNext(ueLst);
11273 } while(NULLP != ueInLst && ueInLst != firstUeInLst);
11282 * @brief Function to Send LCG GBR register to MAC
11286 * Function: rgSCHUtlBuildNSendLcgReg
11288 * Handler for sending LCG GBR registration
11293 * Processing Steps:
11295 * @param[in] RgSchCellCb *cell
11296 * @param[in] CmLteRnti crnti
11297 * @param[in] uint8_t lcgId
11298 * @param[in] Bool isGbr
11303 S16 rgSCHUtlBuildNSendLcgReg
11311 S16 rgSCHUtlBuildNSendLcgReg(cell, crnti, lcgId, isGbr)
11319 RgInfLcgRegReq lcgRegReq;
11321 memset(&pst, 0, sizeof(Pst));
11322 lcgRegReq.isGbr = isGbr;
11323 lcgRegReq.cellId = cell->cellId;
11324 lcgRegReq.crnti = crnti;
11325 lcgRegReq.lcgId = lcgId;
11326 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
11327 /* code Coverage portion of the test case */
11328 RgSchMacLcgReg(&pst, &lcgRegReq);
11337 * @brief Function to map RGR pucch type to TFU type
11341 * Function: rgSchUtlGetFdbkMode
11347 * Processing Steps:
11349 * @param[in] RgrSchFrmt1b3TypEnum
11350 * @return TfuAckNackMode
11354 TfuAckNackMode rgSchUtlGetFdbkMode
11356 RgrSchFrmt1b3TypEnum fdbkType
11359 TfuAckNackMode rgSchUtlGetFdbkMode(fdbkType)
11360 RgrSchFrmt1b3TypEnum fdbkType;
11364 TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
11368 case RG_SCH_UCI_FORMAT_NON_CA:
11369 case RG_SCH_UCI_FORMAT1A_1B:
11371 mode = TFU_UCI_FORMAT_1A_1B;
11374 case RG_SCH_UCI_FORMAT1B_CS:
11376 mode = TFU_UCI_FORMAT_1B_CS;
11379 case RG_SCH_UCI_FORMAT3:
11381 mode = TFU_UCI_FORMAT_3;
11387 #endif /* TFU_TDD */
11388 #endif /* LTE_ADV */
11389 #endif /*TFU_UPGRADE */
11393 * @brief Send Ue SCell delete to SMAC.
11397 * Function : rgSCHUtlSndUeSCellDel2Mac
11398 * This function populates the struct RgInfRlsRnti and
11399 * get the pst for SMac and mark field isUeSCellDel to TRUE which
11400 * indicates that it is a Ue SCell delete.
11404 * @param[in] RgSchCellCb *cell
11405 * @param[in] CmLteRnti rnti
11410 Void rgSCHUtlSndUeSCellDel2Mac
11416 Void rgSCHUtlSndUeSCellDel2Mac(cell, rnti)
11422 Inst inst = cell->instIdx;
11423 RgInfRlsRnti rntiInfo;
11425 RGSCHDBGINFONEW(inst,(rgSchPBuf(inst),"RNTI Release IND for UE(%d)\n", rnti));
11426 /* Copy the info to rntiInfo */
11427 rntiInfo.cellId = cell->cellId;
11428 rntiInfo.rnti = rnti;
11429 /* Fix : syed ueId change as part of reestablishment.
11430 * Now SCH to trigger this. CRG ueRecfg for ueId change
11432 rntiInfo.ueIdChng = FALSE;
11433 rntiInfo.newRnti = rnti;
11434 rntiInfo.isUeSCellDel = TRUE;
11435 /* Invoke MAC to release the rnti */
11436 rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
11437 RgSchMacRlsRnti(&pst, &rntiInfo);
11442 * @brief Returns max TB supported by a given txMode
11446 * Function : rgSCHUtlGetMaxTbSupp
11447 * Max TB supported for TM Modes (1,2,5,6 and 7) is 1
11451 * @param[in] RgrTxMode txMode
11452 * @return uint8_t maxTbCount;
11456 uint8_t rgSCHUtlGetMaxTbSupp
11461 uint8_t rgSCHUtlGetMaxTbSupp(txMode)
11465 uint8_t maxTbCount;
11489 return (maxTbCount);
11493 * @brief Send Ue SCell delete to SMAC.
11497 * Function : rgSCHTomUtlGetTrigSet
11498 * This function gets the triggerset based on cqiReq
11500 * @param[in] RgSchCellCb *cell
11501 * @param[in] RgSchUeCb ueCb
11502 * @param[in] uint8_t cqiReq,
11503 * @param[out] uint8_t *triggerSet
11509 Void rgSCHTomUtlGetTrigSet
11514 uint8_t *triggerSet
11517 static S16 rgSCHTomUtlGetTrigSet(cell, ueCb, cqiReq, triggerSet)
11521 uint8_t *triggerSet;
11524 RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
11527 case RG_SCH_APCQI_SERVING_CC:
11529 /* APeriodic CQI request for Current Carrier.*/
11530 uint8_t sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
11531 *triggerSet = 1 << (7 - sCellIdx);
11534 case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
11536 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
11539 case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
11541 *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
11554 * @brief This function updates the value of UE specific DCI sizes
11558 * Function: rgSCHUtlUpdUeDciSize
11559 * Purpose: This function calculates and updates DCI Sizes in bits.
11561 * Invoked by: Scheduler
11563 * @param[in] RgSchCellCb *cell
11564 * @param[in] RgSchUeCb *ueCb
11565 * @param[in] isCsi2Bit *isCsi2Bit: is 1 bit or 2 bit CSI
11570 Void rgSCHUtlUpdUeDciSize
11577 Void rgSCHUtlUpdUeDciSize(cell, ueCb, isCsi2Bit)
11583 uint8_t dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11584 uint8_t dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
11585 if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
11587 dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
11588 dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
11590 if (isCsi2Bit == TRUE)
11592 dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
11596 dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
11599 /* Common CSI is always 1 bit DCI 0 */
11600 dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
11602 /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
11603 if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11605 dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11607 if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11609 dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11612 /* 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 */
11613 dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
11614 dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
11616 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0] = dci01aCmnSize;
11617 ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
11619 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0] = dci01aDedSize;
11620 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
11622 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11624 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11625 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11626 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11627 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11628 if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
11630 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
11633 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11634 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11635 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11636 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11637 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
11638 } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
11640 /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
11641 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11642 ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11643 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2] = cell->dciSize.size[TFU_DCI_FORMAT_2];
11644 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
11646 /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource
11647 * on a secondary cell without an uplink configuration associated with the secondary cell */
11648 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11649 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
11650 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
11652 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled
11653 * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A
11654 * for scheduling the same serving cell and mapped onto the UE specific search space given by the
11655 * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
11656 if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
11658 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
11661 /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs
11662 * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended
11663 * to format 1 until the payload size of format 1 does not belong to one of the sizes in
11664 * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
11665 ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
11666 } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
11668 rgSCHEmtcUtlUpdUeDciSize(cell, ueCb);
11673 * @brief This function initialises the DCI Size table
11677 * Function: rgSCHUtlCalcDciSizes
11678 * Purpose: This function calculates and initialises DCI Sizes in bits.
11680 * Invoked by: Scheduler
11682 * @param[in] RgSchCellCb *cell
11687 Void rgSCHUtlCalcDciSizes
11692 Void rgSCHUtlCalcDciSizes(cell)
11696 uint8_t dciSize = 0;
11697 uint8_t dci01aSize = 0;
11698 uint32_t bits = 0, idx = 0;
11700 switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
11702 case TFU_DCI_FORMAT_0:
11704 /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
11706 /*-- Calculate resource block assignment bits need to be set
11707 Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
11708 bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
11709 while ((bits & 0x8000) == 0)
11716 dciSize = 1 /* DCI 0 bit indicator */ + \
11717 1 /* Frequency hoping enable bit field */ + \
11718 (uint8_t)bits /* For frequency Hopping */ + \
11725 2 /* UL Index Config 0 or DAI Config 1-6 */
11729 cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
11731 /* If hoping flag is enabled */
11732 if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
11734 cell->dciSize.dci0HopSize = 1;
11738 cell->dciSize.dci0HopSize = 2;
11741 /* Update common non-CRNTI scrambled DCI 0/1A flag */
11742 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
11744 case TFU_DCI_FORMAT_1A:
11746 /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
11749 /* Calculate resource block assignment bits need to be set
11750 Which is ln(N(N+1)/2) */
11751 bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
11752 while ((bits & 0x8000) == 0)
11759 dciSize += 1 /* Format 1A */ + \
11760 1 /* Local or Distributed */ + \
11761 (uint8_t)bits /* Resource block Assignment */ + \
11764 4 /* HARQ Proc Id */ +
11766 3 /* HARQ Proc Id */ +
11776 cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
11778 /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI,
11779 * and the number of information bits in format 1A is less than that of format 0,
11780 * zeros shall be appended to format 1A until the payload size equals that of format 0. */
11781 /* Compare the size with DCI 1A and DCI 0 and consider the greater one */
11782 if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
11784 dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
11786 /* If the number of information bits in format 1A belongs to one of the sizes in
11787 * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
11788 dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
11789 cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
11791 case TFU_DCI_FORMAT_1:
11793 /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
11795 if (cell->bwCfg.dlTotalBw > 10)
11797 dciSize = 1; /* Resource Allocation header bit */
11800 /* Resouce allocation bits Type 0 and Type 1 */
11801 bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
11802 if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
11807 dciSize += (uint8_t)bits /* Resource Allocation bits */ + \
11815 2 /* Redunancy Version */ + \
11824 cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
11826 cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
11829 /* If the UE is not configured to decode PDCCH with CRC
11830 * scrambled by the C-RNTI and the number of information bits in format 1
11831 * is equal to that for format 0/1A, one bit of value zero shall be appended
11833 if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
11835 cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
11838 /* If the number of information bits in format 1 belongs to one of the sizes in
11839 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until
11840 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1
11841 * and is not equal to that of format 0/1A mapped onto the same search space. */
11842 cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
11843 } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
11845 case TFU_DCI_FORMAT_2:
11847 /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
11849 if (cell->bwCfg.dlTotalBw > 10)
11851 dciSize = 1; /* Resource Allocation bit */
11854 dciSize += (uint8_t)bits /* Resource Allocation bits */ + \
11862 1 /* CW Swap Flag */ + \
11863 5 /* MCS for TB1 */+ \
11864 1 /* NDI for TB1 */+ \
11865 2 /* RV for TB1 */ + \
11866 5 /* MCS for TB2 */+ \
11867 1 /* NDI for TB2 */+ \
11868 2 /* RV for TB2 */;
11869 if (cell->numTxAntPorts == 2)
11873 else if (cell->numTxAntPorts == 4)
11877 cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
11878 cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
11880 case TFU_DCI_FORMAT_2A:
11882 /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
11884 if (cell->bwCfg.dlTotalBw > 10)
11886 dciSize = 1; /* Resource Allocation bit */
11889 dciSize += (uint8_t)bits /* Resource Allocation bits */ + \
11897 1 /* CW Swap Flag */ + \
11898 5 /* MCS for TB1 */+ \
11899 1 /* NDI for TB1 */+ \
11900 2 /* RV for TB1 */ + \
11901 5 /* MCS for TB2 */+ \
11902 1 /* NDI for TB2 */+ \
11903 2 /* RV for TB2 */;
11904 if (cell->numTxAntPorts == 4)
11908 cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
11909 cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
11910 rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
11912 case TFU_DCI_FORMAT_3:
11914 /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
11915 cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
11916 if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
11918 cell->dciSize.size[TFU_DCI_FORMAT_3]++;
11921 case TFU_DCI_FORMAT_3A:
11923 /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
11924 cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
11927 case TFU_DCI_FORMAT_6_0A:
11929 rgSCHEmtcGetDciFrmt60ASize(cell);
11931 case TFU_DCI_FORMAT_6_1A:
11933 rgSCHEmtcGetDciFrmt61ASize(cell);
11938 /* DCI format not supported */
11945 * @brief Handler for the CPU OvrLd related state adjustment.
11949 * Function : rgSCHUtlCpuOvrLdAdjItbsCap
11951 * Processing Steps:
11952 * - Record dl/ulTpts
11953 * - Adjust maxItbs to acheive target throughputs
11955 * @param[in] RgSchCellCb *cell
11959 Void rgSCHUtlCpuOvrLdAdjItbsCap
11964 Void rgSCHUtlCpuOvrLdAdjItbsCap(cell)
11970 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP |
11971 RGR_CPU_OVRLD_DL_TPT_DOWN))
11973 /* Regulate DL Tpt for CPU overload */
11974 if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
11976 tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
11977 /* Upto 0.5% drift in measured vs target tpt is ignored */
11978 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
11980 cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
11985 tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
11986 /* Upto 0.5% drift in measured vs target tpt is ignored */
11987 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
11989 cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
11992 #ifdef CPU_OL_DBG_PRINTS
11993 printf("\n DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt,
11994 cell->thresholds.maxDlItbs);
11998 if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP |
11999 RGR_CPU_OVRLD_UL_TPT_DOWN))
12001 /* Regualte DL Tpt for CPU overload */
12002 if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
12004 tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
12005 /* Upto 1% drift in measured vs target tpt is ignored */
12006 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12008 cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
12013 tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
12014 /* Upto 1% drift in measured vs target tpt is ignored */
12015 if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
12017 cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
12020 #ifdef CPU_OL_DBG_PRINTS
12021 printf("\n UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt,
12022 cell->thresholds.maxUlItbs);
12029 * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
12033 * Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12035 * Processing Steps:
12036 * - Validate the config params.
12037 * - Update numUEperTTi CPU OL related information.
12038 * - If successful, return ROK else RFAILED.
12040 * @param[in] RgSchCellCb *cell
12041 * @param[in] uint8_t cnrtCpuOvrLdIns
12045 static Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
12048 uint8_t crntCpuOvrLdIns
12051 static S16 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns)
12053 uint8_t crntCpuOvrLdIns;
12056 RgSchCpuOvrLdCntrlCb *cpuInstr = &(cell->cpuOvrLdCntrl);
12057 RgSchCmnCell *cellSch;
12058 uint8_t maxUeNewDlTxPerTti;
12059 uint8_t maxUeNewUlTxPerTti;
12060 uint8_t tmpslot = 0;
12061 #ifdef CPU_OL_DBG_PRINTS
12064 uint8_t maxDlDecCnt;
12065 uint8_t maxUlDecCnt;
12067 cellSch = RG_SCH_CMN_GET_CELL(cell);
12069 maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti;
12070 maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
12072 /* Calculate Maximum Decremen */
12073 maxDlDecCnt = (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12074 maxUlDecCnt = (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
12076 /* Check for DL CPU Commands */
12077 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI )
12079 /* Decrement till 90% of maxUeNewDlTxPerTti */
12080 if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
12082 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12083 cpuInstr->dlNxtIndxDecNumUeTti++;
12084 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] > 1 )
12086 cpuInstr->maxUeNewTxPerTti[tmpslot]--;
12090 #ifdef CPU_OL_DBG_PRINTS
12091 printf("CPU_OL_TTI__ERROR\n");
12093 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12096 #ifdef CPU_OL_DBG_PRINTS
12097 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12099 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12100 cpuInstr->dlNxtIndxDecNumUeTti);
12102 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
12104 if ( cpuInstr->dlNxtIndxDecNumUeTti > 0)
12106 cpuInstr->dlNxtIndxDecNumUeTti--;
12107 tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
12108 if ( cpuInstr->maxUeNewTxPerTti[tmpslot] < maxUeNewDlTxPerTti )
12110 cpuInstr->maxUeNewTxPerTti[tmpslot]++;
12114 #ifdef CPU_OL_DBG_PRINTS
12115 printf("CPU_OL_TTI__ERROR\n");
12117 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12120 #ifdef CPU_OL_DBG_PRINTS
12121 printf("dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
12123 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12124 cpuInstr->dlNxtIndxDecNumUeTti);
12126 /* Check for UL CPU commands */
12127 if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
12129 /* Decrement till 90% of maxUeNewDlTxPerTti */
12130 if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
12132 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12133 cpuInstr->ulNxtIndxDecNumUeTti++;
12134 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] > 1 )
12136 cpuInstr->maxUeNewRxPerTti[tmpslot]--;
12140 #ifdef CPU_OL_DBG_PRINTS
12141 printf("CPU_OL_TTI__ERROR\n");
12143 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12146 #ifdef CPU_OL_DBG_PRINTS
12147 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12149 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12150 cpuInstr->dlNxtIndxDecNumUeTti);
12152 else if ( crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
12154 if ( cpuInstr->ulNxtIndxDecNumUeTti > 0)
12156 cpuInstr->ulNxtIndxDecNumUeTti--;
12157 tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
12158 if ( cpuInstr->maxUeNewRxPerTti[tmpslot] < maxUeNewUlTxPerTti )
12160 cpuInstr->maxUeNewRxPerTti[tmpslot]++;
12164 #ifdef CPU_OL_DBG_PRINTS
12165 printf("CPU_OL_TTI__ERROR\n");
12167 RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Invalid CPU OL");
12170 #ifdef CPU_OL_DBG_PRINTS
12171 printf("ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
12173 RLOG_ARG1(L_DEBUG,DBG_CELLID,cell->cellId,"dlNxtIndxDecNumUeTti = %d",
12174 cpuInstr->dlNxtIndxDecNumUeTti);
12176 #ifdef CPU_OL_DBG_PRINTS
12177 /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
12178 printf("maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
12179 printf("DL Sf numUePerTti:");
12180 for ( idx = 0; idx < 10 ; idx ++ )
12182 printf(" %d", cpuInstr->maxUeNewTxPerTti[idx]);
12184 printf("\nUL Sf numUePerTti:");
12185 for ( idx = 0; idx < 10 ; idx ++ )
12187 printf(" %d", cpuInstr->maxUeNewRxPerTti[idx]);
12193 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
12196 * @brief Handler for the CPU OvrLd related cell Recfg.
12200 * Function : rgSCHUtlResetCpuOvrLdState
12202 * Processing Steps:
12203 * - Validate the config params.
12204 * - Update CPU OL related state information.
12205 * - If successful, return ROK else RFAILED.
12207 * @param[in] RgSchCellCb *cell
12208 * @param[in] uint8_t cnrtCpuOvrLdIns
12214 S16 rgSCHUtlResetCpuOvrLdState
12217 uint8_t crntCpuOvrLdIns
12220 S16 rgSCHUtlResetCpuOvrLdState(cell, crntCpuOvrLdIns)
12222 uint8_t crntCpuOvrLdIns;
12225 uint8_t crntDlCpuOL=0;
12226 uint8_t crntUlCpuOL=0;
12227 RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
12230 #ifdef CPU_OL_DBG_PRINTS
12231 printf("\n CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
12233 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"CPU OVR LD Ins Rcvd");
12235 if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
12237 /* The CPU OL instruction received with RESET (0), hence reset it */
12238 #ifdef CPU_OL_DBG_PRINTS
12239 printf("rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
12241 RLOG_ARG0(L_INFO,DBG_CELLID,cell->cellId,"RESET CPU OVR LD");
12242 cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
12243 /* Reset the max UL and DL itbs to 26 */
12244 cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
12245 cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
12246 /* Reset the num UE per TTI intructions */
12247 cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
12248 cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
12249 for ( idx = 0; idx < 10; idx++ )
12251 cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] =
12252 schCmnCell->dl.maxUeNewTxPerTti;
12253 cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] =
12254 schCmnCell->ul.maxUeNewTxPerTti;
12259 /* Check and Update numUEPer TTI based CPU overload instruction before
12260 * going for TP based CPU OL
12261 * TTI based intrcuctions shall be > 0xF */
12262 if ( crntCpuOvrLdIns > 0xF )
12264 rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
12265 /* If need to have both TP and numUePerTti instrcution together in
12266 * one command then dont return from here */
12270 crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
12271 (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
12272 if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) &&
12273 (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
12275 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12278 crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
12279 (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
12280 if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) &&
12281 (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
12283 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12286 if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
12288 /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
12292 cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
12296 if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
12298 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
12299 (cell->measurements.ulTpt * 3 )/100;
12303 cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
12304 (cell->measurements.ulTpt * 2 )/100;
12306 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD UL Reset to "
12307 "%d, %lu, %lu", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
12308 #ifdef CPU_OL_DBG_PRINTS
12309 printf("\n CPU OVR LD UL Reset to= %d, %lu, %lu\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
12310 cell->measurements.ulTpt);
12316 if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
12318 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
12319 (cell->measurements.dlTpt * 1 )/100;
12323 cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
12324 (cell->measurements.dlTpt * 1 )/100;
12326 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,"CPU OVR LD DL Reset to "
12327 "%d, %lu, %lu", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
12329 #ifdef CPU_OL_DBG_PRINTS
12330 printf("\n CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
12331 cell->measurements.dlTpt);
12334 rgSCHUtlCpuOvrLdAdjItbsCap(cell);
12338 S16 rgSCHUtlAddToResLst
12341 RgSchIotRes *iotRes
12344 cmLListAdd2Tail(cp, &iotRes->resLnk);
12345 iotRes->resLnk.node = (PTR)iotRes;
12348 S16 rgSCHUtlDelFrmResLst
12351 RgSchIotRes *iotRes
12354 CmLListCp *cp = NULLP;
12355 RgSchEmtcUeInfo *emtcUe = NULLP;
12356 emtcUe = RG_GET_EMTC_UE_CB(ue);
12357 if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
12359 cp = &emtcUe->ulResLst;
12360 }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
12362 cp = &emtcUe->dlResLst;
12365 RLOG0(L_INFO, "*****restype mismatch");
12371 RLOG0(L_INFO,"****error count*****\n");
12375 cmLListDelFrm(cp, &iotRes->resLnk);
12376 iotRes->resLnk.node = NULLP;
12380 /**********************************************************************
12383 **********************************************************************/