[Epic-ID: ODUHIGH-464][Task-ID: ODUHIGH-483] Memeory related fix in FDD and TDD mode
[o-du/l2.git] / src / 5gnrsch / rg_sch_utl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /************************************************************************
20
21      Name:     LTE-MAC layer
22
23      Type:     C source file
24
25      Desc:     C source code for Entry point fucntions
26
27      File:     rg_sch_utl.c
28
29 **********************************************************************/
30
31 /** @file rg_sch_utl.c
32 @brief This file implements the schedulers main access to MAC layer code.
33 */
34
35
36 /* header include files -- defines (.h) */
37 #include "common_def.h"
38 #include "lrg.h"
39 #include "rgr.h"
40 #include "tfu.h"
41 #include "sch_utils.h"
42 #include "rg_env.h"
43 #include "rg_sch_err.h"
44 #include "rg_sch_inf.h"
45 #include "rg_sch.h"
46 #include "rg_sch_cmn.h"
47 #include "rgm.h"
48
49 /* header/extern include files (.x) */
50 #include "tfu.x"           /* TFU types */
51 #include "lrg.x"           /* layer management typedefs for MAC */
52 #include "rgr.x"           /* layer management typedefs for MAC */
53 #include "rgm.x"
54 #include "rg_sch_inf.x"         /* typedefs for Scheduler */
55 #include "rg_sch.x"        /* typedefs for Scheduler */
56 #include "rg_sch_cmn.x"        /* typedefs for Scheduler */
57 #ifdef EMTC_ENABLE
58 #include "rg_sch_emtc_ext.x"
59 #endif
60
61
62 /* SR_RACH_STATS */
63 uint32_t rgNumPrachRecvd =0;       /* Num of Rach Req received including dedicated preambles */
64 uint32_t rgNumRarSched =0;         /* Num of RARs sent */
65 uint32_t rgNumBI =0;               /* Num of BackOff Ind sent */
66 uint32_t rgNumMsg3CrcPassed =0;    /* Num of CRC success for Msg3 */
67 uint32_t rgNumMsg3CrcFailed =0;    /* Num of CRC fail for Msg 3 */
68 uint32_t rgNumMsg3FailMaxRetx =0;  /* Num of Msg3 fail after Max Retx attempts */
69 uint32_t rgNumMsg4Ack =0;          /* Num of Acks for Msg4 Tx */
70 uint32_t rgNumMsg4Nack =0; 
71        /* Num of Nacks for Msg4 Tx */
72 uint32_t rgNumMsg4FailMaxRetx =0;  /* Num of Msg4 Tx failed after Max Retx attempts */
73 uint32_t rgNumSrRecvd =0;          /* Num of Sched Req received */
74 uint32_t rgNumSrGrant =0;          /* Num of Sched Req Grants sent */
75 uint32_t rgNumMsg3CrntiCE =0;      /* Num of Msg 3 CRNTI CE received */
76 uint32_t rgNumDedPream =0;         /* Num of Dedicated Preambles recvd */
77 uint32_t rgNumMsg3CCCHSdu =0;      /* Num of Msg 3 CCCH Sdus recvd */
78 uint32_t rgNumCCCHSduCrntiNotFound =0;  /*UE Ctx not found for CCCH SDU Msg 3 */
79 uint32_t rgNumCrntiCeCrntiNotFound =0;  /*UE Ctx not found for CRNTI CE Msg 3 */
80 uint32_t rgNumMsg4WithCCCHSdu =0;       /* Num of Msg4 with CCCH Sdu */
81 uint32_t rgNumMsg4WoCCCHSdu =0;         /* Num of Msg4 without CCCH Sdu */
82 uint32_t rgNumMsg4Dtx =0;               /* Num of DTX received for Msg 4 */
83 uint32_t rgNumMsg3AckSent =0;           /* Num of PHICH Ack sent for Msg 3 */
84 uint32_t rgNumMsg3NackSent =0;          /* Num of PHICH Nack sent for Msg 3 */
85 uint32_t rgNumMsg4PdcchWithCrnti =0;    /* Num of PDCCH for CRNTI based contention resolution */
86 uint32_t rgNumRarFailDuetoRntiExhaustion =0; /* Num of RACH Failures due to RNTI pool exhaution */
87 uint32_t rgNumTAModified =0;            /* Num of times TA received is different from prev value */
88 uint32_t rgNumTASent =0;               /* Num of TA Command sent */
89 uint32_t rgNumMsg4ToBeTx =0;           /* Num of times MSG4 that should be sent */
90 uint32_t rgNumMsg4Txed =0;             /* Num of MSG4 actually sent *//* ysNumMsg4ToBeTx -ysNumMsg4Txed == Failed MSG4 TX */
91 uint32_t rgNumMsg3DtxRcvd  =0;         /* CRC Fail with SINR < 0 */
92
93 uint32_t rgNumDedPreamUECtxtFound =0;         /* Num of Dedicated Preambles recvd */
94
95 static uint8_t rgSchDciAmbigSizeTbl[61] = {0,0,0,0,0,0,0,0,0,0,0,
96                          0,1,0,1,0,1,0,0,0,1,
97                          0,0,0,1,0,1,0,0,0,0,
98                          0,1,0,0,0,0,0,0,0,1,
99                          0,0,0,1,0,0,0,0,0,0,
100                          0,0,0,0,0,1,0,0,0,0};
101
102 /* local defines */
103
104 uint32_t rgSchCmnBetaCqiOffstTbl[16];
105 uint32_t rgSchCmnBetaRiOffstTbl[16]; 
106 RgSchdApis rgSchCmnApis;
107 S16 RgUiRgmSendPrbRprtInd ARGS((
108 Pst* pst, 
109 SuId suId, 
110 RgmPrbRprtInd *prbRprtInd
111 ));
112
113 S16 RgUiRgmSendTmModeChangeInd ARGS((
114 Pst* pst, 
115 SuId suId, 
116 RgmTransModeInd *txModeChngInd
117 ));
118 #ifdef EMTC_ENABLE
119 S16 rgSCHEmtcUtlGetSfAlloc ARGS((
120 RgSchCellCb *cell
121 ));
122 S16 rgSCHEmtcUtlPutSfAlloc ARGS((
123 RgSchCellCb *cell
124 ));
125 Void rgSCHEmtcUtlUpdUeDciSize ARGS((
126 RgSchCellCb *cell,
127 RgSchUeCb *ueCb
128 ));
129 Void rgSCHEmtcGetDciFrmt61ASize ARGS((
130 RgSchCellCb *cell
131 ));
132 Void rgSCHEmtcGetDciFrmt60ASize ARGS((
133 RgSchCellCb *cell
134 ));
135 S16 rgSCHEmtcUtlFillPdschDciInfo ARGS((
136 TfuPdschDciInfo *pdsch,
137 TfuDciInfo      *pdcchDci
138 ));
139 Void rgSCHEmtcUtlRlsRnti ARGS((
140 RgSchCellCb *cell,
141 RgSchRntiLnk   *rntiLnk,
142 uint8_t             *isLegacy
143 ));
144 S16 rgSCHEmtcPdcchAlloc ARGS((
145 RgSchCellCb *cell,
146 RgSchPdcch  *pdcch
147 ));
148 Void rgSCHEmtcPdcchFree ARGS((
149 RgSchCellCb *cell,
150 RgSchPdcch  *pdcch
151 ));
152 #endif
153 /* Functions specific to TM1/TM2/TM6/TM7 for PRB calculation*/
154 Void rgSchUtlDlCalc1CwPrb ARGS(( RgSchCellCb    *cell,
155                                         RgSchUeCb      *ue,
156                                         uint32_t             bo,
157                                         uint32_t            *prbReqrd));
158
159 /* Functions specific to TM3/TM4 for PRB calculation*/
160 Void rgSchUtlDlCalc2CwPrb ARGS(( RgSchCellCb    *cell,
161                                         RgSchUeCb      *ue,
162                                         uint32_t             bo,
163                                         uint32_t            *prbReqrd));
164
165 #ifdef LTE_ADV
166 RgSchCellCb* rgSchUtlGetCellCb ARGS(( Inst       inst,
167                                              uint16_t        cellId
168 ));
169 #endif
170
171 typedef Void (*RgSchUtlDlCalcPrbFunc) ARGS((RgSchCellCb *cell, RgSchUeCb *ue,
172                                             uint32_t bo, uint32_t *prbRequrd));
173 #ifndef LTE_ADV
174 /* Functions specific to each transmission mode for PRB calculation*/
175 RgSchUtlDlCalcPrbFunc  dlCalcPrbFunc[7] = {rgSchUtlDlCalc1CwPrb,
176 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
177 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb};
178
179 #else
180 /* Functions specific to each transmission mode for PRB calculation*/
181 RgSchUtlDlCalcPrbFunc  dlCalcPrbFunc[9] = {rgSchUtlDlCalc1CwPrb,
182 rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc2CwPrb, rgSchUtlDlCalc2CwPrb,
183 NULLP, rgSchUtlDlCalc1CwPrb, rgSchUtlDlCalc1CwPrb, NULLP, NULLP};
184
185 #endif
186
187 #ifdef LTE_TDD
188 /* The below table will be used to map the UL SF number in a TDD Cfg 0 
189    frame to the ul Sf array maintained in cellCb */
190 static uint8_t  rgSchTddCfg0UlSfTbl[] = {2, 3, 4, 7, 8, 9};
191 #endif
192
193 static S16 rgSCHUtlUlAllocDbInit ARGS((
194          RgSchCellCb    *cell,
195          RgSchUlAllocDb *db,
196          uint8_t maxAllocs
197          ));
198 static Void rgSCHUtlUlAllocDbDeinit ARGS((
199          RgSchCellCb    *cell,
200          RgSchUlAllocDb *db
201          ));
202 static S16 rgSCHUtlUlHoleDbInit ARGS((
203          RgSchCellCb    *cell,
204          RgSchUlHoleDb *db,
205          uint8_t maxHoles,
206          uint8_t start,
207          uint8_t num
208          ));
209 static Void rgSCHUtlUlHoleDbDeinit ARGS((
210          RgSchCellCb   *cell,
211          RgSchUlHoleDb *db
212          ));
213
214 static S16 rgSCHChkBoUpdate ARGS((
215          RgSchCellCb    *cell,
216          RgInfCmnBoRpt  *boUpdt
217          ));
218 #ifdef UNUSE_FUN
219 #ifdef TFU_UPGRADE
220 static uint8_t rgSCHUtlFetchPcqiBitSz ARGS((
221  RgSchCellCb    *cell,
222  RgSchUeCb      *ueCb, 
223  uint8_t        numTxAnt
224  ));
225 #endif
226 #endif
227 /* sorted in ascending order of tbSz */
228 const struct rgSchUtlBcchPcchTbSz
229 {
230    uint8_t   rbIndex;    /* RB index {2,3} */
231    uint16_t  tbSz;       /* one of the Transport block size in bits of
232                      * rbIndex 2 or 3 */
233    /* Corrected allocation for common channels */
234    uint8_t   mcs;        /* imcs */
235 } rgSchUtlBcchPcchTbSzTbl[44] = {
236    { 2,   32,  0 }, { 2,   56,  1 }, { 2,   72,  2 }, { 3,   88,  1 },
237    { 2,  104,  3 }, { 2,  120,  4 }, { 2,  144,  5 }, { 2,  176,  6 },
238    { 3,  208,  4 }, { 2,  224,  7 }, { 2,  256,  8 }, { 2,  296,  9 },
239    { 2,  328, 10 }, { 2,  376, 11 }, { 3,  392,  8 }, { 2,  440, 12 },
240    { 3,  456,  9 }, { 2,  488, 13 }, { 3,  504, 10 }, { 2,  552, 14 },
241    { 3,  584, 11 }, { 2,  600, 15 }, { 2,  632, 16 }, { 3,  680, 12 },
242    { 2,  696, 17 }, { 3,  744, 13 }, { 2,  776, 18 }, { 2,  840, 19 },
243    { 2,  904, 20 }, { 3,  968, 16 }, { 2, 1000, 21 }, { 2, 1064, 22 },
244    { 2, 1128, 23 }, { 3, 1160, 18 }, { 2, 1192, 24 }, { 2, 1256, 25 },
245    { 3, 1288, 19 }, { 3, 1384, 20 }, { 2, 1480, 26 }, { 3, 1608, 22 },
246    { 3, 1736, 23 }, { 3, 1800, 24 }, { 3, 1864, 25 }, { 3, 2216, 26 }
247 };
248
249 /* local typedefs */
250
251 /* local externs */
252
253 /* forward references */
254 #ifdef LTE_TDD
255 static Void rgSCHUtlUpdPrachOcc ARGS((
256 RgSchCellCb *cell,
257 RgrTddPrachInfo *cellCfg));
258 #endif
259
260 #define RGSCH_NUM_PCFICH_REG 4
261 #define RGSCH_NUM_REG_PER_CCE 9
262 #define RGSCH_NUM_REG_PER_PHICH_GRP 3
263
264 #ifdef LTE_TDD
265 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _iPhich) {\
266    (_phich)->hqFeedBack = _hqFeedBack; \
267    (_phich)->rbStart = _rbStart; \
268    (_phich)->nDmrs = _nDmrs; \
269    (_phich)->iPhich = _iPhich; \
270    (_phich)->lnk.next = NULLP; \
271    (_phich)->lnk.prev = NULLP; \
272    (_phich)->lnk.node = (PTR)(_phich); \
273 }
274 #else
275 #define RGSCH_INITPHICH(_phich, _hqFeedBack, _nDmrs, _rbStart, _isForMsg3) {\
276    (_phich)->hqFeedBack = _hqFeedBack; \
277    (_phich)->rbStart = _rbStart; \
278    (_phich)->nDmrs = _nDmrs; \
279    (_phich)->isForMsg3 = _isForMsg3; \
280    (_phich)->lnk.next = NULLP; \
281    (_phich)->lnk.prev = NULLP; \
282    (_phich)->lnk.node = (PTR)(_phich); \
283 }
284 #endif
285
286 #define RGSCH_PHICH_ALLOC(_inst,_dataPtr, _size, _ret) {\
287    _ret = rgSCHUtlAllocSBuf(_inst, (Data **)&_dataPtr, _size); \
288 }
289
290 /* ccpu00117052 - MOD - Passing double pointer
291 for proper NULLP assignment*/
292 #define RGSCH_PHICH_FREE(_inst, _dataPtr, _size) {\
293       rgSCHUtlFreeSBuf(_inst, (Data **)(&(_dataPtr)), _size); \
294 }
295
296 #ifdef TFU_UPGRADE
297 #define RGSCH_GETBIT(a, b)     ((((uint8_t*)a)[(b)>>3] >> ((7-((b)&7)))) & 1)
298
299 /*
300 *
301 *       Fun:   rgSCHUtlPower
302 *
303 *       Desc:  This function finds of the Power of x raised to n
304 *
305 *       Ret:   value of x raised to n
306 *
307 *       Notes: None
308 *
309 *       File:  rg_sch_utl.c
310 *
311 */
312 F64 rgSCHUtlPower(F64 x,F64 n)
313 {
314  if( n==0 )
315  {
316    return ( 1 );
317  }
318  else if ( n>0 )
319  {
320    return ( x * rgSCHUtlPower( x, n-1 ) );
321  }
322  else
323  {
324    return ( (1/x) * rgSCHUtlPower( x, n+1 ) );
325  }
326 } /* end of rgSCHUtlPower*/
327
328 /*
329 *
330 *       Fun:   rgSCHUtlParse
331 *
332 *       Desc:  This function parses bits x to y of an array and
333 *                  returns the integer value  out of it.
334 *
335 *       Ret:   integer value of z bits
336 *
337 *       Notes: None
338 *
339 *       File:  rg_sch_utl.c
340 *
341 */
342 uint32_t rgSCHUtlParse(uint8_t *buff,uint8_t startPos,uint8_t endPos,uint8_t buffSize)
343 {
344  uint8_t pointToChar,pointToEnd, loop;
345  uint8_t size =  endPos - startPos;
346  F64 result = 0;
347  pointToEnd = (startPos)%8;
348    for ( loop=0; loop<size; loop++)
349    {
350       pointToChar = (((startPos)+loop)/8);
351       if (RGSCH_GETBIT(buff+pointToChar,pointToEnd%8)==1)
352       {
353          result=result+(rgSCHUtlPower(2,(size-loop-1)));
354       }
355       pointToEnd++;
356    }
357    return ((uint32_t)result);
358 } /* end of rgSCHUtlParse*/
359
360 /*
361 *
362 *       Fun:   rgSCHUtlFindDist
363 *
364 *       Desc:  This function calculates the iterations need to cover
365 *                  before the valid Index can be used for next possible Reception
366 *
367 *       Ret:   integer value of z bits
368 *
369 *       Notes: None
370 *
371 *       File:  rg_sch_utl.c
372 *
373 */
374 uint8_t rgSCHUtlFindDist(uint16_t crntTime,uint16_t tempIdx)
375 {
376  uint8_t  dist =0;
377  /* ccpu00137113- Distance is not estimated properly if the periodicity is 
378   * equal to RG_SCH_PCQI_SRS_SR_TRINS_SIZE.
379   */
380  while(crntTime<=tempIdx)
381  {
382     crntTime += RG_SCH_PCQI_SRS_SR_TRINS_SIZE;
383     dist+=1;
384  }
385  return (dist-1);
386 } /* end of rgSCHUtlFindDist*/
387 #endif
388
389 \f
390 /**
391  * @brief This function checks availability of a PDCCH
392  *
393  * @details
394  *
395  *     Function: rgSCHUtlPdcchAvail
396  *     Purpose:  This function checks if a particular PDCCH is in use.
397  *               map field of PDCCH is used to track the CCEs arleady
398  *               allocated. Each bit of map represents one CCE and the
399  *               LSBit of first byte represents CCE 0.
400  *               steps:
401  *               1. Locate the set of bits that represent the PDCCH for
402  *               the provided location.
403  *               2.  If the value of the bits is non-zero one or many CCEs
404  *               for the PDCCH are in use and hence the PDCCH is not available.
405  *               3. If pdcch is available, assign it to [out]pdcch.
406  *               4.  Set all of the bits to one. There is no check performed
407  *               to see if the PDCCH is available.
408  *
409  *     Invoked by: scheduler
410  *
411  *  @param[in]  RgSchCellCb*     cell
412  *  @param[in]  RgSchPdcchInfo*  pdcchInfo
413  *  @param[in]  uint8_t            loc
414  *  @param[in]  uint8_t            aggrLvl
415  *  @param[out] RgSchPdcch**     pdcch
416  *  @return  Boolean
417  *         -#   TRUE  if available
418  *         -#   FALSE otherwise
419  *
420  **/
421 Bool rgSCHUtlPdcchAvail
422 (
423 RgSchCellCb    *cell,
424 RgSchPdcchInfo *pdcchInfo,
425 CmLteAggrLvl   aggrLvl,
426 RgSchPdcch     **pdcch
427 )
428 {
429    uint8_t             *byte;
430    uint16_t             offset;
431    uint16_t             initMask;
432    uint16_t             currMask;
433    Inst                 inst = cell->instIdx;
434    S16                  ret;
435    uint16_t             offsetStepMask;
436
437    /* V5G_213 : 10.1 */
438         offset = 0;
439         byte = &pdcchInfo->map[0];
440         initMask = (0xffff >> (16 - aggrLvl));
441         currMask = initMask;
442         /* if N(symbol, xPDCCH) =2, then xPDCCH will be candidates in 
443           * search space of index {0,1,2,3} and {8,9,..14}
444           */
445         if ((cell->cell5gtfCb.cfi == 2) && (aggrLvl == CM_LTE_AGGR_LVL2))
446         {
447                 offsetStepMask = 0xc;
448         }
449         else
450         {
451                 offsetStepMask = 0xc0;
452         }
453
454         /* Loop till the number of bytes available in the CCE map */
455         while (offset < ((pdcchInfo->nCce+ 7) >> 3))
456         {
457            byte = &pdcchInfo->map[offset];
458                 /* Checking for available CCE */
459                 if ((*byte & currMask) == 0)
460            {
461               break;
462            }
463                 /* if the number of CCEs required are not available, move to next offset */
464                 if (currMask & offsetStepMask)
465                 {
466                         offset++;
467                         currMask = initMask;
468                 }
469                 else
470                 {
471                    /* Move to the next available CCE index in the current byte(cce map) */
472                         currMask = currMask << aggrLvl;
473                 }
474         }
475
476         if ((offset >= ((pdcchInfo->nCce + 7) >> 3)) || 
477                   ((aggrLvl == CM_LTE_AGGR_LVL16) && (offset > 0)))
478         {
479                 return (FALSE);
480         }
481
482         byte = &pdcchInfo->map[offset];
483    
484    if (cell->pdcchLst.first != NULLP)
485    {
486       *pdcch = (RgSchPdcch *)(cell->pdcchLst.first->node);
487       cmLListDelFrm(&cell->pdcchLst, cell->pdcchLst.first);
488    }
489    else
490    {
491       ret = rgSCHUtlAllocSBuf(inst, (Data **)pdcch, sizeof(RgSchPdcch));
492       if(ROK != ret)
493       {
494          return (FALSE);
495       }
496    }
497
498    if (*pdcch)
499    {
500       (*byte) |= currMask;
501                 /* ALL CCEs will be used in case of level 16 */
502                 if (aggrLvl == CM_LTE_AGGR_LVL16)
503                 {
504                         *(byte+1) |= currMask;
505                 }
506       (*pdcch)->aggrLvl = aggrLvl;
507       cmLListAdd2Tail(&pdcchInfo->pdcchs, &((*pdcch)->lnk));
508       (*pdcch)->lnk.node = (PTR)*pdcch;
509       (*pdcch)->nCce = aggrLvl;
510       (*pdcch)->ue = NULLP;
511    }
512    return (TRUE);
513 }
514
515
516 \f
517 /**
518  * @brief This function releases a PDCCH
519  *
520  * @details
521  *
522  *     Function: rgSCHUtlPdcchPut
523  *     Purpose:  This function releases a PDCCH.
524  *               steps:
525  *               1. Locate the set of bits that represent the PDCCH for
526  *               the provided location.
527  *               2. Set all of the bits to zero.
528  *               3. Release the memory of PDCCH to the cell free Q
529  *
530  *     Invoked by: scheduler
531  *
532  *  @param[in]  RgSchPdcchInfo*  pdcchInfo
533  *  @param[in]  uint8_t            loc
534  *  @param[in]  uint8_t            aggrLvl
535  *  @return     Void
536  *
537  **/
538 Void rgSCHUtlPdcchPut(RgSchCellCb *cell,RgSchPdcchInfo *pdcchInfo,RgSchPdcch *pdcch)
539 {
540    uint8_t              *byte;
541    uint8_t              offset;
542    uint16_t             mask;
543
544    switch(pdcch->aggrLvl)
545    {
546       case CM_LTE_AGGR_LVL2:
547          offset = (pdcch->nCce >> 1) & 3;
548          mask = 0x3 << (offset * 2); /*ccpu00128826 - Offset Correction */
549          break;
550       case CM_LTE_AGGR_LVL4:
551          offset = (pdcch->nCce >> 2) & 1;
552          mask = 0xf << (offset * 4);/*ccpu00128826 - Offset Correction */
553          break;
554       case CM_LTE_AGGR_LVL8:
555          mask = 0xff;
556          break;
557                 case CM_LTE_AGGR_LVL16:
558          mask = 0xffff;
559          break;
560       default:
561          return;
562    }
563    /* Placing common computation of byte from all the cases above here
564       for optimization */
565    byte = &pdcchInfo->map[pdcch->nCce >> 3];
566
567    cmLListDelFrm(&pdcchInfo->pdcchs, &pdcch->lnk);
568    cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
569    pdcch->lnk.node = (PTR)pdcch;
570    pdcch->ue = NULLP;
571    (*byte) &= ~mask;
572
573   return;
574 }
575
576 \f
577 /**
578  * @brief This function initializes PDCCH information for frame
579  *
580  * @details
581  *
582  *     Function: rgSCHUtlPdcchInit
583  *     Purpose:  This function initializes PDCCH information for
584  *               a slot. It removes the list of PDCCHs allocated
585  *               in the prior use of this slot structure.
586  *
587  *     Invoked by: rgSCHUtlSubFrmPut
588  *
589  *  @param[in]  RgSchCellCb*     cell
590  *  @param[in]  RgSubFrm*     subFrm
591  *  @return  Void
592  *
593  **/
594 Void rgSCHUtlPdcchInit(RgSchCellCb *cell,RgSchDlSf *subFrm,uint16_t nCce)
595 {
596    RgSchPdcchInfo       *pdcchInfo;
597    RgSchPdcch           *pdcch;
598    Inst                 inst = cell->instIdx;
599    uint8_t              extraBits;
600    uint32_t             cceMapSz;
601
602    pdcchInfo = &subFrm->pdcchInfo;
603    while(pdcchInfo->pdcchs.first != NULLP)
604    {
605       pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
606       cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
607       cmLListAdd2Tail(&cell->pdcchLst, &pdcch->lnk);
608       pdcch->ue = NULLP;
609    }
610    cmLListInit(&pdcchInfo->pdcchs);
611    
612 #ifdef LTEMAC_SPS
613    subFrm->relPdcch = NULLP;
614 #endif
615    
616    cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
617
618         /* The bitMap array size is the number of ceiling(CCEs/8) */
619         /* If nCce received is not the same as the one stored in    
620         * pdcchInfo, free the pdcchInfo map                      */
621
622    if(pdcchInfo->nCce != nCce)
623    {
624       if(pdcchInfo->nCce)
625       {
626         rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)), cceMapSz);
627       }
628       pdcchInfo->nCce = nCce;
629       cceMapSz = ((pdcchInfo->nCce + 7) >> 3);
630       rgSCHUtlAllocSBuf(inst, (Data **)&pdcchInfo->map,  
631       cceMapSz);
632       if (pdcchInfo->map == NULLP)
633       {
634          /* Generate log error here */
635          return;
636       }    
637    }
638
639    memset(subFrm->pdcchInfo.map, 0, cceMapSz);
640    /*   If nCce is not exactly same as the bitMap size(no of bits allocated
641         * to represent the Cce's, then mark the extra bits as unavailable
642         extra bits = (((pdcchInfo->nCce + 7) >> 3)*8) - pdcchInfo->nCce
643         The last byte of bit map = subFrm->pdcchInfo.map[((pdcchInfo->nCce + 7) >> 3) - 1]
644          NOTE : extra bits are most significant of the last byte eg.  */
645    extraBits = (cceMapSz)*8 - pdcchInfo->nCce;
646    subFrm->pdcchInfo.map[cceMapSz - 1] |=
647      ((1 << extraBits) - 1) << (8 - extraBits);
648    return;
649 }
650
651 /* LTE_ADV_FLAG_REMOVED_START */
652 /**
653  * @brief This function frees Pool
654  * @details
655  *
656  *     Function: rgSchSFRTotalPoolFree
657  *
658  *     Invoked by: rgSchSFRTotalPoolInit
659  *
660  *  @param[in]  RgSchCellCb*     cell
661  *  @param[in]  RgSubFrm*     subFrm
662  *  @return  Void
663  *
664  **/
665 Void rgSchSFRTotalPoolFree(RgSchSFRTotalPoolInfo *sfrTotalPoolInfo,RgSchCellCb *cell)
666 {
667    CmLListCp   *l;
668    CmLList     *n;
669
670    /*Deinitialise if  these cc pools and ce pools are already existent*/
671    l = &sfrTotalPoolInfo->ccPool;
672    n = cmLListFirst(l);
673    while (n != NULL)
674    {
675       /*REMOVING Cell Centred POOLS IF ANY*/
676       n = cmLListDelFrm(l, n);
677
678       /* Deallocate buffer */
679       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
680
681       /* Deallocate buffer */
682       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));   
683       n = cmLListNext(l);
684    }
685
686    /*REMOVING Cell Edged POOLS IF ANY*/
687    l = &sfrTotalPoolInfo->cePool;
688    n = cmLListFirst(l);
689    while (n != NULL)
690    {
691       n = cmLListDelFrm(l, n);
692
693       /* Deallocate buffer */
694       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n->node)), sizeof(RgSchSFRPoolInfo));
695
696       /* Deallocate buffer */
697       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(n)), sizeof(CmLList));   
698       n = cmLListNext(l);
699    } 
700
701 }
702
703 /**
704  * @brief This function resets temporary variables in Pool
705  * @details
706  *
707  *     Function: rgSchSFRResetPoolVariables
708  *
709  *     Invoked by: rgSCHSFRUtlTotalPoolInit
710  *
711  *  @param[in]  RgSchCellCb*     cell
712  *  @param[in]  RgSubFrm*     subFrm
713  *  @return  Void
714  *
715  **/
716 S16 rgSchSFRTotalPoolInit(RgSchCellCb *cell,RgSchDlSf *sf)
717 {      
718    /*  Initialise the variables */
719    RgSchSFRPoolInfo *sfrCCPool;
720    RgSchSFRPoolInfo *sfrCEPool;
721    CmLListCp   *l;
722    CmLList     *n;
723    CmLList *temp = NULLP;
724    S16 ret = 0;
725
726    rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);  
727    sf->sfrTotalPoolInfo.CCPool1BwAvlbl          = 0;
728    sf->sfrTotalPoolInfo.CCPool2BwAvlbl          = 0;
729    sf->sfrTotalPoolInfo.CEPoolBwAvlbl           = 0;
730    sf->sfrTotalPoolInfo.CC1                     = FALSE;
731    sf->sfrTotalPoolInfo.CC2                     = FALSE;
732    /*Initialise the CE Pools*/
733    cmLListInit (&(sf->sfrTotalPoolInfo.cePool));
734
735    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
736    if (ret != ROK)
737    {
738       DU_LOG("\nERROR  -->  SCH : CE Pool memory allocation FAILED for cell");       
739       rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo, cell);
740       return RFAILED;
741    }
742
743    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
744    if (ret != ROK)
745    {
746       DU_LOG("\nERROR  -->  SCH : CE Pool memory allocation FAILED for cell ");       
747       rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
748       return RFAILED;
749    }
750
751    l = &sf->sfrTotalPoolInfo.cePool;
752    cmLListAdd2Tail(l, temp);
753
754    /*Initialise Bandwidth and startRB and endRB for each pool*/
755    n = cmLListFirst(l);
756
757    /* Initialise the CE Pools */
758    sfrCEPool = (RgSchSFRPoolInfo*)n->node;
759
760    sfrCEPool->poolstartRB             = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.startRb;
761    sfrCEPool->poolendRB               = cell->lteAdvCb.sfrCfg.cellEdgeRbRange.endRb;
762    sfrCEPool->bw                      = sfrCEPool->poolendRB - sfrCEPool->poolstartRB + 1;
763    sf->sfrTotalPoolInfo.CEPoolBwAvlbl = sfrCEPool->bw;
764
765    sfrCEPool->bwAlloced               = 0;
766    sfrCEPool->type2Start              = sfrCEPool->poolstartRB;
767    sfrCEPool->type2End                = RGSCH_CEIL(sfrCEPool->poolstartRB, cell->rbgSize);   
768    sfrCEPool->type0End                = ((sfrCEPool->poolendRB + 1) / cell->rbgSize) - 1;
769    sfrCEPool->pwrHiCCRange.startRb    = 0;
770    sfrCEPool->pwrHiCCRange.endRb      = 0;
771
772    /*Initialise CC Pool*/
773    cmLListInit (&(sf->sfrTotalPoolInfo.ccPool));
774
775    /*Add memory and Update CCPool*/
776    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
777    if (ret != ROK)
778    {
779       DU_LOG("\nERROR  -->  SCH : CC Pool memory allocation FAILED for cell ");       
780       rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
781       return RFAILED;
782    }
783
784    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
785    if (ret != ROK)
786    {
787       DU_LOG("\nERROR  -->  SCH : CC Pool memory allocation FAILED for cell ");       
788       rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
789       return RFAILED;
790    }
791
792    l = &sf->sfrTotalPoolInfo.ccPool;
793    cmLListAdd2Tail(l, temp);
794
795    /*Initialise Bandwidth and startRB and endRB for each pool*/
796    if(sfrCEPool->poolstartRB)
797    {
798       n = cmLListFirst(l);
799       sfrCCPool = (RgSchSFRPoolInfo*)n->node;
800
801       sfrCCPool->poolstartRB              = 0;
802       sfrCCPool->poolendRB                = sfrCEPool->poolstartRB - 1;
803       sfrCCPool->bw                       = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
804       sf->sfrTotalPoolInfo.CCPool1BwAvlbl = sfrCCPool->bw;
805       sfrCCPool->bwAlloced                = 0;
806       sfrCCPool->type2Start               = 0;
807       sfrCCPool->type2End                 = 0;
808       sfrCCPool->type0End                 = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
809       sf->sfrTotalPoolInfo.CC1            = TRUE;
810       sfrCCPool->pwrHiCCRange.startRb     = 0;
811       sfrCCPool->pwrHiCCRange.endRb       = 0;
812    }
813    else
814    {
815       n = cmLListFirst(l);
816       sfrCCPool = (RgSchSFRPoolInfo*)n->node;
817
818       sfrCCPool->poolstartRB              = sfrCEPool->poolendRB + 1;
819       sfrCCPool->poolendRB                = sf->bw - 1;
820       sfrCCPool->bw                       = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
821       sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
822       sfrCCPool->CCPool2Exists            = TRUE;
823       sfrCCPool->bwAlloced                = 0;
824       sfrCCPool->type2Start               = sfrCCPool->poolstartRB;
825       sfrCCPool->type2End                 = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
826       sfrCCPool->type0End                 = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
827       sf->sfrTotalPoolInfo.CC2            = TRUE;
828       sfrCEPool->adjCCPool                = sfrCCPool; /* SFR_FIX */
829       sfrCCPool->pwrHiCCRange.startRb     = 0;
830       sfrCCPool->pwrHiCCRange.endRb       = 0;
831    }
832
833    if((sfrCEPool->poolendRB != sf->bw - 1) && (!sfrCCPool->poolstartRB))
834    {    
835       /*Add memory and Update CCPool*/
836       ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp, sizeof(CmLList));
837       if (ret != ROK)
838       {
839          DU_LOG("\nERROR  -->  SCH : CC Pool memory allocation FAILED for cell ");       
840          rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
841          return RFAILED;
842       }
843
844       ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&temp->node, sizeof(RgSchSFRPoolInfo));
845       if (ret != ROK)
846       {
847          DU_LOG("\nERROR  -->  SCH : CC Pool memory allocation FAILED for cell ");       
848          rgSchSFRTotalPoolFree(&sf->sfrTotalPoolInfo,cell);
849          return RFAILED;
850       }
851
852       cmLListAdd2Tail(l, temp);
853
854       n = cmLListCrnt(l);
855       sfrCCPool = (RgSchSFRPoolInfo*)n->node;
856
857       sfrCCPool->poolstartRB              = sfrCEPool->poolendRB + 1;
858       sfrCCPool->poolendRB                = sf->bw - 1;
859       sfrCCPool->bw                       = sfrCCPool->poolendRB - sfrCCPool->poolstartRB + 1;
860       sf->sfrTotalPoolInfo.CCPool2BwAvlbl = sfrCCPool->bw;
861       sfrCCPool->CCPool2Exists            = TRUE;
862       sfrCCPool->bwAlloced                = 0;
863       sfrCCPool->type2Start               = sfrCCPool->poolstartRB;      
864       sfrCCPool->type2End                 = RGSCH_CEIL(sfrCCPool->poolstartRB, cell->rbgSize);
865       sfrCCPool->type0End                 = ((sfrCCPool->poolendRB + 1) / cell->rbgSize) - 1;
866       sf->sfrTotalPoolInfo.CC2            = TRUE;
867       sfrCEPool->adjCCPool                = sfrCCPool; /* SFR_FIX */
868       sfrCCPool->pwrHiCCRange.startRb     = 0;
869       sfrCCPool->pwrHiCCRange.endRb       = 0;
870    }   
871
872    sf->sfrTotalPoolInfo.CCRetx            = FALSE;
873    sf->sfrTotalPoolInfo.CERetx            = FALSE;
874
875    sf->sfrTotalPoolInfo.ccBwFull          = FALSE;
876    sf->sfrTotalPoolInfo.ceBwFull          = FALSE;
877    sf->sfrTotalPoolInfo.isUeCellEdge      = FALSE;
878    return ROK;
879 }
880 /**
881  * @brief This function resets temporary variables in RNTP Prepration
882  * @details
883  *
884  *     Function:   rgSchDSFRRntpInfoInit 
885  *
886  *     Invoked by: rgSCHSFRUtlTotalPoolInit
887  *
888  *  @param[in]  TknStrOSXL*     rntpPtr
889  *  @param[in]  RgSubFrm*        subFrm
890  *  @return  S16
891  *
892  **/
893 S16   rgSchDSFRRntpInfoInit(TknStrOSXL  *rntpPtr,RgSchCellCb *cell,uint16_t bw)
894 {   
895    Inst inst = cell->instIdx;
896    uint16_t len;
897
898    rntpPtr->pres = PRSNT_NODEF;
899
900    len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
901
902    rntpPtr->len  = len;   
903
904    /* Allocate memory for "scheduled UE" Info */
905    if((rgSCHUtlAllocSBuf(inst, (Data**)&(rntpPtr->val),
906                (len * sizeof(uint8_t)))) != ROK)
907    {
908       DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for RNTP Alloc");
909       return RFAILED;
910    }
911
912    return ROK;
913 }
914
915 /**
916  * @brief This function release RNTP pattern from slot and Cell 
917  * @details
918  *
919  *     Function:   rgSchDSFRRntpInfoFree 
920  *
921  *     Invoked by: rgSCHSFRUtlTotalPoolInit
922  *
923  *  @param[in]  TknStrOSXL*     rntpPtr
924  *  @param[in]  RgSubFrm*        subFrm
925  *  @return  S16
926  *
927  **/
928 S16   rgSchDSFRRntpInfoFree(TknStrOSXL *rntpPtr,RgSchCellCb *cell,uint16_t bw)
929 {   
930    Inst inst = cell->instIdx;
931    uint16_t len;
932
933    len = (bw % 8 == 0) ? (bw/8) : (bw/8 + 1);
934
935    if(rntpPtr->pres == PRSNT_NODEF)
936    {   
937       rgSCHUtlFreeSBuf(inst, (Data **)(&(rntpPtr->val)),(len * sizeof(uint8_t)));
938       rntpPtr->pres = NOTPRSNT;
939       rntpPtr->len  = 0;   
940    }
941
942    return ROK;
943 }
944
945 /**
946  * @brief This function resets temporary variables in Pool
947  * @details
948  *
949  *     Function: rgSchSFRResetPoolVariables
950  *     Purpose:  Initialise the dynamic variables in each pool.
951  *                    Reset bwAlloced, bwAssigned, type2End, type0End, type2Start
952  *     Invoked by: rgSCHSFRUtlTotalPoolReset
953  *
954  *  @param[in]  RgSchCellCb*     cell
955  *  @param[in]  RgSchSFRPoolInfo *pool
956  *  @return  Void
957  *
958  **/
959 static Void rgSchSFRResetPoolVariables(RgSchCellCb *cell,RgSchSFRPoolInfo *pool)
960 {
961
962    pool->bwAlloced  = 0;
963
964    /*type0end will be the last RBG in pool with all available RBs*/
965    pool->type0End = (((pool->poolendRB + 1)/cell->rbgSize) - 1);
966
967    /*type2end will be the first RBG in pool with all available RBs*/
968    pool->type2End = RGSCH_CEIL(pool->poolstartRB, cell->rbgSize);
969    pool->type2Start = pool->poolstartRB;
970    pool->bw = pool->poolendRB - pool->poolstartRB + 1;
971
972       return;
973 }
974 /**
975  * @brief This function resets SFR Pool information for frame
976  *
977  * @details
978  *
979  *     Function: rgSCHSFRUtlTotalPooReset
980  *     Purpose:  Update the dynamic variables in each pool as they will be modified in each slot.
981  *                    Dont modify the static variables like startRB, endRB, BW
982  *     Invoked by: rgSCHUtlSubFrmPut
983  *
984  *  @param[in]  RgSchCellCb*     cell
985  *  @param[in]  RgSchDlSf*     subFrm
986  *  @return  Void
987  *
988  **/
989 static Void rgSCHSFRUtlTotalPoolReset(RgSchCellCb *cell,RgSchDlSf *subFrm)
990 {
991    RgSchSFRTotalPoolInfo *totalPoolInfo = &subFrm->sfrTotalPoolInfo;
992    CmLListCp    *ccPool = &totalPoolInfo->ccPool;
993    CmLListCp    *cePool = &totalPoolInfo->cePool;
994    CmLList *node = NULLP;
995    RgSchSFRPoolInfo *tempPool = NULLP;
996
997    totalPoolInfo->ccBwFull          = FALSE;
998    totalPoolInfo->ceBwFull          = FALSE;
999    totalPoolInfo->isUeCellEdge      = FALSE;
1000    totalPoolInfo->CCPool1BwAvlbl    = 0;
1001    totalPoolInfo->CCPool2BwAvlbl    = 0;
1002    totalPoolInfo->CEPoolBwAvlbl     = 0;
1003    totalPoolInfo->CCRetx            = FALSE;
1004    totalPoolInfo->CERetx            = FALSE;
1005
1006    node = ccPool->first;
1007    while(node)
1008    {
1009       tempPool = (RgSchSFRPoolInfo *)(node->node);
1010       node = node->next;
1011       rgSchSFRResetPoolVariables(cell, tempPool);
1012       if(tempPool->poolstartRB == 0)
1013          totalPoolInfo->CCPool1BwAvlbl = tempPool->bw;
1014       else
1015          totalPoolInfo->CCPool2BwAvlbl = tempPool->bw;
1016    }
1017
1018    node = cePool->first;
1019    while(node)
1020    {
1021       tempPool = (RgSchSFRPoolInfo *)(node->node);
1022       node = node->next;
1023       rgSchSFRResetPoolVariables(cell, tempPool);
1024       totalPoolInfo->CEPoolBwAvlbl = tempPool->bw;    
1025    }
1026
1027    return;
1028 }
1029 /* LTE_ADV_FLAG_REMOVED_END */
1030 /**
1031  * @brief This function appends PHICH information for frame
1032  *
1033  * @details
1034  *
1035  *     Function: rgSCHUtlAddPhich
1036  *     Purpose:  This function appends PHICH information for
1037  *               a slot.
1038  *
1039  *     Invoked by: TOM
1040  *
1041  *  @param[in]  RgSchCellCb*     cell
1042  *  @param[in]  RgSubFrm*     subFrm
1043  *  @param[in]  uint8_t            hqFeedBack
1044  *  @param[in]  uint8_t            nDmrs
1045  *  @param[in]  uint8_t            rbStart
1046  *  @return  S16
1047  *      -# ROK
1048  *      -# RFAILED
1049  **/
1050 #ifdef LTE_TDD
1051 S16 rgSCHUtlAddPhich
1052 (
1053 RgSchCellCb     *cell,
1054 CmLteTimingInfo frm,
1055 uint8_t         hqFeedBack,
1056 uint8_t         nDmrs,
1057 uint8_t         rbStart,
1058 uint8_t         iPhich
1059 )
1060 #else
1061 S16 rgSCHUtlAddPhich
1062 (
1063 RgSchCellCb     *cell,
1064 CmLteTimingInfo frm,
1065 uint8_t         hqFeedBack,
1066 uint8_t         nDmrs,
1067 uint8_t         rbStart,
1068 Bool            isForMsg3
1069 )
1070 #endif
1071 {
1072    S16                ret;
1073    RgSchPhich         *phich;
1074    RgSchDlSf          *dlSf;
1075    Inst               inst = cell->instIdx;
1076
1077    dlSf = rgSCHUtlSubFrmGet(cell, frm);
1078    RGSCH_PHICH_ALLOC(inst, phich,sizeof(RgSchPhich), ret);
1079
1080    if(ret != ROK)
1081    {
1082       DU_LOG("\nERROR  -->  SCH : rgSCHUtlAddPhich(): "
1083                "Allocation of RgSchPhich failed");
1084       return RFAILED;
1085    }
1086 #ifdef LTE_TDD
1087    RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, iPhich);
1088 #else
1089    RGSCH_INITPHICH(phich, hqFeedBack, nDmrs, rbStart, isForMsg3); /*SR_RACH_STATS */
1090 #endif
1091    cmLListAdd2Tail(&dlSf->phichInfo.phichs, &phich->lnk);
1092    return ROK;
1093 } /* rgSCHUtlAddPhich */
1094
1095 /**
1096  * @brief This function resets PHICH information for frame
1097  *
1098  * @details
1099  *
1100  *     Function: rgSCHUtlPhichReset
1101  *     Purpose:  This function initializes PHICH information for
1102  *               a slot. It removes the list of PHICHs allocated
1103  *               in the prior use of this slot structure.
1104  *
1105  *     Invoked by: rgSCHUtlSubFrmPut
1106  *
1107  *  @param[in]  RgSchCellCb*     cell
1108  *  @param[in]  RgSubFrm*     subFrm
1109  *  @return  Void
1110  *
1111  **/
1112 static Void rgSCHUtlPhichReset(RgSchCellCb *cell,RgSchDlSf *subFrm)
1113 {
1114    RgSchPhichInfo          *phichInfo;
1115    RgSchPhich              *phich;
1116
1117    UNUSED(cell);
1118
1119    phichInfo = &subFrm->phichInfo;
1120    while(phichInfo->phichs.first != NULLP)
1121    {
1122       phich = (RgSchPhich *)phichInfo->phichs.first->node;
1123       cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
1124       RGSCH_PHICH_FREE(cell->instIdx, phich, sizeof(RgSchPhich));
1125    }
1126    cmLListInit(&phichInfo->phichs);
1127    return;
1128 } /* rgSCHUtlPhichReset */
1129
1130 \f
1131 /**
1132  * @brief This function returns slot data structure for a cell
1133  *
1134  * @details
1135  *
1136  *     Function: rgSCHUtlSubFrmGet
1137  *     Purpose:  This function resets the slot data structure
1138  *               when the slot is released
1139  *
1140  *     Invoked by: scheduler
1141  *
1142  *  @param[in]  RgSubFrm  subFrm
1143  *  @return  Void
1144  *
1145  **/
1146 RgSchDlSf* rgSCHUtlSubFrmGet(RgSchCellCb *cell,CmLteTimingInfo frm)
1147 {
1148    RgSchDlSf            *sf;
1149    uint8_t               dlIdx;
1150
1151 #ifdef LTE_TDD
1152    dlIdx = rgSCHUtlGetDlSfIdx(cell, &frm);
1153    //RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1154    sf = cell->subFrms[dlIdx];
1155 #else
1156    /* Changing the idexing
1157       so that proper slot is selected */
1158    dlIdx = (((frm.sfn & 1) * RGSCH_NUM_SUB_FRAMES) + (frm.slot % RGSCH_NUM_SUB_FRAMES));
1159    RGSCH_ARRAY_BOUND_CHECK(cell->instIdx, cell->subFrms, dlIdx);
1160    sf = cell->subFrms[dlIdx];
1161 #endif
1162   /* CA dev Start */
1163    sf->dlIdx    = dlIdx;
1164   /* CA dev End */
1165    return (sf);
1166 }
1167
1168 \f
1169 /**
1170  * @brief This function returns slot data structure for a cell
1171  *
1172  * @details
1173  *
1174  *     Function: rgSCHUtlSubFrmPut
1175  *     Purpose:  This function resets the slot data structure
1176  *               when the slot is released
1177  *
1178  *     Invoked by: scheduler
1179  *
1180  *  @param[in]  RgSubFrm  subFrm
1181  *  @return  Void
1182  *
1183  **/
1184 Void rgSCHUtlSubFrmPut(RgSchCellCb *cell,RgSchDlSf *sf)
1185 {
1186    uint8_t                  i;
1187    uint8_t                  noRaRsps;
1188
1189 #ifdef LTE_TDD
1190    /* Release all the held PDCCH information */
1191    rgSCHUtlPdcchInit(cell, sf, sf->nCce);
1192 #else
1193    /* Release all the held PDCCH information */
1194    rgSCHUtlPdcchInit(cell, sf, cell->nCce);
1195 #endif
1196    rgSCHUtlPhichReset(cell, sf);
1197
1198    /* Reset the bw allocated. */
1199    sf->bwAssigned = 0;
1200 #ifdef LTEMAC_SPS
1201    /* Setting allocated bandwidth to SPS bandwidth for non-SPS RB allocator */
1202    sf->bwAlloced = ((cell->spsCellCfg.maxSpsDlBw +
1203       cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
1204    if (sf->bwAlloced > sf->bw)
1205    {
1206       sf->bwAlloced = sf->bw;
1207    }
1208    sf->spsAllocdBw = 0;
1209    sf->type2Start = sf->bwAlloced;
1210    memset( &sf->dlSfAllocInfo, 0, sizeof(RgSchDlSfAllocInfo));
1211 #else
1212    sf->bwAlloced = 0;
1213    /* Fix for ccpu00123918*/
1214    sf->type2Start = 0;
1215    /* LTE_ADV_FLAG_REMOVED_START */
1216    /* dsfr_pal_fixes ** 21-March-2013 ** SKS */
1217    if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
1218    {
1219       memset(sf->rntpInfo.val, 0, sf->rntpInfo.len);
1220    }
1221    /* LTE_ADV_FLAG_REMOVED_END */
1222 #endif
1223    sf->txDone = FALSE;
1224    /*[ccpu00138609]-ADD-Reset the CCCH UE counter */
1225    sf->schdCcchUe = 0;
1226
1227    /* Non DLFS scheduling using Type0 RA requires the following
1228     * parameter's tracking */
1229    /* Type 2 localized allocations start from 0th RBG and onwards */
1230    /* Type 0 allocations start from last RBG and backwards*/
1231 #ifndef LTEMAC_SPS
1232    sf->type2End   = 0;
1233 #else
1234    sf->type2End   = RGSCH_CEIL(sf->bwAlloced,cell->rbgSize);
1235 #endif
1236    sf->type0End   = cell->noOfRbgs - 1;
1237    /* If last RBG is of incomplete size then special handling */
1238    (sf->bw % cell->rbgSize == 0)? (sf->lstRbgDfct = 0) :
1239       (sf->lstRbgDfct = cell->rbgSize - (sf->bw % cell->rbgSize));
1240    /* This resets the allocation for BCCH and PDCCH */
1241 #ifdef EMTC_ENABLE
1242    /* TODO we need to move this reset for emtc functions */
1243    if(!(cell->emtcEnable))
1244    {
1245       sf->bch.tb     = NULLP;
1246       sf->bch.tbSize = 0;
1247    }
1248 #else
1249    sf->bch.tb     = NULLP;
1250    sf->bch.tbSize = 0;
1251 #endif
1252    sf->bcch.pdcch = NULLP;
1253    sf->pcch.pdcch = NULLP;
1254 #ifdef LTE_TDD
1255    noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
1256 #else
1257    noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
1258 #endif
1259    for (i = 0; i < noRaRsps; i++)
1260    {
1261       sf->raRsp[i].pdcch = NULLP;
1262       cmLListInit(&(sf->raRsp[i].raRspLst));
1263    }
1264    /* LTE_ADV_FLAG_REMOVED_START */
1265    if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
1266    {
1267       rgSCHSFRUtlTotalPoolReset(cell, sf);
1268    }
1269    /* LTE_ADV_FLAG_REMOVED_END */
1270 #ifdef LTE_ADV
1271    cmLListInit(&sf->n1PucchResLst);
1272 #endif
1273
1274    sf->cceCnt = 0;
1275    sf->isCceFailure = FALSE;
1276    sf->dlUlBothCmplt = 0;
1277    return;
1278 }
1279
1280 \f
1281 /**
1282  * @brief This function computes log N (32 bit Unsigned) to the base 2
1283  *
1284  * @details
1285  *
1286  *     Function: rgSCHUtlLog32bitNbase2
1287  *     Purpose:  This function computes log N (32 bit Unsigned) to the base 2.
1288  *               For n= 0,1 ret = 0.
1289  *
1290  *     Invoked by: Scheduler
1291  *
1292  *  @param[in]  uint32_t       n
1293  *  @return  uint8_t
1294  *
1295  **/
1296 uint8_t rgSCHUtlLog32bitNbase2(uint32_t n)
1297 {
1298    uint32_t  b[] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
1299    uint32_t  s[] = {1, 2, 4, 8, 16};
1300    S16       i;
1301    uint8_t   ret = 0;
1302
1303    for (i=4; i >= 0; i--)
1304    {
1305       if (n & b[i])
1306       {
1307          n >>= s[i];
1308          ret |= s[i];
1309       }
1310    }
1311    return (ret);
1312 }
1313
1314 #ifdef LTEMAC_SPS
1315
1316 /**
1317  * @brief This function is a wrapper to call scheduler specific API.
1318  *
1319  * @details
1320  *
1321  *     Function: rgSCHUtlDlRelPdcchFbk
1322  *     Purpose:  Calls scheduler's handler for SPS release PDCCH feedback
1323  *     information.
1324  *
1325  *     Invoked by: DHM
1326  *
1327  *  @param[in]   RgSchCellCb     *cell
1328  *  @param[in]   RgSchUeCb       *ue
1329  *  @param[in]   uint8_t            isAck
1330  *  @return  Void
1331  *
1332  **/
1333 Void rgSCHUtlDlRelPdcchFbk(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t isAck)
1334 {
1335    cell->sc.apis->rgSCHDlRelPdcchFbk(cell, ue, isAck);
1336    return;
1337 }
1338
1339
1340
1341 /**
1342  * @brief This function is a wrapper to call scheduler specific API.
1343  *
1344  * @details
1345  *
1346  *     Function: rgSCHUtlDlProcAck
1347  *     Purpose:  Calls scheduler's handler to process Ack
1348  *     information.
1349  *
1350  *     Invoked by: DHM
1351  *
1352  *  @param[in]   RgSchCellCb     *cell
1353  *  @param[in]   RgSchDlHqProcCb *hqP
1354  *  @return  Void
1355  *
1356  **/
1357 Void rgSCHUtlDlProcAck(RgSchCellCb *cell,RgSchDlHqProcCb *hqP)
1358 {
1359    cell->sc.apis->rgSCHDlProcAck(cell, hqP);
1360    return;
1361 }
1362
1363 /**
1364  * @brief CRNTI CE Handler
1365  *
1366  * @details
1367  *
1368  *     Function : rgSCHUtlHdlCrntiCE
1369  *
1370  *     - Call scheduler common API
1371  *
1372  *
1373  *  @param[in]  RgSchCellCb   *cell
1374  *  @param[in]  RgSchUeCb     *ue
1375  *  @param[out] RgSchErrInfo  *err
1376  *  @return  Void
1377  **/
1378 Void rgSCHUtlHdlCrntiCE(RgSchCellCb  *cell,RgSchUeCb *ue)
1379 {
1380
1381    cell->sc.apis->rgSCHHdlCrntiCE(cell, ue);
1382    return;
1383 }  /* rgSCHUtlHdlCrntiCE */
1384 #endif /* LTEMAC_SPS */
1385
1386 /***********************************************************
1387  *
1388  *     Func : rgSCHUtlCalcTotalRegs
1389  *
1390  *     Desc : Calculate total REGs, given a bandwidth, CFI
1391  *            and number of antennas.
1392  *
1393  *     Ret  : Total REGs (uint16_t)
1394  *
1395  *     Notes: Could optimise if bw values are limited
1396  *            (taken from RRC spec) by indexing values from
1397  *            a table.
1398  *            Input values are not validated. CFI is assumed
1399  *            to be 1/2/3/4.
1400  *
1401  *     File :
1402  *
1403  **********************************************************/
1404 static uint16_t rgSCHUtlCalcTotalRegs(uint8_t bw,uint8_t cfi,uint8_t numAntna,Bool  isEcp)
1405 {
1406    uint16_t regs = 0;
1407
1408    /*ccpu00116757-  removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1409
1410    if (bw <= 10)
1411       ++cfi;
1412    switch (cfi)
1413    {
1414       /* Refer 36.211 section 6.10.1.2
1415        * For symbols 2 and 4, the REGs per RB will be based on cyclic prefix
1416        *  and number of antenna ports.
1417        * For symbol 1, there are 2 REGs per RB always. Similarly symbol 3
1418        * will have 3 REGS.
1419        */
1420       case 4:
1421          /*CR changes [ccpu00124416] - MOD*/
1422          if(isEcp)
1423          {
1424             regs =  bw * RGSCH_NUM_REGS_4TH_SYM_EXT_CP;
1425          }
1426          else
1427          {
1428             regs =  bw * RGSCH_NUM_REGS_4TH_SYM_NOR_CP;
1429          }
1430       case 3:
1431          regs += bw * RGSCH_NUM_REGS_3RD_SYM;
1432       case 2:
1433             /*CR changes [ccpu00124416] - MOD using number of antenna ports*/
1434          regs += (numAntna == RGSCH_NUM_ANT_PORT_FOUR) ? \
1435             (bw * RGSCH_NUM_REGS_2ND_SYM_FOUR_ANT_PORT) : \
1436             (bw * RGSCH_NUM_REGS_2ND_SYM_1OR2_ANT_PORT);
1437       default: /* case 1 */
1438          regs += bw * RGSCH_NUM_REGS_1ST_SYM;
1439    }
1440    return (regs);
1441 }
1442
1443 /***********************************************************
1444  *
1445  *     Func : rgSCHUtlCalcPhichRegs
1446  *
1447  *     Desc : Calculates number of PHICH REGs
1448  *
1449  *     Ret  : Number of PHICH REGs (uint8_t)
1450  *
1451  *     Notes: ng6 is Ng multiplied by 6
1452  *
1453  *     File :
1454  *
1455  **********************************************************/
1456 static uint16_t rgSCHUtlCalcPhichRegs(uint8_t bw,uint8_t ng6)
1457 {
1458    /* ccpu00115330: Corrected the calculation for number of PHICH groups*/
1459    return (RGSCH_CEIL((bw * ng6) ,(8 * 6)) * RGSCH_NUM_REG_PER_PHICH_GRP);
1460 }
1461
1462 #ifdef LTE_TDD
1463 /**
1464  * @brief Calculates total CCEs (N_cce)
1465  *
1466  * @details
1467  *
1468  *     Function: rgSCHUtlCalcNCce
1469  *     Purpose:  This function calculates and returns total CCEs for a
1470  *               cell, given the following: bandwidth, Ng configuration
1471  *               (multiplied by six), cfi (actual number of control
1472  *               symbols), m factor for PHICH  and number of antennas.
1473  *
1474  *     Invoked by: Scheduler
1475  *
1476  *  @param[in]  uint8_t      bw
1477  *  @param[in]  uint8_t      ng6
1478  *  @param[in]  uint8_t      cfi
1479  *  @param[in]  uint8_t      mPhich
1480  *  @param[in]  uint8_t      numAntna
1481  *  @param[in]  Bool    isEcp
1482  *  @return     N_cce (uint8_t)
1483  *
1484  **/
1485 uint8_t rgSCHUtlCalcNCce(uint8_t bw,RgrPhichNg ng,uint8_t cfi,uint8_t mPhich,uint8_t numAntna,Bool isEcp)
1486 {
1487    uint16_t totalRegs;
1488    uint16_t phichRegs;
1489    uint16_t cceRegs;
1490    uint8_t  ng6;
1491
1492    /*ccpu00116757-  removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1493
1494    switch (ng)
1495    {
1496       case RGR_NG_ONESIXTH:
1497          ng6 = 1;
1498          break;
1499       case RGR_NG_HALF:
1500          ng6 = 3;
1501          break;
1502       case RGR_NG_ONE:
1503          ng6 = 6;
1504          break;
1505       case RGR_NG_TWO:
1506       default:
1507          ng6 = 12;
1508          break;
1509    }
1510
1511    totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1512    phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1513    cceRegs   = totalRegs - mPhich*phichRegs - RGSCH_NUM_PCFICH_REG;
1514
1515    return ((uint8_t)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1516 }
1517
1518 #else
1519 /**
1520  * @brief Calculates total CCEs (N_cce)
1521  *
1522  * @details
1523  *
1524  *     Function: rgSCHUtlCalcNCce
1525  *     Purpose:  This function calculates and returns total CCEs for a
1526  *               cell, given the following: bandwidth, Ng configuration
1527  *               (multiplied by six), cfi (actual number of control
1528  *               symbols) and number of antennas.
1529  *
1530  *     Invoked by: Scheduler
1531  *
1532  *  @param[in]  uint8_t      bw
1533  *  @param[in]  uint8_t      ng6
1534  *  @param[in]  uint8_t      cfi
1535  *  @param[in]  uint8_t      numAntna
1536  *  @return     N_cce (uint8_t)
1537  *
1538  **/
1539 uint8_t rgSCHUtlCalcNCce(uint8_t bw,RgrPhichNg ng,uint8_t cfi,uint8_t numAntna,Bool isEcp)
1540 {
1541    uint16_t totalRegs;
1542    uint16_t phichRegs;
1543    uint16_t cceRegs;
1544    uint8_t  ng6;
1545
1546    /*ccpu00116757-  removed check for (ERRCLASS & ERRCLS_DEBUG)*/
1547
1548    switch (ng)
1549    {
1550       case RGR_NG_ONESIXTH:
1551          ng6 = 1;
1552          break;
1553       case RGR_NG_HALF:
1554          ng6 = 3;
1555          break;
1556       case RGR_NG_ONE:
1557          ng6 = 6;
1558          break;
1559       case RGR_NG_TWO:
1560       default:
1561          ng6 = 12;
1562          break;
1563    }
1564
1565    totalRegs = rgSCHUtlCalcTotalRegs(bw, cfi, numAntna, isEcp);
1566    phichRegs = rgSCHUtlCalcPhichRegs(bw, ng6);
1567    cceRegs   = totalRegs - phichRegs - RGSCH_NUM_PCFICH_REG;
1568
1569    return ((uint8_t)(cceRegs/RGSCH_NUM_REG_PER_CCE));
1570 }
1571 #endif
1572
1573 /**
1574  * @brief Returns PHICH info associated with an uplink
1575  *        HARQ process allocation
1576  *
1577  * @details
1578  *
1579  *     Function: rgSCHUtlGetPhichInfo
1580  *     Purpose:  This function returns PHICH info associated with
1581  *               an uplink HARQ process allocation. PHICH info
1582  *               comprises RB start and N_dmrs.
1583  *
1584  *  @param[in]  RgSchUlHqProcCb   *hqProc
1585  *  @param[out] uint8_t             *rbStartRef
1586  *  @param[out] uint8_t             *nDmrsRef
1587  *  @return  S16
1588  **/
1589 #ifdef LTE_TDD
1590 S16 rgSCHUtlGetPhichInfo(RgSchUlHqProcCb *hqProc,uint8_t *rbStartRef,uint8_t *nDmrsRef,uint8_t *iPhich)
1591 #else
1592 S16 rgSCHUtlGetPhichInfo(RgSchUlHqProcCb *hqProc,uint8_t *rbStartRef,uint8_t *nDmrsRef)
1593 #endif
1594 {
1595 /* ACC-TDD */
1596         S16 ret = RFAILED;
1597
1598         if ((hqProc != NULLP) && (hqProc->alloc != NULLP))
1599     {
1600        *rbStartRef = hqProc->alloc->grnt.rbStart;
1601        *nDmrsRef   = hqProc->alloc->grnt.nDmrs;
1602 #ifdef LTE_TDD
1603    *iPhich     = hqProc->iPhich;
1604 #endif
1605        ret = ROK;
1606     }
1607     return (ret);
1608 }
1609 #ifndef TFU_UPGRADE
1610 /**
1611  * @brief Returns uplink grant information required to permit
1612  *        PHY to receive data
1613  *
1614  * @details
1615  *
1616  *     Function: rgSCHUtlAllocRcptInfo
1617  *     Purpose:  Given an uplink allocation, this function returns
1618  *               uplink grant information which is needed by PHY to
1619  *               decode data sent from UE. This information includes:
1620  *               - RB start
1621  *               - Number of RBs
1622  *               - RV
1623  *
1624  *  @param[in]  RgSchUlAlloc   *alloc
1625  *  @param[out] uint8_t             *rbStartRef
1626  *  @param[out] uint8_t             *numRbRef
1627  *  @param[out] uint8_t             *rvRef
1628  *  @param[out] uint16_t            *size
1629  *  @param[out] TfuModScheme   *modType
1630  *  @param[out] Bool           *isRtx
1631  *  @param[out] uint8_t             *nDmrs
1632  *  @param[out] Bool           *ndi
1633  *  @param[out] uint8_t             *hqPId
1634  *  @return  S16
1635  **/
1636 S16 rgSCHUtlAllocRcptInfo
1637 (
1638 RgSchUlAlloc   *alloc,
1639 CmLteRnti      *rnti,
1640 uint8_t        *iMcsRef,
1641 uint8_t        *rbStartRef,
1642 uint8_t        *numRbRef,
1643 uint8_t        *rvRef,
1644 uint16_t       *size,
1645 TfuModScheme   *modType,
1646 Bool           *isRtx,
1647 uint8_t        *nDmrs,
1648 Bool           *ndi,
1649 uint8_t        *hqPId
1650 )
1651 {
1652    /* Modulation order for 16qam UEs would be
1653     * min(4,modulation order in grant). Please refer to 36.213-8.6.1*/
1654    CmLteUeCategory ueCtgy;
1655
1656 #if (ERRCLASS & ERRCLS_DEBUG)
1657    if ((alloc == NULLP) || (alloc->hqProc == NULLP))
1658    {
1659       return RFAILED;
1660    }
1661 #endif
1662
1663    if ( !alloc->forMsg3 )
1664    {
1665       if ( ((alloc->ue) == NULLP) ||  (RG_SCH_CMN_GET_UE(alloc->ue, alloc->ue->cell) == NULLP))
1666       {
1667          DU_LOG("\nERROR  -->  SCH : Failed: ue->sch is null RNTI:%d,isRetx=%d",
1668                      alloc->rnti, alloc->grnt.isRtx);
1669          return RFAILED; 
1670       }
1671      ueCtgy =  (RG_SCH_CMN_GET_UE_CTGY(alloc->ue));
1672    }
1673
1674    *iMcsRef    = alloc->grnt.iMcs;
1675    *rbStartRef = alloc->grnt.rbStart;
1676    *numRbRef   = alloc->grnt.numRb;
1677    *rvRef      = rgRvTable[alloc->hqProc->rvIdx];
1678    *rnti       = alloc->rnti;
1679    *size       = alloc->grnt.datSz;
1680    *modType    = (alloc->forMsg3)? alloc->grnt.modOdr:
1681                          ((ueCtgy == CM_LTE_UE_CAT_5)?
1682                          alloc->grnt.modOdr:
1683                          (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr)));
1684    *isRtx      = alloc->grnt.isRtx;
1685    *nDmrs      = alloc->grnt.nDmrs;
1686    *ndi        = alloc->hqProc->ndi;
1687    *hqPId      = alloc->hqProc->procId;
1688
1689    return ROK;
1690 }
1691 #else
1692 /**
1693  * @brief Returns uplink grant information required to permit
1694  *        PHY to receive data
1695  *
1696  * @details
1697  *
1698  *     Function: rgSCHUtlAllocRcptInfo
1699  *     Purpose:  Given an uplink allocation, this function returns
1700  *               uplink grant information which is needed by PHY to
1701  *               decode data sent from UE. This information includes:
1702  *               - RB start
1703  *               - Number of RBs
1704  *               - RV
1705  *
1706  *  @param[in]  RgSchUlAlloc   *alloc
1707  *  @param[out] uint8_t             *rbStartRef
1708  *  @param[out] uint8_t             *numRbRef
1709  *  @param[out] uint8_t             *rvRef
1710  *  @param[out] uint16_t            *size
1711  *  @param[out] TfuModScheme   *modType
1712  *  @return  S16
1713  **/
1714 S16 rgSCHUtlAllocRcptInfo(RgSchCellCb *cell,RgSchUlAlloc *alloc,CmLteTimingInfo *timeInfo,TfuUeUlSchRecpInfo *recpReq)
1715 {
1716 #if (ERRCLASS & ERRCLS_DEBUG)
1717    if ((alloc == NULLP) || (alloc->hqProc == NULLP))
1718    {
1719       return RFAILED;
1720    }
1721 #endif
1722    recpReq->size           = alloc->grnt.datSz;
1723    recpReq->rbStart        = alloc->grnt.rbStart;
1724    recpReq->numRb          = alloc->grnt.numRb;
1725    /* Modulation order min(4,mod in grant) for 16 qam UEs.
1726     * Please refer to 36.213-8.6.1*/
1727 #ifdef FOUR_TX_ANTENNA
1728    recpReq->modType        = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
1729          (/*(alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
1730             alloc->grnt.modOdr:    *//* Chandra:TmpFx-TM500 Cat5 with Only16QAM */
1731           (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
1732 #else
1733    recpReq->modType        = (TfuModScheme)((alloc->forMsg3)?alloc->grnt.modOdr:
1734                              ((alloc->ue->ueCatEnum == CM_LTE_UE_CAT_5)?
1735                               alloc->grnt.modOdr:
1736                              (RGSCH_MIN(RGSCH_QM_QPSK,alloc->grnt.modOdr))));
1737 #endif
1738    recpReq->nDmrs          = alloc->grnt.nDmrs;
1739    recpReq->hoppingEnbld   = FALSE;
1740    recpReq->hoppingBits    = 0;
1741    recpReq->isRtx          = alloc->grnt.isRtx;
1742    recpReq->ndi            = alloc->hqProc->ndi;   
1743    recpReq->rv             = rgRvTable[alloc->hqProc->rvIdx];
1744 #ifndef LTE_TDD
1745    recpReq->harqProcId = alloc->hqProc->procId;
1746 #else
1747    recpReq->harqProcId = rgSCHCmnGetUlHqProcIdx(timeInfo, cell);
1748 #endif
1749    /* Transmission mode is SISO till Uplink MIMO is implemented. */
1750    recpReq->txMode   = 0;
1751    /* This value needs to filled in in the case of frequency hopping. */
1752    recpReq->crntTxNb = 0;
1753
1754    recpReq->mcs = alloc->grnt.iMcs;
1755 #ifdef RG_5GTF
1756    recpReq->rbgStart = alloc->grnt.vrbgStart;
1757    recpReq->numRbg = alloc->grnt.numVrbg;
1758    recpReq->xPUSCHRange = alloc->grnt.xPUSCHRange;
1759    //TODO_SID Need to check
1760    recpReq->nAntPortLayer = 0;
1761    recpReq->SCID = alloc->grnt.SCID;
1762    recpReq->PMI = alloc->grnt.PMI;
1763    recpReq->uciWoTBFlag = alloc->grnt.uciOnxPUSCH;
1764    if(alloc->ue)
1765    {
1766       recpReq->beamIndex = alloc->ue->ue5gtfCb.BeamId;
1767    }
1768 #endif
1769
1770 #ifdef TENB_STATS
1771    if (!alloc->forMsg3)
1772    {
1773       if (alloc->grnt.isRtx)
1774       {
1775          alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulRetxOccns++;
1776       }
1777       else
1778       {
1779          alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulTxOccns++;
1780          alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulSumiTbs += \
1781             rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
1782          alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulNumiTbs ++;
1783          cell->tenbStats->sch.ulSumiTbs += \
1784             rgSCHCmnUlGetITbsFrmIMcs(alloc->grnt.iMcs);
1785          cell->tenbStats->sch.ulNumiTbs ++;
1786       }
1787       alloc->ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(alloc->ue->cell)].ulPrbUsg += alloc->grnt.numRb;
1788       cell->tenbStats->sch.ulPrbUsage[0] += alloc->grnt.numRb;
1789    }
1790 #endif
1791   /* ccpu00117050 - DEL - nSrs setting at rgSCHUtlAllocRcptInfo */
1792    return ROK;
1793 }
1794 #endif
1795
1796 #ifdef LTE_TDD
1797 /**
1798  * @brief This function initialises the PRACH slot occasions
1799  *
1800  * @details
1801  *
1802  *     Function: rgSCHUtlUpdPrachOcc
1803  *     Purpose:  This function updates the PRACH slots based on
1804  *               RGR configuration.
1805  *
1806  *     Invoked by: Scheduler
1807  *
1808  *  @param[in]  RgSchCellCb      *cell
1809  *  @param[in]  RgrTddPrachInfo  *cellCfg
1810  *  @return     Void
1811  *
1812  **/
1813 static Void rgSCHUtlUpdPrachOcc(RgSchCellCb *cell,RgrTddPrachInfo *cellCfg)
1814 {
1815    uint8_t    idx;
1816    uint8_t    count = 0;
1817    uint8_t    size;
1818    uint8_t    startIdx;
1819    uint8_t    endIdx;
1820
1821    /* In the 1st half frame */
1822    if(cellCfg->halfFrm == 0)
1823    {
1824       startIdx = 2;
1825       endIdx = 6;
1826    }
1827    /* In the 2nd half frame */
1828    else
1829    {
1830       startIdx = 6;
1831       endIdx = 10;
1832    }
1833    for(idx = startIdx; idx < endIdx; idx++)
1834    {
1835       if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
1836             == RG_SCH_TDD_UL_slot)
1837       {
1838          if(cellCfg->ulStartSfIdx == count)
1839          {
1840             size = cell->rachCfg.raOccasion.size;
1841             cell->rachCfg.raOccasion.slotNum[size] = idx;
1842             cell->rachCfg.raOccasion.size++;
1843             break;
1844          }
1845          count ++;
1846       }
1847    }
1848    return;
1849 }
1850
1851 /**
1852  * @brief This function initialises the PRACH occasions
1853  *
1854  * @details
1855  *
1856  *     Function: rgSCHUtlPrachCfgInit
1857  *     Purpose:  This function initialises the PRACH occasions based on
1858  *               RGR configuration.
1859  *
1860  *     Invoked by: Scheduler
1861  *
1862  *  @param[in]  RgSchCellCb       *cell
1863  *  @param[in]  RgrCellCfg        *cellCfg
1864  *  @return     Void
1865  *
1866  **/
1867 Void rgSCHUtlPrachCfgInit(RgSchCellCb *cell,RgrCellCfg *cellCfg)
1868 {
1869    uint8_t idx;
1870    uint8_t subfrmIdx;
1871    uint8_t splFrm;
1872
1873    if(cellCfg->prachRscInfo.numRsc <= 0)
1874    {
1875       DU_LOG("\nERROR  -->  SCH : Invalid"
1876                   "PRACH resources Configuration ");
1877       return;
1878    }
1879
1880    /* Update SFN occasions */
1881    cell->rachCfg.raOccasion.sfnEnum =
1882                      cellCfg->prachRscInfo.prachInfo[0].sfn;
1883
1884    cell->rachCfg.raOccasion.size = 0;
1885
1886    /* Update slot occasions */
1887    for(idx = 0; idx < cellCfg->prachRscInfo.numRsc; idx++)
1888    {
1889       if(cellCfg->prachRscInfo.prachInfo[idx].freqIdx == 0)
1890       {
1891          if(cellCfg->prachRscInfo.prachInfo[idx].halfFrm == 0)
1892          {
1893             splFrm = 1;
1894          }
1895          else
1896          {
1897             splFrm = 6;
1898          }
1899          if(cellCfg->prachRscInfo.prachInfo[idx].ulStartSfIdx ==
1900                                                 RGR_TDD_SPL_UL_IDX)
1901          {
1902             subfrmIdx = cell->rachCfg.raOccasion.size;
1903             cell->rachCfg.raOccasion.slotNum[subfrmIdx] = splFrm;
1904             cell->rachCfg.raOccasion.size++;
1905          }
1906          else
1907          {
1908             rgSCHUtlUpdPrachOcc(cell,
1909                   &cellCfg->prachRscInfo.prachInfo[idx]);
1910          }
1911       }
1912    }
1913    return;
1914 }
1915
1916 /**
1917  * @brief This function performs RGR cell initialization
1918  *
1919  * @details
1920  *
1921  *     Function: rgSCHUtlRgrCellCfg
1922  *     Purpose:  This function initialises the cell with RGR configuration
1923  *               and slot related initialization.
1924  *
1925  *     Invoked by: Scheduler
1926  *
1927  *  @param[in]  RgSchCellCb       *cell
1928  *  @param[in]  RgrCellCfg        *cellCfg
1929  *  @param[in]  RgSchErrInfo      *errInfo
1930  *  @return     Void
1931  *
1932  **/
1933 S16 rgSCHUtlRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cellCfg,RgSchErrInfo *errInfo)
1934 {
1935    uint8_t         i;
1936    uint8_t         sfn=0;
1937    uint8_t         sfNum = 0;
1938    RgSchDlSf       *sf;
1939    CmLteTimingInfo frm;
1940    uint8_t         ulDlCfgIdx = cellCfg->ulDlCfgIdx;
1941    uint8_t         maxslots ;
1942    uint8_t         maxDlslots;
1943    S16             ret = ROK;
1944    uint16_t        bw;         /*!< Number of RBs in the cell */
1945    
1946    memset(&frm,0,sizeof(CmLteTimingInfo));
1947
1948    /* ccpu00132657-MOD- Determining DLSF array size independent of DELTAS */
1949    maxDlslots = rgSchTddNumDlSubfrmTbl[ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
1950    maxslots = 2 * maxDlslots;
1951    cell->numDlSubfrms = maxslots;
1952 /* ACC-TDD <ccpu00130639> */
1953    cell->tddHqSfnCycle = -1;
1954    cell->ulDlCfgIdx = ulDlCfgIdx;
1955
1956    /* PRACH Occasions Initialization */
1957    rgSCHUtlPrachCfgInit(cell, cellCfg);
1958
1959    /* ccpu00132658- Moved out of below for loop since the updating rbgSize and 
1960     * bw are independent of sfNum*/
1961    /* determine the RBG size and no of RBGs for the configured
1962     * DL BW */
1963    if (cell->bwCfg.dlTotalBw > 63)
1964    {
1965       cell->rbgSize  = 4;
1966    }
1967    else if (cell->bwCfg.dlTotalBw > 26)
1968    {
1969       cell->rbgSize  = 3;
1970    }
1971    else if (cell->bwCfg.dlTotalBw > 10)
1972    {
1973       cell->rbgSize  = 2;
1974    }
1975    else
1976    {
1977       cell->rbgSize  = 1;
1978    }
1979    cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
1980
1981    bw    = cell->bwCfg.dlTotalBw;
1982
1983    rgSCHUtlAllocSBuf(cell->instIdx,
1984                (Data **)&cell->subFrms, sizeof(RgSchDlSf *) * maxslots);
1985    if (cell->subFrms == NULLP)
1986    {
1987       return RFAILED;
1988    }
1989
1990    /* Create memory for each frame. */
1991    for(i = 0; i < maxslots; i++)
1992    {
1993       while(rgSchTddUlDlSubfrmTbl[ulDlCfgIdx][sfNum] ==
1994             RG_SCH_TDD_UL_slot)
1995       {
1996          sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
1997       }
1998
1999       rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf, sizeof(RgSchDlSf));
2000       if (sf == NULLP)
2001       {
2002          break;
2003       }
2004       memset(sf, 0, sizeof(*sf));
2005
2006 #ifdef LTE_ADV
2007       if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2008       {
2009          break;
2010       }
2011 #endif
2012       sf->sfNum = sfNum;
2013       sf->bw    = bw;
2014 #ifdef LTEMAC_SPS
2015    /* Mark SPS bandwidth to be occupied */
2016    sf->bwAlloced = ((cellCfg->spsCfg.maxSpsDlBw +
2017       cell->rbgSize - 1)/cell->rbgSize) * cell->rbgSize;
2018    sf->spsAllocdBw = 0;
2019    sf->type2End = sf->bwAlloced/cell->rbgSize;
2020 #else
2021    sf->bwAlloced = 0;
2022    /* Fix for ccpu00123918*/
2023    sf->type2Start = 0;
2024 #endif /* LTEMAC_SPS */
2025       /* Initialize the ackNakRepQ here */
2026 #ifdef RG_MAC_MEASGAP
2027       cmLListInit (&(sf->ackNakRepQ));
2028 #endif
2029       cell->subFrms[i] = sf;
2030       sfNum = (sfNum+1) % RGSCH_NUM_SUB_FRAMES;
2031    }
2032    if (i != maxslots)
2033    {
2034       for (; i > 0; i--)
2035       {
2036          /* ccpu00117052 - MOD - Passing double pointer
2037          for proper NULLP assignment*/
2038          rgSCHUtlFreeSBuf(cell->instIdx,
2039                (Data **)(&(cell->subFrms[i-1])), sizeof(RgSchDlSf));
2040 #ifdef LTE_ADV
2041          rgSCHLaaDeInitDlSfCb(cell, sf);
2042 #endif
2043       }
2044       /* ccpu00117052 - MOD - Passing double pointer
2045       for proper NULLP assignment*/
2046       rgSCHUtlFreeSBuf(cell->instIdx,
2047             (Data **)(&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2048
2049       return RFAILED;
2050    }
2051
2052    if (cell->sc.apis == NULLP)
2053    {
2054       cell->sc.apis = &rgSchCmnApis;
2055    }
2056    ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2057
2058    if (ret != ROK)
2059    {
2060       /* ccpu00132286- Removed deletion of sf nodes as the deletion will be 
2061        * happening during CellDelete. Added return handling to provide negative
2062        * confirm*/
2063       return (ret);
2064    }
2065
2066    /* Release the slots and thereby perform the initialization */
2067    for (i = 0; i < maxslots; i++)
2068    {
2069      if((i > 0) && (i%maxDlslots == 0))
2070      {
2071       sfn++;
2072      }
2073      frm.sfn = sfn;
2074      frm.slot = cell->subFrms[i]->sfNum;
2075      rgSCHUtlDlRlsSubFrm(cell, frm);
2076    }
2077
2078    return (ret);
2079 }
2080
2081 #else
2082 \f
2083 /**
2084  * @brief This function performs scheduler related cell creation
2085  *
2086  * @details
2087  *
2088  *     Function: rgSCHUtlRgrCellCfg
2089  *     Purpose:  This function creates the slots needed for the
2090  *               cell. It then peforms init of the scheduler by calling
2091  *               scheduler specific cell init function.
2092  *
2093  *     Invoked by: Scheduler
2094  *
2095  *  @param[in]  RgSchCellCb          *cell
2096  *  @param[in]  RgrCellCfg        *cellCfg
2097  *  @param[in]  RgSchErrInfo         *errInfo
2098  *  @return     Void
2099  *
2100  **/
2101 S16 rgSCHUtlRgrCellCfg(RgSchCellCb *cell,RgrCellCfg *cellCfg,RgSchErrInfo *errInfo)
2102 {
2103    uint8_t         i;
2104    RgSchDlSf       *sf;
2105    CmLteTimingInfo frm;
2106    S16             ret;
2107    Inst            inst = cell->instIdx;
2108    /* LTE_ADV_FLAG_REMOVED_START */
2109    uint16_t        len;
2110    len = (uint16_t)((cell->bwCfg.dlTotalBw % 8 == 0) ? (cell->bwCfg.dlTotalBw/8) : (cell->bwCfg.dlTotalBw/8 + 1)); /*KW fix for LTE_ADV */
2111    /* LTE_ADV_FLAG_REMOVED_END */
2112
2113    memset(&frm,0,sizeof(CmLteTimingInfo));
2114
2115    /* determine the RBG size and no of RBGs for the configured
2116     * DL BW */
2117    if (cell->bwCfg.dlTotalBw > 63)
2118    {
2119       cell->rbgSize  = 4;
2120    }
2121    else if (cell->bwCfg.dlTotalBw > 26)
2122    {
2123       cell->rbgSize  = 3;
2124    }
2125    else if (cell->bwCfg.dlTotalBw > 10)
2126    {
2127       cell->rbgSize  = 2;
2128    }
2129    else
2130    {
2131       cell->rbgSize  = 1;
2132    }
2133    cell->noOfRbgs = RGSCH_CEIL(cell->bwCfg.dlTotalBw, cell->rbgSize);
2134    /* Create memory for each frame. */
2135    /* Changing loop limit from
2136       RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2137    for(i = 0; i < RGSCH_NUM_DL_slotS; i++)
2138    {
2139       rgSCHUtlAllocSBuf(inst, (Data **)&sf, sizeof(RgSchDlSf));
2140       if (sf == NULLP)
2141       {
2142          break;
2143       }
2144       memset(sf, 0, sizeof(*sf));
2145
2146 #ifdef LTE_ADV
2147       if (ROK != rgSCHLaaInitDlSfCb(cell, sf))
2148       {
2149          break;
2150       }
2151 #endif
2152       /* Doing MOD operation before assigning value of i */
2153       sf->sfNum = i % RGSCH_NUM_SUB_FRAMES;
2154       sf->bw    = cell->bwCfg.dlTotalBw;
2155       /* Initialize the ackNakRepQ here */
2156 #ifdef RG_MAC_MEASGAP
2157       cmLListInit (&(sf->ackNakRepQ));
2158 #endif
2159       cell->subFrms[i] = sf;
2160       /* LTE_ADV_FLAG_REMOVED_START */
2161       if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2162       {
2163          /*initialize the RNTP Buffer*/
2164          if(rgSchDSFRRntpInfoInit(&sf->rntpInfo, cell, sf->bw))
2165          {
2166             return RFAILED; 
2167          }
2168       }
2169
2170       if (cell->lteAdvCb.sfrCfg.status == RGR_ENABLE)
2171       {
2172          /*initialise the pools of CC and CE*/
2173          if(rgSchSFRTotalPoolInit(cell, sf))
2174          {
2175             return RFAILED; 
2176          }
2177       }
2178       /* LTE_ADV_FLAG_REMOVED_END */
2179    }
2180
2181    /* LTE_ADV_FLAG_REMOVED_START */
2182    /* Allocate memory for "scheduled UE" Info */
2183    if (cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE)
2184    {    
2185       if((rgSCHUtlAllocSBuf(inst, (Data**)&(cell->rntpAggrInfo.val),
2186                   (len * sizeof(uint8_t)))) != ROK)
2187       {
2188          DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for RNTP Alloc");
2189          return RFAILED;
2190       }
2191       cell->rntpAggrInfo.pres = PRSNT_NODEF;
2192       cell->rntpAggrInfo.len  = len;
2193    }     
2194    /* LTE_ADV_FLAG_REMOVED_END */
2195
2196    /* Changing loop limit from
2197       RGSCH_NUM_SUB_FRAMES to RGSCH_NUM_DL_slotS */
2198    if (i != RGSCH_NUM_DL_slotS)
2199    {
2200       for (; i > 0; i--)
2201       {
2202          /* ccpu00117052 - MOD - Passing double pointer
2203          for proper NULLP assignment*/
2204          rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i-1])),
2205                sizeof(RgSchDlSf));
2206 #ifdef LTE_ADV
2207          rgSCHLaaDeInitDlSfCb(cell, sf);
2208 #endif
2209       }
2210       return RFAILED;
2211    }
2212
2213    if (cell->sc.apis == NULLP)
2214    {
2215       cell->sc.apis = &rgSchCmnApis;
2216    }
2217
2218    /* Release the slots and thereby perform the initialization */
2219    for (i = 0; i < RGSCH_NUM_DL_slotS; i++)
2220    {
2221       if (i >= RGSCH_NUM_SUB_FRAMES)
2222       {
2223          /* [ccpu00123828]-MOD-The below statement sfn += 1incorrectly modified
2224           * the value of sfn for i>=10 thru 19. Correct way is to assign
2225           it to one */
2226          frm.sfn = 1;
2227       }
2228       frm.slot = i % RGSCH_NUM_SUB_FRAMES;
2229       rgSCHUtlDlRlsSubFrm(cell, frm);
2230    }
2231
2232    ret = cell->sc.apis->rgSCHRgrCellCfg(cell, cellCfg, errInfo);
2233    if (ret != ROK)
2234    {
2235       errInfo->errCause = RGSCHERR_SCH_CFG;
2236       return RFAILED;
2237    }
2238 #ifdef EMTC_ENABLE
2239       if(cell->emtcEnable)
2240       {
2241          /* TODO: Repetition framework in RGR and APP */
2242          if (rgSCHUtlEmtcResMngmtInit(
2243                   cell, 
2244                   RGSCH_IOT_PDSCH_POOLSZ, RGSCH_IOT_PDSCH_DELTA, cellCfg->bwCfg.dlTotalBw,
2245                   RGSCH_IOT_PUSCH_POOLSZ, RGSCH_IOT_PUSCH_DELTA, RGSCH_IOT_PUSCH_MAXFREQSZ,
2246                   RGSCH_IOT_PUCCH_POOLSZ, RGSCH_IOT_PUCCH_DELTA, RGSCH_IOT_PUCCH_MAXFREQSZ) != ROK)
2247          {
2248             errInfo->errCause = RGSCHERR_SCH_CFG;
2249             return RFAILED;
2250          }
2251       }
2252 #endif
2253
2254    return (ret);
2255 }
2256 #endif
2257
2258 \f
2259 /**
2260  * @brief This function performs the cell reconfiguration at RGR interface
2261  *
2262  * @details
2263  *
2264  *     Function: rgSCHUtlRgrCellRecfg
2265  *     Purpose:  This function updates the reconfigurable parameters
2266  *               on the cell control block for the scheduler.
2267  *
2268  *     Invoked by: Scheduler
2269  *
2270  *  @param[in]  RgSchCellCb          *cell
2271  *  @param[in]  RgrCellCfg        *cellCfg
2272  *  @param[in]  RgSchErrInfo         *errInfo
2273  *  @return     Void
2274  *
2275  **/
2276 S16 rgSCHUtlRgrCellRecfg(RgSchCellCb *cell,RgrCellRecfg *recfg,RgSchErrInfo *err)
2277 {
2278    return (cell->sc.apis->rgSCHRgrCellRecfg(cell, recfg, err));
2279 }
2280
2281
2282 \f
2283 /**
2284  * @brief This function returns the Y value of UE for a sub frame
2285  *
2286  * @details
2287  *
2288  *     Function: rgSCHUtlFreeCell
2289  *     Purpose:  This function updates the value of Y stored in the
2290  *               UE control block. It uses the previously computed
2291  *               value for computing for this slot.
2292  *
2293  *     Invoked by: Scheduler
2294  *
2295  *  @param[in]  RgSchCellCb          *cell
2296  *  @return     Void
2297  *
2298  **/
2299 S16 rgSCHUtlFreeCell(RgSchCellCb  *cell)
2300 {
2301    uint8_t          i;
2302    CmLListCp        *lst;
2303    RgSchPdcch       *pdcch;
2304    RgSchPdcchInfo   *pdcchInfo;
2305    RgSchPhichInfo   *phichInfo;
2306    RgSchPhich       *phich;
2307    Inst             inst = cell->instIdx;
2308    uint8_t          maxslots;
2309 #ifdef LTE_TDD
2310    RgSchRaReqInfo *raReqInfo;
2311    uint8_t         idx;
2312 #endif
2313
2314 #ifdef LTE_TDD
2315    maxslots = cell->numDlSubfrms;
2316 #else
2317    maxslots = RGSCH_NUM_DL_slotS;
2318 #endif
2319
2320
2321    /* Invoke the index for scheduler, cell deletion */
2322    cell->sc.apis->rgSCHFreeCell(cell);
2323
2324    /* Release the slots allocated               */
2325    for (i = 0; i < maxslots; i++)
2326    {
2327 #ifdef LTE_ADV
2328       rgSCHLaaDeInitDlSfCb(cell, cell->subFrms[i]);
2329 #endif
2330       pdcchInfo = &cell->subFrms[i]->pdcchInfo;
2331       /* ccpu00117052 - MOD - Passing double pointer
2332       for proper NULLP assignment*/
2333       rgSCHUtlFreeSBuf(inst, (Data **)(&(pdcchInfo->map)),
2334             (pdcchInfo->nCce + 7) >> 3);
2335       while (pdcchInfo->pdcchs.first != NULLP)
2336       {
2337          pdcch = (RgSchPdcch *)pdcchInfo->pdcchs.first->node;
2338          cmLListDelFrm(&pdcchInfo->pdcchs, pdcchInfo->pdcchs.first);
2339       /* ccpu00117052 - MOD - Passing double pointer
2340       for proper NULLP assignment*/
2341          rgSCHUtlFreeSBuf(inst, (Data **)&pdcch, sizeof(RgSchPdcch));
2342       }
2343
2344       phichInfo = &cell->subFrms[i]->phichInfo;
2345       while(phichInfo->phichs.first != NULLP)
2346       {
2347          phich = (RgSchPhich *)phichInfo->phichs.first->node;
2348          cmLListDelFrm(&phichInfo->phichs, phichInfo->phichs.first);
2349          RGSCH_PHICH_FREE(inst, phich, sizeof(RgSchPhich));
2350       }
2351
2352       /* LTE_ADV_FLAG_REMOVED_START */
2353       /*releasing SFR pool entries*/
2354       rgSchSFRTotalPoolFree(&cell->subFrms[i]->sfrTotalPoolInfo, cell);
2355
2356       /*releasing dsfr rntp pattern info*/
2357       rgSchDSFRRntpInfoFree(&cell->subFrms[i]->rntpInfo, cell, 
2358                                        cell->bwCfg.dlTotalBw);
2359       /* LTE_ADV_FLAG_REMOVED_END */
2360
2361       /* ccpu00117052 - MOD - Passing double pointer
2362       for proper NULLP assignment*/
2363       rgSCHUtlFreeSBuf(inst, (Data **)(&(cell->subFrms[i])), sizeof(RgSchDlSf));
2364    }
2365 #ifdef LTE_TDD
2366    /* Release the slot pointers */
2367    /* ccpu00117052 - MOD - Passing double pointer
2368    for proper NULLP assignment*/
2369    rgSCHUtlFreeSBuf(inst,
2370          (Data **) (&(cell->subFrms)), sizeof(RgSchDlSf *) * maxslots);
2371
2372    for(idx=0; idx < cell->raInfo.lstSize; idx++)
2373    {
2374       lst = &cell->raInfo.raReqLst[idx];
2375       while (lst->first != NULLP)
2376       {
2377          raReqInfo = (RgSchRaReqInfo *)lst->first->node;
2378          cmLListDelFrm(lst, &raReqInfo->raReqLstEnt);
2379          /* ccpu00117052 - MOD - Passing double pointer
2380          for proper NULLP assignment*/
2381          rgSCHUtlFreeSBuf(inst,(Data **)&raReqInfo, sizeof(RgSchRaReqInfo));
2382       }
2383    }
2384    /* ccpu00117052 - MOD - Passing double pointer
2385    for proper NULLP assignment*/
2386    rgSCHUtlFreeSBuf(inst,
2387          (Data **)(&(cell->raInfo.raReqLst)),
2388             sizeof(CmLListCp) * (cell->raInfo.lstSize));
2389 #endif
2390
2391    /* Release allocated pdcchs */
2392    lst = &cell->pdcchLst;
2393    while (lst->first != NULLP)
2394    {
2395       pdcch = (RgSchPdcch *)lst->first->node;
2396       cmLListDelFrm(lst, &pdcch->lnk);
2397 #ifdef EMTC_ENABLE
2398       if(cell->emtcEnable)
2399       {
2400          rgSCHEmtcPdcchFree(cell, pdcch);
2401          rgSCHUtlEmtcResMngmtDeinit(cell);
2402       }
2403 #endif
2404       /* ccpu00117052 - MOD - Passing double pointer
2405       for proper NULLP assignment*/
2406       rgSCHUtlFreeSBuf(inst,(Data **)&pdcch, sizeof(RgSchPdcch));
2407    }
2408 #ifdef LTE_ADV
2409    rgSCHLaaFreeLists(cell);
2410 #endif
2411
2412    /* LTE_ADV_FLAG_REMOVED_START */
2413    /* releasing RNTP Aggregation Info from CellCb*/
2414    rgSchDSFRRntpInfoFree(&cell->rntpAggrInfo, cell, cell->bwCfg.dlTotalBw);
2415    /* LTE_ADV_FLAG_REMOVED_END */
2416
2417    return ROK;
2418 }
2419
2420 \f
2421 /**
2422  * @brief This function adds the UE to scheduler
2423  *
2424  * @details
2425  *
2426  *     Function: rgSCHUtlRgrUeCfg
2427  *     Purpose:  This function performs addition of UE to scheduler
2428  *               1. First, it updates the Y table in the UE
2429  *               2. Then, it calls the scheduler's handler for UE addition
2430  *
2431  *     Invoked by: Scheduler
2432  *
2433  *  @param[in]  RgSchCellCb          *cell
2434  *  @param[in]  RgSchUeCb            *ue
2435  *  @param[in]  RgrUeCfg             *cfg
2436  *  @param[in]  RgSchErrInfo            *err
2437  *  @return     S16
2438  *
2439  **/
2440 S16 rgSCHUtlRgrUeCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeCfg *cfg,RgSchErrInfo *err)
2441 {
2442
2443    /* Assign TM 1 as UE's default TM */
2444    ue->mimoInfo.txMode = RGR_UE_TM_1;
2445    ue->txModeTransCmplt = TRUE;
2446    cmInitTimers(&ue->txModeTransTmr, 1);
2447    if (cfg->txMode.pres == PRSNT_NODEF)
2448    {
2449       /* DL MU-MIMO not supported */
2450       if (cfg->txMode.txModeEnum == RGR_UE_TM_5)
2451       {
2452          err->errCause = RGSCHERR_SCH_CFG;
2453          return RFAILED;
2454       }
2455       ue->mimoInfo.txMode = cfg->txMode.txModeEnum;
2456    }
2457    ue->ul.ulTxAntSel = cfg->ulTxAntSel;
2458    ue->mimoInfo.cdbkSbstRstrctn = cfg->ueCodeBookRstCfg;
2459 #ifdef TFU_UPGRADE
2460    ue->ueCatEnum = cfg->ueCatEnum;
2461    if ((cfg->puschDedCfg.bACKIdx > 15) ||
2462        (cfg->puschDedCfg.bCQIIdx > 15) ||
2463        (cfg->puschDedCfg.bRIIdx > 15))
2464    {
2465       err->errCause = RGSCHERR_SCH_CFG;
2466       return RFAILED;
2467    }
2468    ue->ul.betaHqOffst = cfg->puschDedCfg.bACKIdx;
2469    ue->ul.betaCqiOffst = cfg->puschDedCfg.bCQIIdx;
2470    ue->ul.betaRiOffst = cfg->puschDedCfg.bRIIdx;
2471 #endif
2472    ue->csgMmbrSta = cfg->csgMmbrSta;
2473 #ifdef RG_PFS_STATS
2474    memset(&ue->pfsStats, 0, sizeof(RgSchPfsStats));
2475 #endif
2476    /* Call the handler of the scheduler based on cell configuration */
2477    return (cell->sc.apis->rgSCHRgrUeCfg(cell, ue, cfg, err));
2478 }
2479 /* Start : LTEMAC_2.1_DEV_CFG */
2480 \f
2481 /**
2482  * @brief This function adds a service to scheduler
2483  *
2484  * @details
2485  *
2486  *     Function: rgSCHUtlRgrLcCfg
2487  *     Purpose:  This function performs addition of service to scheduler
2488  *               The addition is performed for each direction based
2489  *               the direction field of the configuration
2490  *
2491  *     Invoked by: Scheduler
2492  *
2493  *  @param[in]  RgSchCellCb          *cell
2494  *  @param[in]  RgSchUeCb            *ue
2495  *  @param[in]  RgSchDlLcCb          *dlLc
2496  *  @param[in]  RgrLchCfg            *cfg
2497  *  @param[in]  RgSchErrInfo         *err
2498  *  @return     S16
2499  *
2500  **/
2501 S16 rgSCHUtlRgrLcCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *dlLc,RgrLchCfg *cfg,RgSchErrInfo *errInfo)
2502 {
2503    return (cell->sc.apis->rgSCHRgrLchCfg(cell, ue, dlLc, cfg, errInfo));
2504 }
2505
2506 \f
2507 /**
2508  * @brief This function modifies a service to scheduler
2509  *
2510  * @details
2511  *
2512  *     Function: rgSCHUtlRgrLcRecfg
2513  *     Purpose:  This function performs modification of a service in
2514  *               scheduler. The modification is performed for each direction
2515  *               based the direction field of the configuration
2516  *
2517  *     Invoked by: Scheduler
2518  *
2519  *  @param[in]  RgSchCellCb          *cell
2520  *  @param[in]  RgSchUeCb            *ue
2521  *  @param[in]  RgSchDlLcCb          *dlLc
2522  *  @param[in]  RgrLchRecfg          *recfg
2523  *  @param[in]  RgSchErrInfo         *err
2524  *  @return     S16
2525  *
2526  **/
2527 S16 rgSCHUtlRgrLcRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *dlLc,RgrLchRecfg *recfg,RgSchErrInfo *err)
2528 {
2529    return (cell->sc.apis->rgSCHRgrLchRecfg(cell, ue, dlLc, recfg, err));
2530 }
2531
2532 /**
2533  * @brief This function deletes a Lc in scheduler
2534  *
2535  * @details
2536  *
2537  *     Function: rgSCHUtlRgrLcDel
2538  *     Purpose:  This function performs deletion of Lc in scheduler
2539  *
2540  *     Invoked by: Scheduler
2541  *
2542  *  @param[in]  RgSchCellCb   *cell
2543  *  @param[in]  RgSchUeCb     *ue
2544  *  @param[in]  CmLteLcId     lcId
2545  *  @param[in]  uint8_t            lcgId
2546  *  @return     S16
2547  *
2548  **/
2549 S16 rgSCHUtlRgrLcDel(RgSchCellCb *cell,RgSchUeCb *ue,CmLteLcId lcId,uint8_t lcgId)
2550 {
2551    cell->sc.apis->rgSCHRgrLchDel(cell, ue, lcId, lcgId);
2552
2553    return  (ROK);
2554 } /* rgSCHUtlRgrLcDel */
2555
2556 /**
2557  * @brief This function adds a service to scheduler
2558  *
2559  * @details
2560  *
2561  *     Function: rgSCHUtlRgrLcgCfg
2562  *     Purpose:  This function performs addition of service to scheduler
2563  *               The addition is performed for each direction based
2564  *               the direction field of the configuration
2565  *
2566  *     Invoked by: Scheduler
2567  *
2568  *  @param[in]  RgSchCellCb          *cell
2569  *  @param[in]  RgSchUeCb            *ue
2570  *  @param[in]  RgrLchCfg            *cfg
2571  *  @param[in]  RgSchErrInfo         *err
2572  *  @return     S16
2573  *
2574  **/
2575 S16 rgSCHUtlRgrLcgCfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrLcgCfg *cfg,RgSchErrInfo *errInfo)
2576 {
2577    return (cell->sc.apis->rgSCHRgrLcgCfg(cell, ue, &(ue->ul.lcgArr[cfg->ulInfo.lcgId]), cfg, errInfo));
2578 }
2579
2580 \f
2581 /**
2582  * @brief This function modifies a service to scheduler
2583  *
2584  * @details
2585  *
2586  *     Function: rgSCHUtlRgrLcgRecfg
2587  *     Purpose:  This function performs modification of a service in
2588  *               scheduler. The modification is performed for each direction
2589  *               based the direction field of the configuration
2590  *
2591  *     Invoked by: Scheduler
2592  *
2593  *  @param[in]  RgSchCellCb          *cell
2594  *  @param[in]  RgSchUeCb            *ue
2595  *  @param[in]  RgrLcgRecfg          *recfg
2596  *  @param[in]  RgSchErrInfo         *err
2597  *  @return     S16
2598  *
2599  **/
2600 S16 rgSCHUtlRgrLcgRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrLcgRecfg *recfg,RgSchErrInfo *err)
2601 {
2602    return (cell->sc.apis->rgSCHRgrLcgRecfg(cell, ue, &(ue->ul.lcgArr[recfg->ulRecfg.lcgId]), recfg, err));
2603 } /* rgSCHUtlRgrLcRecfg */
2604
2605 /**
2606  * @brief This function modifies a service to scheduler
2607  *
2608  * @details
2609  *
2610  *     Function: rgSCHUtlRgrLcgDel
2611  *     Purpose:  This function performs modification of a service in
2612  *               scheduler. The modification is performed for each direction
2613  *               based the direction field of the configuration
2614  *
2615  *     Invoked by: Scheduler
2616  *
2617  *  @param[in]  RgSchCellCb   *cell
2618  *  @param[in]  RgSchUeCb     *ue
2619  *  @param[in]  RgrDel        *lcDelInfo
2620  *  @return     S16
2621  *
2622  **/
2623 Void rgSCHUtlRgrLcgDel(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t lcgId)
2624 {
2625    cell->sc.apis->rgSCHFreeLcg(cell, ue, &ue->ul.lcgArr[lcgId]);
2626
2627   /* Stack Crash problem for TRACE5 changes. added the return below . */
2628  return;
2629
2630 } /* rgSCHUtlRgrLcgDel */
2631
2632
2633 /* End: LTEMAC_2.1_DEV_CFG */
2634
2635 /**
2636  * @brief This function is a wrapper to call scheduler specific API.
2637  *
2638  * @details
2639  *
2640  *     Function: rgSCHUtlDoaInd
2641  *     Purpose:  Updates the DOA for the UE
2642  *
2643  *     Invoked by: TOM
2644  *
2645  *  @param[in]  RgSchCellCb        *cell
2646  *  @param[in]  RgSchUeCb          *ue
2647  *  @param[in]  TfuDoaRpt          *doaRpt
2648  *  @return  Void
2649  *
2650  **/
2651 Void  rgSCHUtlDoaInd(RgSchCellCb  *cell,RgSchUeCb *ue,TfuDoaRpt *doaRpt)
2652 {
2653    ue->mimoInfo.doa.pres = PRSNT_NODEF;
2654    ue->mimoInfo.doa.val = doaRpt->doa;
2655    return;
2656 }
2657 \f
2658 /**
2659  * @brief This function is a wrapper to call scheduler specific API.
2660  *
2661  * @details
2662  *
2663  *     Function: rgSCHUtlDlCqiInd
2664  *     Purpose:  Updates the DL CQI for the UE
2665  *
2666  *     Invoked by: TOM
2667  *
2668  *  @param[in]  RgSchCellCb        *cell
2669  *  @param[in]  RgSchUeCb          *ue
2670  *  @param[in]  TfuDlCqiRpt        *dlCqiRpt
2671  *  @param[in]  CmLteTimingInfo    timingInfo
2672  *  @return  Void
2673  *
2674  **/
2675 Void rgSCHUtlDlCqiInd(RgSchCellCb *cell,RgSchUeCb  *ue,TfuDlCqiRpt *dlCqiRpt,CmLteTimingInfo timingInfo)
2676 {
2677    RgSchCellCb        *sCellCb = NULLP;
2678    if (dlCqiRpt->isPucchInfo)
2679    {
2680       sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pucchCqi.cellIdx]->cell;
2681       sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
2682             (Void *)&dlCqiRpt->dlCqiInfo.pucchCqi, timingInfo);
2683    }
2684    else
2685    {
2686       uint32_t idx;
2687       for (idx = 0; idx < dlCqiRpt->dlCqiInfo.pusch.numOfCells; idx++)
2688       {
2689          sCellCb = ue->cellInfo[dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx].cellIdx]->cell;
2690          sCellCb->sc.apis->rgSCHDlCqiInd(sCellCb, ue, dlCqiRpt->isPucchInfo, \
2691                (Void *)&dlCqiRpt->dlCqiInfo.pusch.puschCqi[idx], timingInfo);
2692       }
2693    }
2694    return;
2695 }
2696
2697 \f
2698 #ifdef TFU_UPGRADE
2699 /**
2700  * @brief This function is a wrapper to call scheduler specific API.
2701  *
2702  * @details
2703  *
2704  *     Function: rgSCHUtlSrsInd
2705  *     Purpose:  Updates the UL SRS for the UE
2706  *
2707  *     Invoked by: TOM
2708  *
2709  *  @param[in]  RgSchCellCb        *cell
2710  *  @param[in]  RgSchUeCb          *ue
2711  *  @param[in]  TfuSrsRpt*     srsRpt
2712  *  @param[in]  CmLteTimingInfo    timingInfo
2713  *  @return  Void
2714  *
2715  **/
2716 Void rgSCHUtlSrsInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuSrsRpt *srsRpt,CmLteTimingInfo timingInfo)
2717 {
2718    cell->sc.apis->rgSCHSrsInd(cell, ue, srsRpt, timingInfo);
2719    return;
2720 }
2721 #endif
2722
2723 /**
2724  * @brief This function is a wrapper to call scheduler specific API.
2725  *
2726  * @details
2727  *
2728  *     Function: rgSCHUtlDlTARpt
2729  *     Purpose:  Reports PHY TA for a UE.
2730  *
2731  *     Invoked by: TOM
2732  *
2733  *  @param[in]  RgSchCellCb        *cell
2734  *  @param[in]  RgSchUeCb          *ue
2735  *  @return  Void
2736  *
2737  **/
2738 Void rgSCHUtlDlTARpt(RgSchCellCb *cell,RgSchUeCb *ue)
2739 {
2740    cell->sc.apis->rgSCHDlTARpt(cell, ue);
2741    return;
2742 }
2743
2744 \f
2745 /**
2746  * @brief This function is a wrapper to call scheduler specific API.
2747  *
2748  * @details
2749  *
2750  *     Function: rgSCHUtlDlRlsSubFrm
2751  *     Purpose:  Releases scheduler Information from DL SubFrm.
2752  *
2753  *     Invoked by: DHM
2754  *
2755  *  @param[in]   RgSchCellCb     *cell
2756  *  @param[out]  CmLteTimingInfo subFrm
2757  *  @return  Void
2758  *
2759  **/
2760 Void rgSCHUtlDlRlsSubFrm(RgSchCellCb *cell,CmLteTimingInfo subFrm)
2761 {
2762    cell->sc.apis->rgSCHDlRlsSubFrm(cell, subFrm);
2763    return;
2764 }
2765
2766 #ifdef TFU_UPGRADE
2767 /**
2768  * @brief This API is invoked to update the AperCQI trigger
2769  *        weight.
2770  *
2771  * @details
2772  *
2773  *     Function : rgSCHUtlUpdACqiTrigWt
2774  *              - If HqFdbk is ACK then add up weight corresponding
2775  *                to ACK to the AcqiTrigWt.
2776  *              - If HqFdbk is NACK then add up weight corresponding
2777  *                to NACK to the AcqiTrigWt.
2778  *              - If AcqiTrigWt crosses threshold then trigger
2779  *                grant req for APERCQI to SCH.
2780  *
2781  *  @param[in]  RgSchUeCb       *ue
2782  *  @param[in]  uint8_t              isAck 
2783  *
2784  *  @return Void
2785  **/
2786 Void rgSCHUtlUpdACqiTrigWt(RgSchUeCb *ue,RgSchUeCellInfo *cellInfo,uint8_t isAck )
2787 {
2788 #ifdef LTE_ADV
2789    uint8_t triggerSet  = 0;
2790    uint8_t sIdx        = 0;
2791 #endif
2792
2793    if (isAck == TFU_HQFDB_ACK)
2794    {
2795       cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_ACK_WGT;
2796    }
2797    else
2798    {
2799       cellInfo->acqiCb.aCqiTrigWt += RG_APER_CQI_NACK_WGT;
2800    }
2801
2802    if (cellInfo->acqiCb.aCqiTrigWt > RG_APER_CQI_THRESHOLD_WGT)
2803    {
2804       RgSchCellCb  *cell = ue->cell;
2805       RgSchErrInfo unUsed;
2806
2807       if(ue->dl.reqForCqi)
2808       {
2809          /* Already one ACQI trigger procedure is going on
2810           * which is not yet satisfied. Delaying this request till
2811           * the previous is getting satisfied*/
2812          return;
2813       }
2814
2815      ue->dl.reqForCqi = TRUE;
2816 #ifdef LTE_ADV
2817       rgSchCmnSetCqiReqField(cellInfo,ue,&ue->dl.reqForCqi);
2818       //Reset aCqiTrigWt for all the serving cells for which we have triggered ACQI 
2819       rgSCHTomUtlGetTrigSet(cell, ue, ue->dl.reqForCqi, &triggerSet);
2820       for (sIdx = 0; sIdx < CM_LTE_MAX_CELLS; sIdx++)
2821       {
2822          /* The Aperiodic requested for SCell index sIdx */
2823          if ((triggerSet >> (7 - sIdx)) & 0x01)
2824          {
2825             /* The Aperiodic request for SCell index sIdx */
2826             ue->cellInfo[sIdx]->acqiCb.aCqiTrigWt = 0;
2827          }
2828       }
2829  
2830 #endif
2831       /* Force SCH to send UL grant by indicating fake SR.
2832        * If this UE already in UL SCH Qs this SR Ind will
2833        * be ignored */
2834       rgSCHUtlSrRcvd(cell, ue, cell->crntTime, &unUsed);
2835    }
2836
2837    return;
2838 }
2839 #endif
2840
2841 /**
2842  * @brief This API is invoked to indicate scheduler of a CRC indication.
2843  *
2844  * @details
2845  *
2846  *     Function : rgSCHUtlHdlUlTransInd
2847  *      This API is invoked to indicate scheduler of a CRC indication.
2848  *
2849  *  @param[in]  RgSchCellCb     *cell
2850  *  @param[in]  RgSchUeCb       *ue
2851  *  @param[in]  CmLteTimingInfo timingInfo
2852  *
2853  *  @return Void
2854  **/
2855 Void rgSCHUtlHdlUlTransInd(RgSchCellCb *cell,RgSchUeCb *ue,CmLteTimingInfo timingInfo)
2856 {
2857    cell->sc.apis->rgSCHHdlUlTransInd(cell, ue, timingInfo);
2858    return;
2859 }
2860 #ifdef LTEMAC_SPS
2861 /**
2862  * @brief This API is invoked to indicate scheduler of a CRC failure.
2863  *
2864  * @details
2865  *
2866  *     Function : rgSCHUtlHdlCrcInd
2867  *      This API is invoked to indicate CRC  to scheduler.
2868  *
2869  *  @param[in]  RgSchCellCb     *cell
2870  *  @param[in]  RgSchUeCb       *ue
2871  *  @param[in]  CmLteTimingInfo timingInfo
2872  *
2873  *  @return Void
2874  **/
2875 Void rgSCHUtlHdlCrcInd(RgSchCellCb *cell,RgSchUeCb  *ue,CmLteTimingInfo timingInfo)
2876 {
2877    cell->sc.apis->rgSCHUlCrcInd(cell, ue, timingInfo);
2878    return;
2879 } /* end of rgSCHUtlHdlCrcFailInd */
2880
2881 /**
2882  * @brief This API is invoked to indicate scheduler of a CRC failure.
2883  *
2884  * @details
2885  *
2886  *     Function : rgSCHUtlHdlCrcFailInd
2887  *      This API is invoked to indicate CRC failure to scheduler.
2888  *
2889  *  @param[in]  RgSchCellCb     *cell
2890  *  @param[in]  RgSchUeCb       *ue
2891  *  @param[in]  CmLteTimingInfo timingInfo
2892  *
2893  *  @return Void
2894  **/
2895 Void rgSCHUtlHdlCrcFailInd(RgSchCellCb *cell,RgSchUeCb  *ue,CmLteTimingInfo timingInfo)
2896 {
2897    cell->sc.apis->rgSCHUlCrcFailInd(cell, ue, timingInfo);
2898    return;
2899 } /* end of rgSCHUtlHdlCrcFailInd */
2900 #endif /* LTEMAC_SPS */
2901
2902 \f
2903 /**
2904  * @brief This function is a wrapper to call scheduler specific API.
2905  *
2906  * @details
2907  *
2908  *     Function: rgSCHUtlDlProcAddToRetx
2909  *     Purpose:  This function adds a HARQ process to retransmission
2910  *               queue. This may be performed when a HARQ ack is
2911  *               unsuccessful.
2912  *
2913  *     Invoked by: HARQ feedback processing
2914  *
2915  *  @param[in]  RgSchCellCb*     cell
2916  *  @param[in]  RgSchDlHqProc*   hqP
2917  *  @return  Void
2918  *
2919  **/
2920 Void rgSCHUtlDlProcAddToRetx(RgSchCellCb *cell,RgSchDlHqProcCb *hqP)
2921 {
2922    cell->sc.apis->rgSCHDlProcAddToRetx(cell, hqP);
2923    return;
2924 }
2925
2926 \f
2927 /**
2928  * @brief This function adds a HARQ process TB to transmission
2929  *
2930  * @details
2931  *
2932  *     Function: rgSCHUtlDlHqPTbAddToTx
2933  *     Purpose:  This function a HarqProcess TB to the slot
2934  *               list.
2935  *
2936  *     Invoked by: Scheduler
2937  *
2938  *  @param[in]  RgSubFrm*     subFrm
2939  *  @param[in]  RgDlHqProc*   hqP
2940  *  @param[in]  uint8_t            tbIdx
2941  *  @return  Void
2942  *
2943  **/
2944 Void rgSCHUtlDlHqPTbAddToTx(RgSchDlSf *subFrm,RgSchDlHqProcCb *hqP,uint8_t tbIdx)
2945 {
2946    RgSchUeCb *ue = NULLP;
2947    RgSchCellCb *cell = hqP->hqE->cell;
2948    /* CA Dev Start */
2949    /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
2950    /* ue->cell will always hold PCell information */
2951    if (NULLP == hqP->hqPSfLnk.node)
2952    {
2953       if (hqP->hqE->ue)
2954       {
2955          ue = hqP->hqE->ue;
2956          if(NULLP == ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node)
2957          {
2958             ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)ue;
2959             cmLListAdd2Tail(&cell->subFrms[subFrm->dlIdx]->ueLst, 
2960                   &ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
2961
2962             ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].isPuschHarqRecpPres = FALSE;
2963
2964          }
2965
2966          /* Add Hq proc in particular dlIdx List for this UE 
2967             This list will be used while processing feedback*/
2968          hqP->hqPSfLnk.node = (PTR)hqP;
2969          cmLListAdd2Tail(&ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk); 
2970 #ifdef CA_DBG
2971          {
2972             uint32_t gSCellSchedCount,gPrimarySchedCount;
2973             if(RG_SCH_IS_CELL_SEC(hqP->hqE->ue,hqP->hqE->cell))
2974             {
2975                gSCellSchedCount++;
2976             }else
2977                gPrimarySchedCount++;
2978          }
2979 #endif
2980       }
2981       else if (hqP->hqE->msg4Proc == hqP)
2982       {
2983          /* Msg4 will be scheduled on PCELL only hence add directly to subFrm msg4HqpList */
2984          hqP->hqPSfLnk.node = (PTR)hqP;
2985          cmLListAdd2Tail(&subFrm->msg4HqPLst, &hqP->hqPSfLnk);
2986       }
2987    }
2988    else
2989    {
2990       ue = hqP->hqE->ue; 
2991    }
2992    if((ue) && (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state))
2993          
2994    {   
2995       ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt++;
2996    }
2997    /*totalTbCnt will hold the total number of TBs across all harq Proc from all 
2998     * cells*/
2999
3000    hqP->subFrm = subFrm; 
3001
3002    /* CA Dev End */
3003    return;
3004 }
3005
3006
3007 \f
3008 /**
3009  * @brief This function removes a HARQ process TB from transmission
3010  *
3011  * @details
3012  *
3013  *     Function: rgSCHUtlDlHqPTbRmvFrmTx
3014  *     Purpose:  This function removes a HarqProcess TB to the slot
3015  *               list.
3016  *
3017  *     Invoked by: Scheduler
3018  *
3019  *  @param[in]  RgSubFrm*     subFrm
3020  *  @param[in]  RgDlHqProc*   hqP
3021  *  @param[in]  uint8_t            tbIdx
3022  *  @param[in]  Bool          isRepeting
3023  *  @return  Void
3024  *
3025  **/
3026 Void rgSCHUtlDlHqPTbRmvFrmTx(RgSchDlSf *subFrm,RgSchDlHqProcCb  *hqP,uint8_t tbIdx,Bool isRepeting)
3027 {
3028    RgSchCellCb *cell = NULLP;
3029    /* Check with TDD */
3030    if ((isRepeting) &&
3031          (hqP->hqE->ue->ackNakRepCb.cfgRepCnt !=
3032           hqP->tbInfo[tbIdx].fbkRepCntr))
3033    {
3034       cmLListDelFrm(&subFrm->ackNakRepQ,
3035          &hqP->tbInfo[tbIdx].anRepLnk[hqP->tbInfo[tbIdx].fbkRepCntr]);
3036    }
3037    else
3038    {
3039       if (NULLP != hqP->hqPSfLnk.node)
3040       {
3041          /* CA dev Start */
3042          if (hqP->hqE->msg4Proc == hqP)
3043          {
3044             /* Msg4 will be scheduled on PCELL only hence delete directly from subFrm msg4HqpList */
3045             cmLListDelFrm(&subFrm->msg4HqPLst, &hqP->hqPSfLnk); 
3046          }
3047          else
3048          {
3049             cell = hqP->hqE->cell;
3050             /* Addition of UE to dlSf->ueLst shall be done only to UE's PCell */
3051             /* ue->cell will always hold PCell information */
3052             cmLListDelFrm(&hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst,&hqP->hqPSfLnk); 
3053             if (0 == hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].hqPLst.count)
3054             {
3055
3056                cmLListDelFrm(&cell->subFrms[subFrm->dlIdx]->ueLst, 
3057                      &hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk);
3058                hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].dlSfUeLnk.node = (PTR)NULLP;
3059                hqP->hqE->ue->dl.dlSfHqInfo[cell->cellId][subFrm->dlIdx].totalTbCnt = 0;
3060             }
3061          }
3062          hqP->hqPSfLnk.node = NULLP;
3063       }
3064       hqP->subFrm = NULLP;
3065    }
3066    return;
3067 }
3068
3069 #ifdef LTE_ADV
3070 /**
3071  * @brief Handler for accessing the existing SCellCb identified by the key
3072  * SCellId under the CellCb.
3073  *
3074  * @details
3075  *
3076  *     Function : rgSchUtlGetCellCb
3077  *     
3078  *           
3079  *  @param[in]  *cellCb
3080  *  @param[in]  ueId
3081  *  @return  RgSchUeCb*
3082  **/
3083 RgSchCellCb* rgSchUtlGetCellCb(Inst inst,uint16_t cellId)
3084 {
3085    RgSchCellCb  *cellCb = NULLP; 
3086    uint8_t      strtCellId;
3087    strtCellId = rgSchCb[inst].genCfg.startCellId;
3088    cellCb     = rgSchCb[inst].cells[cellId - strtCellId];
3089
3090    return (cellCb);
3091
3092 }  /* rgSchUtlGetCellCb */
3093
3094 /**
3095  * @brief Handler for deriving the servCellidx
3096  *
3097  * @details
3098  *
3099  *     Function : rgSchUtlGetServCellIdx
3100  *     
3101  *           
3102  *  @param[in]  *cellId
3103  *  @param[in]  RgSchUeCb *ue
3104  *  @return   uint8_t servCellIdx
3105  **/
3106 uint8_t rgSchUtlGetServCellIdx(Inst inst, uint16_t cellId, RgSchUeCb *ue)
3107 {
3108    uint8_t servCellIdx;
3109    uint16_t strtCellId;
3110
3111    strtCellId = rgSchCb[inst].genCfg.startCellId;
3112    servCellIdx = ue->cellIdToCellIdxMap[cellId - strtCellId];
3113    return (servCellIdx);
3114
3115 }  /* rgSchUtlGetCellCb */
3116
3117 /**
3118  * @brief Handler for validating the Cell Id received secondary Cell Addition
3119  *
3120  * @details
3121  *
3122  *     Function : rgSchUtlGetCellId
3123  *     
3124  *           
3125  *  @param[in]  *cellCb
3126  *  @param[in]  ueId
3127  *  @return  RgSchUeCb*
3128  **/
3129 S16 rgSchUtlVldtCellId(Inst inst,uint16_t cellId)
3130 {
3131    uint8_t              strtCellId;
3132
3133    strtCellId = rgSchCb[inst].genCfg.startCellId;
3134    if((cellId >= strtCellId) && ((cellId - strtCellId) < CM_LTE_MAX_CELLS))
3135    {
3136       return ROK;
3137    }
3138    return RFAILED;
3139 }  /* rgSchUtlVldtCellId */
3140
3141 #endif /* LTE_ADV*/
3142 /**
3143  * @brief UE reconfiguration for scheduler
3144  *
3145  * @details
3146  *
3147  *     Function : rgSCHUtlRgrUeRecfg
3148  *
3149  *     This functions updates UE specific scheduler
3150  *     information upon UE reconfiguration
3151  *
3152  *  @param[in]  RgSchCellCb  *cell
3153  *  @param[in]  RgSchUeCb    *ue
3154  *  @param[int] RgrUeRecfg   *ueRecfg
3155  *  @param[out] RgSchErrInfo *err
3156  *  @return  S16
3157  *      -# ROK
3158  *      -# RFAILED
3159  **/
3160 S16 rgSCHUtlRgrUeRecfg(RgSchCellCb *cell,RgSchUeCb *ue,RgrUeRecfg *ueRecfg,RgSchErrInfo *err)
3161 {
3162 /* Changes for UE Category Reconfiguration feature addition */
3163    RgSchCmnUe    *ueSch = RG_SCH_CMN_GET_UE(ue, cell);
3164
3165    /* Changes for UE Category Reconfiguration feature addition */
3166    if (ueRecfg->ueRecfgTypes & RGR_UE_UECAT_RECFG)
3167    {
3168       ueSch->cmn.ueCat = ueRecfg->ueCatEnum-1;
3169 #ifdef TFU_UPGRADE
3170       ue->ueCatEnum = ueRecfg->ueCatEnum;
3171 #endif
3172    } 
3173
3174    /* DL MU-MIMO not supported */
3175    if (ueRecfg->ueRecfgTypes & RGR_UE_TXMODE_RECFG)
3176    {
3177
3178       if (ueRecfg->txMode.pres == PRSNT_NODEF)
3179       {
3180          if (ueRecfg->txMode.txModeEnum == RGR_UE_TM_5)
3181          {
3182             err->errCause = RGSCHERR_SCH_CFG;
3183             return RFAILED;
3184          }
3185 #ifdef LTE_ADV
3186         if(ue->mimoInfo.txMode != ueRecfg->txMode.txModeEnum)
3187          {
3188             /* Decremnt the previos A value for this cell */
3189             ue->f1bCsAVal -= rgSCHUtlGetMaxTbSupp(ue->mimoInfo.txMode);
3190             /* Update A value with the new TM Mode */
3191             ue->f1bCsAVal += rgSCHUtlGetMaxTbSupp(ueRecfg->txMode.txModeEnum);
3192
3193
3194             DU_LOG("\nINFO  -->  SCH : UeReCfg A valie is %d\n",ue->f1bCsAVal);
3195          }
3196 #endif
3197          ue->mimoInfo.txMode = ueRecfg->txMode.txModeEnum;
3198       }
3199    }
3200 #ifdef TFU_UPGRADE
3201    /* [ccpu00123958]-ADD- Check for PUSCH related Reconfig from the bit mask  */
3202     if(ueRecfg->ueRecfgTypes & RGR_UE_PUSCH_RECFG)
3203     {
3204        /* Fix: ccpu00124012 */
3205        /* TODO:: Need to check if this is 
3206           mandatory to be re-configured on UE category re-configuration */
3207        /* ue->ul.betaHqOffst = ueRecfg->puschDedCfg.bACKIdx;
3208           ue->ul.betaCqiOffst = ueRecfg->puschDedCfg.bCQIIdx;
3209           ue->ul.betaRiOffst = ueRecfg->puschDedCfg.bRIIdx;*/
3210     }
3211 #endif
3212    if (ueRecfg->ueRecfgTypes & RGR_UE_ULTXANTSEL_RECFG)
3213    {
3214       ue->ul.ulTxAntSel = ueRecfg->ulTxAntSel;
3215    }
3216    if (ueRecfg->ueRecfgTypes & RGR_UE_CDBKSBST_RECFG)
3217    {
3218       ue->mimoInfo.cdbkSbstRstrctn = ueRecfg->ueCodeBookRstRecfg;
3219    }
3220
3221    /* Commenting here to assign garbage value when it is not set in APP. */
3222    //ue->accessStratumRls = ueRecfg->accessStratumRls;
3223    return (cell->sc.apis->rgSCHRgrUeRecfg(cell, ue, ueRecfg, err));
3224 }  /* rgSCHUtlRgrUeRecfg */
3225
3226 /**
3227  * @brief This function deletes a service from scheduler
3228  *
3229  * @details
3230  *
3231  *     Function: rgSCHUtlFreeDlLc
3232  *     Purpose:  This function is made available through a FP for
3233  *               making scheduler aware of a service being deleted from UE
3234  *
3235  *     Invoked by: BO and Scheduler
3236  *
3237  *  @param[in]  RgSchCellCb*  cell
3238  *  @param[in]  RgSchUeCb*    ue
3239  *  @param[in]  RgSchDlLcCb*  svc
3240  *  @return  Void
3241  **/
3242 Void rgSCHUtlFreeDlLc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb  *svc)
3243 {
3244    cell->sc.apis->rgSCHFreeDlLc(cell, ue, svc);
3245
3246   /* Stack Crash problem for TRACE5 changes. added the return below . */
3247  return;
3248
3249 }
3250
3251 /**
3252  * @brief UE deletion for scheduler
3253  *
3254  * @details
3255  *
3256  *     Function : rgSCHUtlFreeUe
3257  *
3258  *     This functions deletes all scheduler information
3259  *     pertaining to a UE
3260  *
3261  *  @param[in]  RgSchCellCb  *cell
3262  *  @param[in]  RgSchUeCb    *ue
3263  *  @return  Void
3264  **/
3265 Void rgSCHUtlFreeUe(RgSchCellCb *cell,RgSchUeCb *ue)
3266 {
3267 #ifdef LTE_TDD
3268    rgSCHUtlDelUeANFdbkInfo(ue,RGSCH_PCELL_INDEX);
3269 #endif
3270    cell->sc.apis->rgSCHFreeUe(cell, ue);
3271
3272   /* Stack Crash problem for TRACE5 changes. added the return below . */
3273  return;
3274
3275 }  /* rgSCHUtlFreeUe */
3276
3277 /**
3278  * @brief This function updates the scheduler with service for a UE
3279  *
3280  * @details
3281  *
3282  *     Function: rgSCHUtlDlDedBoUpd
3283  *     Purpose:  This function should be called whenever there is a
3284  *               change BO for a service.
3285  *
3286  *     Invoked by: BO and Scheduler
3287  *
3288  *  @param[in]  RgSchCellCb*  cell
3289  *  @param[in]  RgSchUeCb*    ue
3290  *  @param[in]  RgSchDlLcCb*  lc
3291  *  @return  Void
3292  **/
3293 Void rgSCHUtlDlDedBoUpd(RgSchCellCb *cell,RgSchUeCb *ue,RgSchDlLcCb *lc)
3294 {
3295    cell->sc.apis->rgSCHDlDedBoUpd(cell, ue, lc);
3296    return;
3297 }
3298 /**
3299  * @brief Record MSG3 allocation into the UE
3300  *
3301  * @details
3302  *
3303  *     Function : rgSCHUtlRecMsg3Alloc
3304  *
3305  *     This function is invoked to update record msg3 allocation information
3306  *    in the UE when UE is detected for RaCb
3307  *
3308  *  @param[in]  RgSchCellCb     *cell
3309  *  @param[in]  RgSchUeCb       *ue
3310  *  @param[in] RgSchRaCb       *raCb
3311  *
3312  **/
3313 Void rgSCHUtlRecMsg3Alloc(RgSchCellCb *cell,RgSchUeCb *ue,RgSchRaCb *raCb)
3314 {
3315    cell->sc.apis->rgSCHUlRecMsg3Alloc(cell, ue, raCb);
3316    return;
3317
3318 }  /* rgSCHRecMsg3Alloc */
3319
3320 #ifdef RG_UNUSED
3321 /**
3322  * @brief Update harq process for allocation
3323  *
3324  * @details
3325  *
3326  *     Function : rgSCHUtlUpdUlHqProc
3327  *
3328  *     This function is invoked when harq process
3329  *     control block is now in a new memory location
3330  *     thus requiring a pointer/reference update.
3331  *
3332  *  @param[in] RgSchCellCb      *cell
3333  *  @param[in] RgSchUlHqProcCb  *curProc
3334  *  @param[in] RgSchUlHqProcCb  *oldProc
3335  *  @return  S16
3336  *      -# ROK
3337  *      -# RFAILED
3338  **/
3339 S16 rgSCHUtlUpdUlHqProc(RgSchCellCb *cell,RgSchUlHqProcCb  *curProc,RgSchUlHqProcCb  *oldProc)
3340 {
3341    return (cell->sc.apis->rgSCHUpdUlHqProc(cell, curProc, oldProc));
3342 }  /* rgSCHUtlUpdUlHqProc */
3343 #endif
3344 /**
3345  * @brief UL grant for contention resolution
3346  *
3347  * @details
3348  *
3349  *     Function : rgSCHUtlContResUlGrant
3350  *
3351  *     Add UE to another queue specifically for CRNTI based contention
3352  *     resolution
3353  *
3354  *  @param[in]  RgSchCellCb *cell
3355  *  @param[in]  RgSchUeCb  *ue
3356  *  @param[out] RgSchErrInfo *err
3357  *  @return  S16
3358  *      -# ROK
3359  *      -# RFAILED
3360  **/
3361 S16 rgSCHUtlContResUlGrant(RgSchCellCb *cell,RgSchUeCb *ue,RgSchErrInfo *err)
3362 {
3363
3364    ue->isMsg4PdcchWithCrnti = TRUE; 
3365    return (cell->sc.apis->rgSCHContResUlGrant(cell, ue, err));
3366 }  /* rgSCHUtlContResUlGrant */
3367
3368 /**
3369  * @brief SR reception handling
3370  *
3371  * @details
3372  *
3373  *     Function : rgSCHUtlSrRcvd
3374  *
3375  *     - Handles SR reception for UE
3376  *
3377  *  @param[in]  RgSchCellCb  *cell
3378  *  @param[in]  RgSchUeCb    *ue
3379  *  @param[out] RgSchErrInfo *err
3380  *  @return  S16
3381  *      -# ROK
3382  *      -# RFAILED
3383  **/
3384 S16 rgSCHUtlSrRcvd(RgSchCellCb  *cell,RgSchUeCb *ue,CmLteTimingInfo frm,RgSchErrInfo *err)
3385 {
3386    return (cell->sc.apis->rgSCHSrRcvd(cell, ue, frm, err));
3387 }  /* rgSCHUtlSrRcvd */
3388
3389 /**
3390  * @brief Short BSR update
3391  *
3392  * @details
3393  *
3394  *     Function : rgSCHUtlUpdBsrShort
3395  *
3396  *     This functions does requisite updates to handle short BSR reporting
3397  *
3398  *  @param[in]  RgSchCellCb  *cell
3399  *  @param[in]  RgSchUeCb    *ue
3400  *  @param[in]  uint8_t           lcgId
3401  *  @param[in]  uint8_t           bsr
3402  *  @param[out] RgSchErrInfo *err
3403  *  @return  Void
3404  *      -# ROK
3405  *      -# RFAILED
3406  **/
3407 Void rgSCHUtlUpdBsrShort(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t lcgId,uint8_t bsr,RgSchErrInfo *err)
3408 {
3409    cell->sc.apis->rgSCHUpdBsrShort(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
3410    return;
3411 }  /* rgSCHUtlUpdBsrShort */
3412
3413
3414 /**
3415  * @brief Truncated BSR update
3416  *
3417  * @details
3418  *
3419  *     Function : rgSCHUtlUpdBsrTrunc
3420  *
3421  *     This functions does required updates to handle truncated BSR report
3422  *
3423  *
3424  *  @param[in]  RgSchCellCb  *cell
3425  *  @param[in]  RgSchUeCb    *ue
3426  *  @param[in]  uint8_t           lcgId
3427  *  @param[in]  uint8_t           bsr
3428  *  @param[out] RgSchErrInfo *err
3429  *  @return  Void
3430  *      -# ROK
3431  *      -# RFAILED
3432  **/
3433 Void rgSCHUtlUpdBsrTrunc(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t  lcgId,uint8_t bsr,RgSchErrInfo *err)
3434 {
3435    cell->sc.apis->rgSCHUpdBsrTrunc(cell, ue, &ue->ul.lcgArr[lcgId], bsr, err);
3436    return; 
3437 }  /* rgSCHUtlUpdBsrTrunc */
3438
3439
3440 /**
3441  * @brief Long BSR update
3442  *
3443  * @details
3444  *
3445  *     Function : rgSCHUtlUpdBsrLong
3446  *
3447  *     - Update BSRs for all configured LCGs
3448  *     - Update priority of LCGs if needed
3449  *     - Update UE's position within/across uplink scheduling queues
3450  *
3451  *
3452  *  @param[in]  RgSchCellCb   *cell
3453  *  @param[in]  RgSchUeCb     *ue
3454  *  @param[in]  uint8_t            bsr0
3455  *  @param[in]  uint8_t            bsr1
3456  *  @param[in]  uint8_t            bsr2
3457  *  @param[in]  uint8_t            bsr3
3458  *  @param[out] RgSchErrInfo  *err
3459  *  @return  Void
3460  *      -# ROK
3461  *      -# RFAILED
3462  **/
3463 Void rgSCHUtlUpdBsrLong(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t bsr0,uint8_t bsr1,uint8_t bsr2,uint8_t bsr3,RgSchErrInfo *err)
3464 {
3465    uint8_t bsArr[4];
3466    bsArr[0] = bsr0;
3467    bsArr[1] = bsr1;
3468    bsArr[2] = bsr2;
3469    bsArr[3] = bsr3;
3470    cell->sc.apis->rgSCHUpdBsrLong(cell, ue, bsArr, err);
3471    return;
3472 }  /* rgSCHUtlUpdBsrLong */
3473
3474 /**
3475  * @brief EXT PHR update
3476  *
3477  * @details
3478  *
3479  *     Function : rgSCHUtlUpdExtPhr
3480  *
3481  *     Updates extended power headroom info for a UE
3482  *
3483  *  @param[in]  RgSchCellCb  *cell
3484  *  @param[in]  RgSchUeCb    *ue
3485  *  @param[in]  uint8_t           phr
3486  *  @param[out] RgSchErrInfo *err
3487  *  @return  S16
3488  *      -# ROK
3489  *      -# RFAILED
3490  **/
3491 S16 rgSCHUtlUpdExtPhr(RgSchCellCb *cell,RgSchUeCb *ue,RgInfExtPhrCEInfo *extPhr,RgSchErrInfo *err)
3492 {
3493    return (cell->sc.apis->rgSCHUpdExtPhr(cell, ue, extPhr, err));
3494 }  /* rgSCHUtlUpdExtPhr */
3495
3496
3497
3498 /**
3499  * @brief PHR update
3500  *
3501  * @details
3502  *
3503  *     Function : rgSCHUtlUpdPhr
3504  *
3505  *     Updates power headroom info for a UE
3506  *
3507  *  @param[in]  RgSchCellCb  *cell
3508  *  @param[in]  RgSchUeCb    *ue
3509  *  @param[in]  uint8_t           phr
3510  *  @param[out] RgSchErrInfo *err
3511  *  @return  S16
3512  *      -# ROK
3513  *      -# RFAILED
3514  **/
3515 S16 rgSCHUtlUpdPhr(RgSchCellCb *cell,RgSchUeCb *ue,uint8_t phr,RgSchErrInfo *err)
3516 {
3517    return (cell->sc.apis->rgSCHUpdPhr(cell, ue, phr, err));
3518 }  /* rgSCHUtlUpdPhr */
3519
3520
3521 /**
3522  * @brief Indication of UL CQI
3523  *
3524  * @details
3525  *
3526  *     Function : rgSCHUtlUlCqiInd
3527  *
3528  *     - Updates uplink CQI information for the UE. Computes and
3529  *       stores the lowest CQI of CQIs reported in all subbands
3530  *
3531  *  @param[in]  RgSchCellCb         *cell
3532  *  @param[in]  RgSchUeCb           *ue
3533  *  @param[in]  TfuUlCqiRpt         *ulCqiInfo
3534  *  @return  Void
3535  **/
3536 Void rgSCHUtlUlCqiInd(RgSchCellCb *cell,RgSchUeCb *ue,TfuUlCqiRpt *ulCqiInfo)
3537 {
3538    cell->sc.apis->rgSCHUlCqiInd(cell, ue, ulCqiInfo);
3539    return;
3540 }  /* rgSCHUtlUlCqiInd */
3541
3542 /**
3543  * @brief Indication of PUCCH power adjustment
3544  *
3545  * @details
3546  *
3547  *     Function : rgSCHUtlPucchDeltaPwrInd
3548  *
3549  *     - Updates uplink CQI information for the UE. Computes and
3550  *       stores the lowest CQI of CQIs reported in all subbands
3551  *
3552  *  @param[in]  RgSchCellCb         *cell
3553  *  @param[in]  RgSchUeCb           *ue
3554  *  @param[in]  uint8_t                  delta
3555  *  @return  Void
3556  **/
3557 Void rgSCHUtlPucchDeltaPwrInd(RgSchCellCb *cell,RgSchUeCb *ue,S8 delta)
3558 {
3559    cell->sc.apis->rgSCHPucchDeltaPwrInd(cell, ue, delta);
3560    return;
3561 }  /* rgSCHUtlPucchDeltaPwrInd */
3562
3563 /* Start: LTEMAC_2.1_DEV_CFG */
3564 /**
3565  * @brief Ue Reset Request
3566  *
3567  * @details
3568  *
3569  *     Function : rgSCHUtlUeReset
3570  *
3571  *
3572  *  @param[in]  RgSchCellCb         *cell
3573  *  @param[in]  RgSchUeCb           *ue
3574  *  @return  S16
3575  **/
3576 Void rgSCHUtlUeReset(RgSchCellCb *cell,RgSchUeCb *ue)
3577 {
3578    ue->remBoCnt = 0;
3579    cell->sc.apis->rgSCHUeReset(cell, ue);
3580    return;
3581 }  /* rgSCHUtlUeReset */
3582 /* End: LTEMAC_2.1_DEV_CFG */
3583
3584 /**
3585  * @brief Returns HARQ proc for which data expected now
3586  *
3587  * @details
3588  *
3589  *     Function: rgSCHUtlUlHqProcForUe
3590  *     Purpose:  This function returns the harq process for
3591  *               which data is expected in the current slot.
3592  *               It does not validate if the HARQ process
3593  *               has an allocation.
3594  *
3595  *     Invoked by: TOM
3596  *
3597  *  @param[in]  RgSchCellCb         *cell
3598  *  @param[in]  CmLteTimingInfo     frm
3599  *  @param[in]  RgSchUeCb           *ue
3600  *  @param[out] RgSchUlHqProcCb     **procRef
3601  *  @return  Void
3602  **/
3603 Void rgSCHUtlUlHqProcForUe(RgSchCellCb *cell,CmLteTimingInfo frm,RgSchUeCb *ue,RgSchUlHqProcCb **procRef)
3604 {
3605    cell->sc.apis->rgSCHUlHqProcForUe(cell, frm, ue, procRef);
3606
3607  /* Stack Crash problems for TRACE5 changes. added the return below */
3608  return;
3609
3610 }
3611
3612 /**
3613  * @brief Returns first uplink allocation to send reception
3614  *        request to PHY
3615  *
3616  * @details
3617  *
3618  *     Function: rgSCHUtlFirstRcptnReq(cell)
3619  *     Purpose:  This function returns the first uplink allocation
3620  *               (or NULLP if there is none) in the slot
3621  *               in which is expected to prepare and send reception
3622  *               request to PHY.
3623  *
3624  *     Invoked by: TOM
3625  *
3626  *  @param[in]  RgSchCellCb      *cell
3627  *  @return  RgSchUlAlloc*
3628  **/
3629 RgSchUlAlloc *rgSCHUtlFirstRcptnReq(RgSchCellCb *cell)
3630 {
3631    return (cell->sc.apis->rgSCHFirstRcptnReq(cell));
3632 }
3633
3634 /**
3635  * @brief Returns first uplink allocation to send reception
3636  *        request to PHY
3637  *
3638  * @details
3639  *
3640  *     Function: rgSCHUtlNextRcptnReq(cell)
3641  *     Purpose:  This function returns the next uplink allocation
3642  *               (or NULLP if there is none) in the slot
3643  *               in which is expected to prepare and send reception
3644  *               request to PHY.
3645  *
3646  *     Invoked by: TOM
3647  *
3648  *  @param[in]  RgSchCellCb      *cell
3649  *  @return  RgSchUlAlloc*
3650  **/
3651 RgSchUlAlloc *rgSCHUtlNextRcptnReq(RgSchCellCb *cell,RgSchUlAlloc *alloc)
3652 {
3653    return (cell->sc.apis->rgSCHNextRcptnReq(cell, alloc));
3654 }
3655
3656 /**
3657  * @brief Returns first uplink allocation to send HARQ feedback
3658  *        request to PHY
3659  *
3660  * @details
3661  *
3662  *     Function: rgSCHUtlFirstHqFdbkAlloc
3663  *     Purpose:  This function returns the first uplink allocation
3664  *               (or NULLP if there is none) in the slot
3665  *               in which it is expected to prepare and send HARQ
3666  *               feedback to PHY.
3667  *
3668  *     Invoked by: TOM
3669  *
3670  *  @param[in]  RgSchCellCb      *cell
3671  *  @param[in]  uint8_t                idx  
3672  *  @return  RgSchUlAlloc*
3673  **/
3674 RgSchUlAlloc *rgSCHUtlFirstHqFdbkAlloc(RgSchCellCb *cell,uint8_t idx)
3675 {
3676    return (cell->sc.apis->rgSCHFirstHqFdbkAlloc(cell, idx));
3677 }
3678
3679 \f
3680 /**
3681  * @brief Returns next allocation to send HARQ feedback for
3682  *
3683  * @details
3684  *
3685  *     Function: rgSCHUtlNextHqFdbkAlloc(cell)
3686  *     Purpose:  This function returns the next uplink allocation
3687  *               (or NULLP if there is none) in the slot
3688  *               for which HARQ feedback needs to be sent.
3689  *
3690  *     Invoked by: TOM
3691  *
3692  *  @param[in]  RgSchCellCb      *cell
3693  *  @return  RgSchUlAlloc*
3694  **/
3695 RgSchUlAlloc *rgSCHUtlNextHqFdbkAlloc(RgSchCellCb *cell,RgSchUlAlloc *alloc,uint8_t idx)
3696 {
3697    return (cell->sc.apis->rgSCHNextHqFdbkAlloc(cell, alloc, idx));
3698 }
3699
3700 /***********************************************************
3701  *
3702  *     Func : rgSCHUtlResetSfAlloc
3703  *
3704  *     Desc : Utility Function to Reset slot allocation information.
3705  *
3706  *
3707  *     Ret  : ROK
3708  *            RFAILED
3709  *
3710  *
3711  *     File : rg_utl.c
3712  *
3713  **********************************************************/
3714 S16 rgSCHUtlResetSfAlloc(RgInfSfAlloc *sfAlloc,Bool resetCmnLcInfo,Bool restAlloc)
3715 {
3716    if(TRUE == restAlloc)
3717    {
3718       if(sfAlloc->ueInfo.numUes)
3719       {
3720          memset(sfAlloc->ueInfo.allocInfo,0x00,
3721                (sizeof(RgInfUeAlloc)*sfAlloc->ueInfo.numUes));
3722       }
3723       sfAlloc->ueInfo.numUes = 0;
3724       sfAlloc->rarInfo.numRaRntis = 0;
3725       sfAlloc->flowCntrlInfo.numUes = 0;
3726    }
3727    if(TRUE == resetCmnLcInfo)
3728    {
3729       sfAlloc->cmnLcInfo.bitMask = 0;
3730    }
3731    return ROK;
3732 }
3733
3734 /***********************************************************
3735  *
3736  *     Func : rgSCHUtlGetRlsHqAlloc
3737  *
3738  *     Desc : Utility Function to Allocate slot allocation information.
3739  *
3740  *
3741  *     Ret  : ROK
3742  *            RFAILED
3743  *
3744  *
3745  *     File : rg_utl.c
3746  *
3747  **********************************************************/
3748 S16 rgSCHUtlGetRlsHqAlloc(RgSchCellCb *cell)
3749 {
3750    uint8_t    idx = 0;
3751    Inst  inst = cell->instIdx;
3752    for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
3753    {
3754       cell->rlsHqArr[idx].cellId = cell->cellId;
3755
3756       /* Allocating with additional location, to accommodate
3757          TA scheduling along with maximum no of UEs per SF */
3758
3759       /* Allocate memory for "scheduled UE" Info */
3760       if((rgSCHUtlAllocSBuf(inst,
3761                      (Data**)&(cell->rlsHqArr[idx].ueHqInfo),
3762                       (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
3763       {
3764          DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for "
3765             "UE Alloc");
3766          return RFAILED;
3767       }
3768    }
3769
3770    return ROK;
3771
3772 }
3773
3774 /***********************************************************
3775  *
3776  *     Func : rgSCHUtlPutRlsHqAlloc
3777  *
3778  *     Desc : Utility Function to deallocate slot allocation information.
3779  *
3780  *
3781  *     Ret  : ROK
3782  *            RFAILED
3783  *
3784  *
3785  *     File : rg_utl.c
3786  *
3787  **********************************************************/
3788 S16 rgSCHUtlPutRlsHqAlloc(RgSchCellCb *cell)
3789 {
3790    uint8_t    idx = 0;
3791    Inst  inst = cell->instIdx;
3792
3793    for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
3794    {
3795       /* Deallocate memory for "scheduled UE" Info */
3796       if (cell->rlsHqArr[idx].ueHqInfo != NULLP)
3797       {
3798          /* Freeing with additional location, to accommodate TA
3799             scheduling along with maximum no of UEs per SF */
3800          /* ccpu00117052 - MOD - Passing double pointer
3801             for proper NULLP assignment*/
3802          rgSCHUtlFreeSBuf(inst,
3803                (Data **)(&(cell->rlsHqArr[idx].ueHqInfo)),
3804              (sizeof(RgInfUeHqInfo)*RGSCH_MAX_UE_PER_DL_SF));
3805       }
3806    }
3807
3808    return ROK;
3809
3810 }
3811
3812
3813 /***********************************************************
3814  *
3815  *     Func : rgSCHUtlGetSfAlloc
3816  *
3817  *     Desc : Utility Function to Allocate slot allocation information.
3818  *
3819  *
3820  *     Ret  : ROK
3821  *            RFAILED
3822  *
3823  *
3824  *     File : rg_utl.c
3825  *
3826  **********************************************************/
3827 S16 rgSCHUtlGetSfAlloc(RgSchCellCb *cell)
3828 {
3829    uint8_t    idx;
3830    uint8_t    indx;
3831    Inst  inst = cell->instIdx;
3832    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
3833
3834 #ifdef LTE_TDD
3835    for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
3836 #else
3837    for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
3838 #endif
3839    {
3840       cell->sfAllocArr[idx].cellId = cell->cellId;
3841
3842       /* Allocating with additional location, to accommodate
3843          TA scheduling along with maximum no of UEs per SF */
3844
3845       /* Allocate memory for "scheduled UE" Info */
3846       if((rgSCHUtlAllocSBuf(inst,
3847                      (Data**)&(cell->sfAllocArr[idx].ueInfo.allocInfo),
3848                       (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF))) != ROK)
3849       {
3850          DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for "
3851             "UE Alloc");
3852          return RFAILED;
3853       }
3854
3855       /* Allocate memory for "scheduled RAR" Info */
3856       if((rgSCHUtlAllocSBuf(inst,
3857                      (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo),
3858                       (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF))) != ROK)
3859       {
3860          DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for "
3861             "RARNTI");
3862          return RFAILED;
3863       }
3864       for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
3865       {
3866          if((rgSCHUtlAllocSBuf(inst,
3867             (Data**)&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo),
3868                    (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)))) != ROK)
3869          {
3870             DU_LOG("\nERROR  -->  SCH : Memory allocation FAILED for "
3871                "RNTI");
3872             return RFAILED;
3873          }
3874       }
3875
3876    }
3877
3878 #ifdef EMTC_ENABLE
3879    rgSCHEmtcUtlGetSfAlloc(cell);
3880 #endif
3881
3882    return ROK;
3883
3884 }
3885
3886 /***********************************************************
3887  *
3888  *     Func : rgSCHUtlPutSfAlloc
3889  *
3890  *     Desc : Utility Function to deallocate slot allocation information.
3891  *
3892  *
3893  *     Ret  : ROK
3894  *            RFAILED
3895  *
3896  *
3897  *     File : rg_utl.c
3898  *
3899  **********************************************************/
3900 S16 rgSCHUtlPutSfAlloc(RgSchCellCb *cell)
3901 {
3902    uint8_t    idx;
3903    uint8_t    indx;
3904    Inst  inst = cell->instIdx;
3905    RgSchCmnUlCell *cellUl      = RG_SCH_CMN_GET_UL_CELL(cell);
3906
3907 #ifdef LTE_TDD
3908    for(idx=0; idx < RGSCH_SF_ALLOC_SIZE; idx++)
3909 #else
3910       for(idx=0; idx < RGSCH_NUM_SUB_FRAMES; idx++)
3911 #endif
3912       {
3913          if (cell->sfAllocArr[idx].rarInfo.raRntiInfo != NULLP)
3914          {
3915             for(indx = 0; indx < RGSCH_MAX_RARNTI_PER_DL_SF; indx++)
3916             {
3917                if (cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].crntiInfo != NULLP)
3918                   /* ccpu00117052 - MOD - Passing double pointer
3919                      for proper NULLP assignment*/
3920                   rgSCHUtlFreeSBuf(inst,
3921                         (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo[indx].\
3922                               crntiInfo)),
3923                         (sizeof(RgInfCrntiInfo)* (cellUl->maxMsg3PerUlSf)));
3924             }
3925             /* Deallocate memory for "scheduled RAR" Info */
3926             /* ccpu00117052 - MOD - Passing double pointer
3927                for proper NULLP assignment*/
3928             rgSCHUtlFreeSBuf(inst,
3929                   (Data**)(&(cell->sfAllocArr[idx].rarInfo.raRntiInfo)),
3930                   (sizeof(RgInfRaRntiInfo)*RGSCH_MAX_RARNTI_PER_DL_SF));
3931          }
3932          /* Deallocate memory for "scheduled UE" Info */
3933          if (cell->sfAllocArr[idx].ueInfo.allocInfo != NULLP)
3934          {
3935             /* Freeing with additional location, to accommodate TA
3936                scheduling along with maximum no of UEs per SF */
3937             /* ccpu00117052 - MOD - Passing double pointer
3938                for proper NULLP assignment*/
3939             rgSCHUtlFreeSBuf(inst,
3940                   (Data**)(&(cell->sfAllocArr[idx].ueInfo.allocInfo)),
3941                   (sizeof(RgInfUeAlloc)*RGSCH_MAX_UE_PER_DL_SF));
3942          }
3943       }
3944
3945 #ifdef EMTC_ENABLE
3946    rgSCHEmtcUtlPutSfAlloc(cell);
3947 #endif
3948    return ROK;
3949
3950 }
3951
3952 /***********************************************************
3953  *
3954  *     Func : rgSCHUtlAllocSBuf
3955  *
3956  *     Desc : Utility Function to Allocate static buffer.
3957  *            Memory allocated is assumed contiguous.
3958  *
3959  *
3960  *     Ret  : ROK
3961  *            RFAILED
3962  *
3963  *     Notes: Caller doesnt need to raise the alarm in case of memory
3964  *            allocation gets failed.
3965  *
3966  *     File : rg_utl.c
3967  *
3968  **********************************************************/
3969 S16 rgSCHUtlAllocSBuf
3970 (
3971 Inst    inst,               /* Instance of the invoking scheduler */
3972 Data    **pData,            /* Pointer of the data to be returned */
3973 Size    size                /* size */
3974 )
3975 {
3976    /* Moving alarm diagnostics to available scope */
3977
3978    /* Initialize the param to NULLP */
3979    *pData = NULLP;
3980
3981    /* May not be necessary for data performance path */
3982 #ifndef NO_ERRCLS
3983    if (size == 0)
3984    {
3985       return RFAILED;
3986    }
3987 #endif
3988
3989    /* allocate buffer */
3990 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
3991    MS_BUF_ADD_ALLOC_CALLER();
3992 #endif /* */
3993    SCH_ALLOC(pData, size);
3994    if(pData == NULLP)
3995    {
3996      RgUstaDgn dgn;      /* Alarm diagnostics structure */
3997      dgn.type = LRG_USTA_DGNVAL_MEM;
3998      dgn.u.mem.region = rgSchCb[inst].rgSchInit.region;
3999      dgn.u.mem.pool = rgSchCb[inst].rgSchInit.pool;
4000      /*  Send an alarm to Layer Manager */
4001      rgSCHLmmStaInd(inst, LCM_CATEGORY_RESOURCE, LCM_EVENT_SMEM_ALLOC_FAIL,
4002                                        LCM_CAUSE_MEM_ALLOC_FAIL, &dgn);
4003      DU_LOG("\nERROR  -->  SCH : Unable to Allocate the Buffer");
4004      return RFAILED;
4005    }
4006
4007
4008    /* zero out the allocated memory */
4009    memset(*pData, 0x00, size);
4010
4011    return ROK;
4012
4013 } /* end of rgSCHUtlAllocSBuf */
4014
4015 \f
4016 /*
4017 *
4018 *       Fun:   rgSCHUtlFreeSBuf
4019 *
4020 *       Desc:  The argument to rgSCHUtlFreeSBuf() is a pointer to a block
4021 *              previously allocated by rgSCHUtlAllocSBuf() and size. It
4022 *              deallocates the memory.
4023 *
4024 *       Ret:   void
4025 *
4026 *       Notes: None
4027 *       File:  rg_utl.c
4028 */
4029 Void rgSCHUtlFreeSBuf
4030 (
4031 Inst inst,          /* Instance of the invoking scheduler */
4032 Data **data,         /* pointer to data */
4033 Size size           /* size */
4034 )
4035 {
4036
4037    if ((data == NULLP) || (*data == NULLP) || (size == 0))
4038    {
4039       return;
4040    }
4041
4042
4043 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
4044    MS_BUF_ADD_CALLER();
4045 #endif /* */
4046    /* Deallocate buffer */
4047    SCH_FREE((*data), size);
4048
4049    if (data ==NULLP)
4050    {
4051       DU_LOG("\nERROR  -->  SCH : rgSCHUtlFreeSBuf failed");
4052       return;
4053    }
4054
4055    /* ccpu00117052 - ADD - Assigning the pointer to NULLP */
4056    *data = NULLP;
4057
4058    return;
4059 } /* end of rgSCHUtlFreeSBuf */
4060
4061 \f
4062 #ifdef RGR_SI_SCH
4063 /*
4064 *
4065 *       Fun:   rgSCHUtlFreeWarningSiSeg
4066 *
4067 *       Desc:  This is used to deallocate Warning SI Seg.
4068 *
4069 *       Ret:   void
4070 *
4071 *       Notes: None
4072 *
4073 *       File:  rg_utl.c
4074 */
4075 Void rgSCHUtlFreeWarningSiSeg(Region reg,Pool pool,CmLListCp *siPduLst)
4076 {
4077    CmLList      *node;
4078    Buffer       *pdu;
4079
4080    while (siPduLst->first != NULLP)
4081    {
4082       node = siPduLst->first;
4083       pdu = (Buffer *)node->node;
4084       cmLListDelFrm(siPduLst, node);
4085       RGSCH_FREE_MSG(pdu);
4086       SCH_FREE(node,sizeof(CmLList));
4087       node = NULLP;
4088    }
4089
4090    return;
4091 } /* end of rgSCHUtlFreeWarningSiSeg */         
4092
4093 \f
4094 /*
4095 *
4096 *       Fun:   rgSCHUtlFreeWarningSiPdu
4097 *
4098 *       Desc:  This is used to deallocate Warning SI PDU.
4099 *
4100 *       Ret:   void
4101 *
4102 *       Notes: None
4103 *
4104 *       File:  rg_utl.c
4105 */
4106 Void rgSCHUtlFreeWarningSiPdu(RgSchCellCb  *cell)
4107 {
4108    CmLList            *node;
4109    Buffer             *pdu;
4110    RgSchWarningSiInfo *warningSi;
4111    RgSchWarningSiPdu  *warningSiPdu; 
4112
4113    warningSi = (RgSchWarningSiInfo *) cell->siCb.\
4114                   siArray[cell->siCb.siCtx.siId-1].si; 
4115    /* ccpu00136659: CMAS ETWS design changes */
4116    CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
4117    if (node == NULLP)
4118    {
4119       return;
4120    }
4121
4122    warningSiPdu = (RgSchWarningSiPdu *)node->node;
4123    pdu = warningSiPdu->pdu;
4124    /* ccpu00136659: CMAS ETWS design changes */
4125    cmLListDelFrm(&warningSi->warningSiMsg.segLstCp, node); 
4126    RGSCH_FREE_MSG(pdu);
4127    if(warningSi->warningSiMsg.segLstCp.count == 0)
4128    {
4129       /* ccpu00136659: CMAS ETWS design changes */
4130       cell->siCb.siArray[cell->siCb.siCtx.siId-1].si = NULLP;
4131       rgSCHUtlRgrWarningSiCfgCfm(cell->instIdx,
4132             rgSchCb[cell->instIdx].rgrSap->sapCfg.spId,
4133             cell->siCb.warningSi[warningSi->idx].siId,
4134             warningSi->warningSiMsg.transId, RGR_CFG_CFM_TX_COMPLETE);
4135    }                                                                                 
4136
4137    return;
4138
4139 } /* end of rgSCHUtlFreeWarningSiPdu */         
4140  
4141 \f
4142 /*
4143 *
4144 *       Fun:   rgSCHUtlGetWarningSiPdu
4145 *
4146 *       Desc:  This is used to get Warning SI PDU for Scheduling. 
4147 *
4148 *       Ret:   
4149 *
4150 *       Notes: None
4151 *
4152 *       File:  rg_utl.c
4153 */
4154 Buffer *rgSCHUtlGetWarningSiPdu(RgSchCellCb *cell)
4155 {
4156    RgSchWarningSiInfo  *warningSi;
4157    RgSchWarningSiPdu  *warningSiPdu; 
4158    Buffer       *pdu;
4159    CmLList      *node;
4160
4161    warningSi = (RgSchWarningSiInfo *) cell->siCb.
4162    siArray[cell->siCb.siCtx.siId-1].si; 
4163    /* ccpu00136659: CMAS ETWS design changes */
4164    CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
4165    if (node != NULLP)
4166    {
4167       warningSiPdu = (RgSchWarningSiPdu *)node->node;
4168       pdu = warningSiPdu->pdu;
4169       return (pdu);
4170    }
4171    else
4172    {
4173       return (NULLP);
4174    }                                                  
4175 } /* rgSCHUtlGetWarningSiPdu  */    
4176
4177 \f
4178 /*
4179 *
4180 *       Fun:   rgSCHUtlGetMcsAndNPrb
4181 *
4182 *       Desc:  This is used to get mcs and nPrb value. 
4183 *
4184 *       Ret:   
4185 *
4186 *       Notes: None
4187 *
4188 *       File:  rg_utl.c
4189 */
4190 S16 rgSCHUtlGetMcsAndNPrb(RgSchCellCb *cell,uint8_t *nPrb,uint8_t *mcs,MsgLen  *msgLen)
4191 {
4192    RgSchWarningSiInfo  *warningSi;
4193    RgSchWarningSiPdu  *warningSiPdu; 
4194    CmLList      *node;
4195
4196    if(cell->siCb.siCtx.warningSiFlag == FALSE)
4197    {
4198       *mcs =  cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].mcs;
4199       *nPrb =  cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].nPrb;
4200       *msgLen = cell->siCb.crntSiInfo.siInfo[cell->siCb.siCtx.siId-1].msgLen;
4201    }
4202    else
4203    {
4204       warningSi = (RgSchWarningSiInfo *) cell->siCb.
4205             siArray[cell->siCb.siCtx.siId-1].si; 
4206       /* ccpu00136659: CMAS ETWS design changes */
4207       CM_LLIST_FIRST_NODE(&warningSi->warningSiMsg.segLstCp, node);
4208       if (node == NULLP)
4209       {
4210         return RFAILED;
4211       }
4212       
4213       warningSiPdu = (RgSchWarningSiPdu *)node->node;
4214       *mcs = warningSiPdu->mcs;
4215       *nPrb = warningSiPdu->nPrb;
4216       *msgLen = warningSiPdu->msgLen;
4217       return ROK;
4218             
4219    }
4220    return ROK;
4221 } /* rgSCHUtlGetMcsAndNPrb  */     
4222
4223 /*
4224 *
4225 *       Fun:   rgSCHUtlCalMacAndPrb
4226 *
4227 *       Desc:  This is used to Calculate mcs and nPrb value for SIB1 and SIs. 
4228 *
4229 *       Ret:   
4230 *
4231 *       Notes: None
4232 *
4233 *       File:  rg_utl.c
4234 */
4235 S16 rgSCHUtlCalMcsAndNPrb(RgSchCellCb *cell,uint8_t cfgType,MsgLen msgLen,uint8_t siId)
4236 {
4237    uint8_t mcs = 0;
4238    uint8_t nPrb = 0;
4239
4240       /*Get the nPrb and mcs parametr values */
4241    if (rgSCHUtlGetAllwdCchTbSz(msgLen*8, &nPrb, &mcs) != (msgLen*8))
4242       {
4243          DU_LOG("\nERROR  -->  SCH : msgLen does "
4244             "not match any valid TB Size");
4245          return RFAILED;
4246       }
4247
4248
4249    if(cfgType == RGR_SI_CFG_TYPE_SIB1 || cfgType == RGR_SI_CFG_TYPE_SIB1_PWS)
4250    {
4251
4252       if(cell->siCb.crntSiInfo.sib1Info.sib1 == NULLP)
4253       {
4254          cell->siCb.crntSiInfo.sib1Info.mcs = mcs;
4255          cell->siCb.crntSiInfo.sib1Info.nPrb = nPrb;
4256          cell->siCb.crntSiInfo.sib1Info.msgLen = msgLen;
4257       }
4258       else
4259       {
4260          cell->siCb.newSiInfo.sib1Info.mcs = mcs;
4261          cell->siCb.newSiInfo.sib1Info.nPrb= nPrb;
4262          cell->siCb.newSiInfo.sib1Info.msgLen = msgLen;
4263       }
4264    }
4265
4266     
4267    if(cfgType == RGR_SI_CFG_TYPE_SI)
4268    {
4269       if(cell->siCb.crntSiInfo.siInfo[siId-1].si == NULLP &&
4270          !(cell->siCb.siBitMask & RGSCH_SI_SICFG_UPD))
4271       {
4272          cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
4273          cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
4274          cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
4275       }
4276       else
4277       {
4278          cell->siCb.newSiInfo.siInfo[siId-1].mcs = mcs;
4279          cell->siCb.newSiInfo.siInfo[siId-1].nPrb= nPrb;
4280          cell->siCb.newSiInfo.siInfo[siId-1].msgLen = msgLen;
4281       }
4282    }
4283
4284    if(cfgType == RGR_SI_CFG_TYPE_SIB8_CDMA)
4285    {
4286       cell->siCb.crntSiInfo.siInfo[siId-1].mcs = mcs;
4287       cell->siCb.crntSiInfo.siInfo[siId-1].nPrb = nPrb;
4288       cell->siCb.crntSiInfo.siInfo[siId-1].msgLen = msgLen;
4289    }
4290
4291     return ROK;
4292 }
4293 #endif
4294
4295 /***********************************************************
4296  *
4297  *     Func : rgSCHUtlFillDgnParams
4298  *
4299  *     Desc : Utility Function to Fill Diagonostic params.
4300  *
4301  *     Ret  : None.
4302  *
4303  *     Notes: None.
4304  *
4305  *     File : rg_utl.c
4306  *
4307  **********************************************************/
4308 Void rgSCHUtlFillDgnParams(Inst inst,RgUstaDgn *dgn,uint8_t dgnType)
4309 {
4310
4311    switch(dgnType)
4312    {
4313       case LRG_USTA_DGNVAL_MEM:
4314          dgn->type = (uint8_t) LRG_USTA_DGNVAL_MEM;
4315          dgn->u.mem.region  = rgSchCb[inst].rgSchInit.region;
4316          dgn->u.mem.pool    = rgSchCb[inst].rgSchInit.pool;
4317       break;
4318
4319       default:
4320       break;
4321    }
4322
4323    return;
4324 } /* end of rgSCHUtlFillDgnParams */
4325
4326 /***********************************************************
4327  *
4328  *     Func : rgSCHUtlGetPstToLyr
4329  *
4330  *     Desc : Utility Function to get the pst structure to post a message to MAC
4331  *
4332  *
4333  *     Ret  : ROK
4334  *            RFAILED
4335  *
4336  *     Notes: This function should be called while sending a msg from
4337  *     scheduler instance to MAC
4338  *
4339  *     File : rg_utl.c
4340  *
4341  **********************************************************/
4342 Void rgSCHUtlGetPstToLyr(Pst  *pst,RgSchCb *schCb,Inst macInst)
4343 {
4344
4345    /* Only the needed params are filled */
4346    pst->region = schCb->rgSchInit.region;
4347    pst->pool = schCb->rgSchInit.pool;
4348    pst->srcInst = schCb->rgSchInit.inst+SCH_INST_START;
4349    pst->srcProcId = schCb->rgSchInit.procId;
4350    pst->dstProcId = schCb->rgSchInit.procId;
4351
4352    pst->dstInst = macInst;
4353    pst->dstEnt = ENTMAC;
4354    pst->srcEnt = ENTMAC;
4355    pst->selector = 0;
4356    pst->prior     = PRIOR0;
4357    pst->intfVer   = 0;
4358    pst->route   = RTESPEC;
4359
4360    return;
4361 } /* end of rgSCHUtlGetPstToLyr */
4362
4363 /** @brief This function fills in the common lc information to be sent to MAC
4364  *
4365  * @details
4366  *
4367  *     Function: rgSCHUtlFillRgInfCmnLcInfo
4368  *       @param  RgSchDlSf       *sf,
4369  *       @param  RgInfSfAlloc    *sfAlloc,
4370  *       @param  CmLteLcId       lcId,
4371  *       @param  Bool            sendInd
4372  *
4373  * @return  S16
4374  *      -# ROK
4375  *      -# RFAILED
4376  */
4377 S16 rgSCHUtlFillRgInfCmnLcInfo(RgSchDlSf  *sf,RgInfSfAlloc *sfAlloc,CmLteLcId lcId,Bool sendInd)
4378 {
4379
4380    if((sf->bch.tbSize)&&
4381       !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCH_INFO))
4382    {
4383 #ifndef RGR_SI_SCH
4384       sfAlloc->cmnLcInfo.bchInfo.lcId = lcId;
4385 #endif
4386       sfAlloc->cmnLcInfo.bitMask |= RGINF_BCH_INFO;
4387    }
4388    else if((sf->bcch.pdcch != NULLP)&&
4389       !(sfAlloc->cmnLcInfo.bitMask & RGINF_BCCH_INFO))
4390    {
4391       sfAlloc->cmnLcInfo.bcchInfo.rnti = RGSCH_SI_RNTI;
4392       rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.bcchInfo.dciInfo),
4393                                        &(sf->bcch.pdcch->dci));
4394 #ifndef RGR_SI_SCH
4395       sfAlloc->cmnLcInfo.bcchInfo.lcId = lcId;
4396       sfAlloc->cmnLcInfo.bcchInfo.sndStatInd = sendInd;
4397 #endif
4398       sfAlloc->cmnLcInfo.bitMask |= RGINF_BCCH_INFO;
4399    }
4400    else if((sf->pcch.pdcch != NULLP) &&
4401       !(sfAlloc->cmnLcInfo.bitMask & RGINF_PCCH_INFO))
4402    {
4403       sfAlloc->cmnLcInfo.pcchInfo.rnti = RGSCH_P_RNTI;
4404       rgSCHUtlFillPdschDciInfo(&(sfAlloc->cmnLcInfo.pcchInfo.dciInfo),
4405                                          &(sf->pcch.pdcch->dci));
4406       sfAlloc->cmnLcInfo.pcchInfo.lcId = lcId;
4407       sfAlloc->cmnLcInfo.bitMask |= RGINF_PCCH_INFO;
4408    }
4409    return ROK;
4410 }
4411
4412 /** @brief This function fills in the RAR information to be sent to MAC
4413  *
4414  * @details
4415  *
4416  *     Function: rgSCHUtlFillRgInfRarInfo
4417  *
4418  * @param  RgSchCellCb  *cell 
4419  * @param  RgSchDlSf    *sf 
4420  * @param  RgInfSfAlloc *sfAlloc
4421  * @return  S16
4422  *      -# ROK
4423  *      -# RFAILED
4424  */
4425 S16 rgSCHUtlFillRgInfRarInfo(RgSchDlSf *sf,RgInfSfAlloc *sfAlloc,RgSchCellCb *cell)
4426 {
4427    uint8_t          idx;
4428    CmLListCp        *lnkLst;
4429    CmLList          *tmp;
4430    RgSchRaCb        *raCb;
4431    RgSchUeCb        *ue;
4432    RgInfRaRntiInfo  *raRntiAlloc;
4433    uint8_t          noRaRsps;
4434    RgSchCmnDlCell   *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4435
4436 #ifdef LTE_TDD
4437    noRaRsps = RGSCH_MAX_TDD_RA_RSP_ALLOC;
4438 #else
4439    noRaRsps = RGSCH_MAX_RA_RSP_ALLOC;
4440 #endif
4441
4442    for(idx =0; idx < noRaRsps; idx++)
4443    {
4444       if (sf->raRsp[idx].pdcch == NULLP)
4445       {
4446          /* No further raResp Allocations. */
4447          break;
4448       }
4449       /* Added Dl TB count for RACH Response transmission*/
4450 #ifdef LTE_L2_MEAS
4451       cell->dlUlTbCnt.tbTransDlTotalCnt++;
4452 #endif      
4453       raRntiAlloc = &(sfAlloc->rarInfo.raRntiInfo[idx]);
4454       raRntiAlloc->raRnti = sf->raRsp[idx].raRnti;
4455       raRntiAlloc->schdTbSz = sf->raRsp[idx].tbSz;
4456       raRntiAlloc->numCrnti = 0;
4457       rgSCHUtlFillPdschDciInfo(&(raRntiAlloc->dciInfo),
4458                       &(sf->raRsp[idx].pdcch->dci));
4459       /* RACHO : fill backoff indicator information */
4460       raRntiAlloc->backOffInd = sf->raRsp[idx].backOffInd;
4461
4462       /* Fill for contention free UEs*/
4463       lnkLst = &(sf->raRsp[idx].contFreeUeLst);
4464       CM_LLIST_FIRST_NODE(lnkLst, tmp);
4465       while (tmp)
4466       {
4467          ue = (RgSchUeCb *)tmp->node;
4468          tmp = tmp->next;
4469          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = ue->ueId;
4470          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = TRUE;
4471          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = ue->ul.rarGrnt.rapId;
4472 #ifndef MAC_5GTF_UPDATE
4473          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
4474                                                         ue->ul.rarGrnt.hop;
4475          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit =
4476                                                         ue->ul.rarGrnt.cqiReqBit;
4477 #endif
4478          /* SHASHAHNK ADD RIV CALC */
4479          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
4480                                                         ue->ul.rarGrnt.rbStart;
4481          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
4482                                                         ue->ul.rarGrnt.numRb;
4483          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
4484                                                         ue->ul.rarGrnt.tpc;
4485          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
4486                                                         ue->ul.rarGrnt.iMcsCrnt;
4487          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta = ue->ul.rarGrnt.ta;
4488          raRntiAlloc->numCrnti++;
4489          cmLListDelFrm(lnkLst, &ue->ul.rarGrnt.raRspLnk);
4490          ue->ul.rarGrnt.raRspLnk.node = (PTR)NULLP;
4491       }
4492       /* Fill for contention based UEs*/
4493       lnkLst = &(sf->raRsp[idx].raRspLst);
4494
4495       CM_LLIST_FIRST_NODE(lnkLst, tmp);
4496
4497       while((NULLP != tmp) && ((RgSchRaCb *)tmp->node != NULLP))
4498       {
4499          raCb     = (RgSchRaCb *)tmp->node;
4500
4501          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].tmpCrnti = raCb->tmpCrnti;
4502          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].isContFree = FALSE;
4503          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].rapId = raCb->rapId;
4504          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.pres = TRUE;
4505          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].ta.val = raCb->ta.val;
4506 #ifndef MAC_5GTF_UPDATE
4507          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.hop =
4508                                                         raCb->msg3Grnt.hop;
4509          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.cqiBit = FALSE;
4510 #endif
4511          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.rbStart =
4512                                                         raCb->msg3Grnt.rbStart;
4513          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.numRb =
4514                                                         raCb->msg3Grnt.numRb;
4515          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.tpc =
4516                                                         raCb->msg3Grnt.tpc;
4517          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.iMcsCrnt =
4518                                                         raCb->msg3Grnt.iMcsCrnt;
4519          raRntiAlloc->crntiInfo[raRntiAlloc->numCrnti].grnt.delayBit =
4520                                                         raCb->msg3Grnt.delayBit;
4521          /* For initial attaching UEs Aperiodic CQI need not be triggered */
4522          raRntiAlloc->numCrnti++;
4523          /* Search the next node */
4524          CM_LLIST_NEXT_NODE(lnkLst, tmp);
4525       }
4526    }
4527    sfAlloc->rarInfo.numRaRntis = idx;
4528    /* ccpu00132314-ADD-Update the tx power allocation info  
4529       TODO-Need to add a check for max tx power per symbol */
4530    sfAlloc->rarInfo.txPwrOffset = cellDl->rarTxPwrOffset;
4531
4532    return ROK;
4533 } /* end of rgSCHUtlFillRgInfRarInfo */
4534
4535 /** @brief This function fills in the pdsch data related allocation Info
4536  *         from the pdcch DCI info.
4537  * slot
4538  *
4539  * @details
4540  *
4541  *     Function: rgSCHUtlFillPdschDciInfo
4542  *
4543  *         Processing steps:
4544  *         - Depending upon the DCI Format, fill the appropriate fields.
4545  *
4546  * @param  [out] TfuPdschDciInfo *pdschDci
4547  * @param  [in]  TfuDciInfo      *pdcchDci
4548  * @return  S16
4549  *      -# ROK
4550  *      -# RFAILED
4551  */
4552 S16 rgSCHUtlFillPdschDciInfo(TfuPdschDciInfo *pdsch,TfuDciInfo *pdcchDci)
4553 {
4554
4555 #ifdef EMTC_ENABLE
4556   S16 ret = ROK; 
4557 #endif
4558    pdsch->format = pdcchDci->dciFormat;
4559    switch(pdcchDci->dciFormat)
4560    {
4561       case TFU_DCI_FORMAT_1:
4562          pdsch->u.format1AllocInfo = pdcchDci->u.format1Info.allocInfo;
4563          break;
4564       case TFU_DCI_FORMAT_1A:
4565          if (pdcchDci->u.format1aInfo.isPdcchOrder == FALSE)
4566          {
4567             pdsch->u.format1aAllocInfo = pdcchDci->u.format1aInfo.t.pdschInfo.allocInfo;
4568          }
4569          break;
4570       case TFU_DCI_FORMAT_1B:
4571          pdsch->u.format1bAllocInfo = pdcchDci->u.format1bInfo.allocInfo;
4572          break;
4573       case TFU_DCI_FORMAT_1C:
4574          pdsch->u.format1cAllocInfo = pdcchDci->u.format1cInfo;
4575          break;
4576       case TFU_DCI_FORMAT_1D:
4577          pdsch->u.format1dAllocInfo = pdcchDci->u.format1dInfo.allocInfo;
4578          break;
4579       case TFU_DCI_FORMAT_2:
4580          pdsch->u.format2AllocInfo = pdcchDci->u.format2Info.allocInfo;
4581          break;
4582       case TFU_DCI_FORMAT_2A:
4583          pdsch->u.format2AAllocInfo = pdcchDci->u.format2AInfo.allocInfo;
4584          break;
4585 #ifdef RG_5GTF
4586                 case TFU_DCI_FORMAT_B1:
4587          pdsch->u.formatB1Info = pdcchDci->u.formatB1Info;
4588          break;
4589       case TFU_DCI_FORMAT_B2:
4590          pdsch->u.formatB2Info = pdcchDci->u.formatB2Info;
4591          break;
4592 #endif
4593       default:
4594 #ifdef EMTC_ENABLE
4595  ret = rgSCHEmtcUtlFillPdschDciInfo(pdsch, pdcchDci);
4596  if(RFAILED == ret)
4597  {
4598       return RFAILED;
4599          }
4600 #else  
4601          return RFAILED;
4602 #endif
4603    }
4604    return ROK;
4605 }
4606
4607 /* LTE_ADV_FLAG_REMOVED_START */
4608 /**
4609  * @brief This function resets temporary variables in Pool
4610  * @details
4611  *
4612  *     Function: rgSchSFRResetPoolVariables
4613  *
4614  *     Invoked by: rgSCHSFRUtlTotalPoolInit
4615  *
4616  *  @param[in]  RgSchCellCb*     cell
4617  *  @param[in]  RgSubFrm*     subFrm
4618  *  @return  Void
4619  *
4620  **/
4621 Void rgSchDSFRPwrCheck(RgSchDlSf *sf,Bool *isAllUePwrHigh)
4622 {     
4623    RgSchSFRPoolInfo *sfrCCPool;
4624
4625    CmLListCp   *l;
4626    CmLList     *n;   
4627
4628    l = &sf->sfrTotalPoolInfo.ccPool;    
4629    n = cmLListFirst(l);
4630    while(n)
4631    {    
4632       sfrCCPool = (RgSchSFRPoolInfo*)n->node;
4633       if((sfrCCPool->poolstartRB == sfrCCPool->pwrHiCCRange.startRb) &&
4634             (sfrCCPool->poolendRB == sfrCCPool->pwrHiCCRange.endRb))
4635       {
4636          n = cmLListNext(l);
4637          if(n)
4638          {
4639             continue;
4640          }
4641          *isAllUePwrHigh = TRUE;
4642          break;
4643       }
4644       else
4645          break;   
4646    } 
4647 }
4648 /* LTE_ADV_FLAG_REMOVED_END */
4649 /***********************************************************
4650  *
4651  *     Func : rgSCHUtlFillRgInfTbInfo
4652  *
4653  *     Desc : Utility Function to fill the allocation info of each Tb
4654  *
4655  *
4656  *     Ret  :  void
4657  *
4658  *
4659  *     Notes: This function should be called while sending a msg from
4660  *     scheduler instance to MAC
4661  *
4662  *     File : rg_utl.c
4663  *
4664  **********************************************************/
4665 static Void rgSCHUtlFillRgInfTbInfo(RgSchDlHqProcCb *hqP,RgInfUeAlloc *allocInfo,RgSchCellCb *cell)
4666 {
4667    RgSchDlSf       *sf;
4668    uint8_t         idx;
4669    RgInfUeTbInfo   *tbInfo;
4670    uint8_t         tbCnt;
4671    /* LTE_ADV_FLAG_REMOVED_START */
4672 #ifdef TFU_UPGRADE
4673    static          uint32_t  tmpCnt = 0;
4674    Bool            isAllUePwrHigh = FALSE;
4675 #endif 
4676    /* LTE_ADV_FLAG_REMOVED_END */
4677    RgSchDlLcCb    *dlLcCb = NULLP;
4678    uint16_t       rlcHdrEstmt;
4679    uint8_t        lcId;
4680    /* RRM_RBC_X */
4681 #ifdef LTE_L2_MEAS
4682    uint8_t        prbUsed = 0;
4683 #endif
4684    /* RRM_RBC_Y */
4685
4686    CmLteTimingInfo        frm;
4687
4688    /* Get Downlink slot */
4689    frm   = cell->crntTime;
4690    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
4691    sf = rgSCHUtlSubFrmGet(cell, frm);
4692    /* Setting of fillCtrlPdu flag
4693       If both P-cell and S-cell are present,
4694       make TRUE for P-cell and FALSE for all s-cells
4695       For all other cases set TRUE */
4696 #ifdef LTE_ADV
4697    if ((rgSchCb[cell->instIdx].genCfg.forceCntrlSrbBoOnPCel) &&
4698          !RG_SCH_CMN_IS_PCELL_HQP(hqP))
4699    {
4700       allocInfo->fillCtrlPdu = FALSE;
4701    }
4702    else
4703    {
4704       allocInfo->fillCtrlPdu = TRUE;
4705    }
4706 #endif
4707
4708    allocInfo->tbStrtIdx = -1;
4709
4710
4711 #ifdef LTE_ADV
4712    allocInfo->tbReqInfo.sCellHqPId = 0xff;
4713    rgSCHLaaHndlFillRgInfTbInfo(cell, hqP, allocInfo);
4714 #endif
4715
4716    /*TODO:REEMA: Check and fill the isRetx */
4717    for(tbCnt = 0; tbCnt < 2; tbCnt++)
4718    {
4719       RgSchUeCb  *ue = NULLP;
4720       /*Changed as a result of CR timer*/
4721       if ((hqP->hqE->ue != NULLP)/* &&
4722       ((hqP->tbInfo[tbCnt].lchSchdData[0].lcId != 0) || \
4723        (hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF))*/)
4724       {
4725          ue = hqP->hqE->ue;
4726          allocInfo->rnti = ue->ueId;
4727          allocInfo->doa = hqP->hqE->ue->mimoInfo.doa;
4728          allocInfo->txMode = (TfuTxMode)(hqP->hqE->ue->mimoInfo.txMode);
4729          allocInfo->puschRptUsd = hqP->hqE->ue->mimoInfo.puschFdbkVld;
4730          allocInfo->puschPmiInfo = hqP->hqE->ue->mimoInfo.puschPmiInfo;
4731          if(hqP->tbInfo[tbCnt].schdTa.pres == PRSNT_NODEF)
4732          {
4733             hqP->tbInfo[tbCnt].taSnt = TRUE;
4734          }
4735 #ifdef TFU_UPGRADE
4736          if (RG_SCH_IS_PAPRSNT(ue,hqP->hqE->cell))
4737          {
4738             /*update pA value */
4739             allocInfo->pa = (RG_SCH_CMN_GET_PA(ue,hqP->hqE->cell)).val;
4740          }
4741 #endif
4742
4743          /* LTE_ADV_FLAG_REMOVED_START */
4744          /* If ABS is enabled, calculate resource used */
4745          if((0 == tbCnt) && (RGR_ENABLE == ue->cell->lteAdvCb.absCfg.status))
4746          {
4747             /* For Macro count number resource used in Non-ABS SF */
4748             if(RGR_ABS_MUTE == ue->cell->lteAdvCb.absCfg.absPatternType)
4749             {
4750                if(RG_SCH_ABS_ENABLED_NONABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
4751                {
4752                   ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
4753                      hqP->tbInfo[tbCnt].dlGrnt.numRb;
4754                }
4755             }
4756             /* For pico count number resource used in ABS SF for ABS UE */
4757             else if(RGR_ABS_TRANSMIT == ue->cell->lteAdvCb.absCfg.absPatternType)
4758             {
4759                if(RG_SCH_ABS_ENABLED_ABS_SF == ue->cell->lteAdvCb.absDlSfInfo)
4760                {
4761                   if(TRUE == ue->lteAdvUeCb.rgrLteAdvUeCfg.isAbsUe)
4762                   {
4763                      ue->cell->lteAdvCb.absLoadInfo[ue->cell->lteAdvCb.absPatternDlIdx]+=
4764                         hqP->tbInfo[tbCnt].dlGrnt.numRb;
4765                   }
4766                }
4767             }
4768          } 
4769
4770 #ifdef TFU_UPGRADE         
4771          /*if SFR is enabled*/
4772          allocInfo->isEnbSFR = (uint8_t)RG_SCH_CMN_IS_SFR_ENB(ue->cell); /* KW fix for LTE_ADV */
4773          if((ue->cell->lteAdvCb.dsfrCfg.status == RGR_ENABLE) && 
4774                (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == FALSE))
4775          {         
4776             rgSchDSFRPwrCheck(sf, &isAllUePwrHigh);          
4777          } 
4778          if(isAllUePwrHigh)
4779          {  
4780             allocInfo->pa = (uint8_t)ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;  /* KW fix for LTE_ADV */  
4781             if(tmpCnt++ == 100000)
4782             {
4783                DU_LOG("\nDEBUG  -->  SCH : DSFR::ll UEs can go HIGH, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
4784                tmpCnt = 0;
4785             }
4786          }    
4787          else
4788          {  
4789             if (allocInfo->isEnbSFR)
4790             {
4791                /*Update pA to Plow if it is cell-centred ,else pA will be pHigh*/
4792                if (ue->lteAdvUeCb.rgrLteAdvUeCfg.isUeCellEdge == TRUE)
4793                {  
4794                   allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
4795                   if(tmpCnt++ == 100000)
4796                   {
4797                      DU_LOG("\nDEBUG  -->  SCH : SFR::UE is CELL EDGE, PHigh(%d) for UE(%d)",allocInfo->pa, ue->ueId);
4798                      tmpCnt = 0;
4799                   }
4800
4801                }  
4802                else
4803                {
4804                   if(TRUE == ue->lteAdvUeCb.isCCUePHigh)
4805                   {
4806                      allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pHigh;
4807                      ue->lteAdvUeCb.isCCUePHigh = FALSE;
4808                   }
4809                   else
4810                   {
4811                      allocInfo->pa = ue->cell->lteAdvCb.sfrCfg.pwrThreshold.pLow;
4812                      if(tmpCnt++ == 100000)
4813                      {
4814                         DU_LOG("\nDEBUG  -->  SCH : SFR::UE is CELL CENTRE, PLow(%d) for UE(%d)\n",allocInfo->pa, ue->ueId);
4815                         tmpCnt = 0;
4816                      }
4817                   }
4818                }
4819             }
4820          }
4821          /* LTE_ADV_FLAG_REMOVED_END */
4822 #endif         
4823       }
4824       else
4825       {
4826          if (hqP->hqE->raCb)
4827          {
4828 #ifdef TFU_UPGRADE
4829             RgSchCmnDlCell   *cellDl = RG_SCH_CMN_GET_DL_CELL(cell);
4830 #endif 
4831 #ifdef LTEMAC_SPS
4832             allocInfo->pdcchRnti = hqP->hqE->raCb->tmpCrnti;
4833 #endif
4834             allocInfo->rnti  =  hqP->hqE->raCb->tmpCrnti;
4835 #ifdef TFU_UPGRADE
4836             /*ccpu00132314-ADD-Use a default pA value
4837               for msg4 */
4838             allocInfo->pa = cellDl->msg4pAVal; 
4839 #endif 
4840          }
4841       }
4842       /* If TB Is scheduled for this SF */
4843       if(hqP->tbInfo[tbCnt].state == HQ_TB_WAITING)
4844       {
4845          if (allocInfo->tbStrtIdx == -1){
4846             allocInfo->tbStrtIdx = tbCnt;
4847 #ifndef LTEMAC_SPS
4848             rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
4849                                &(hqP->pdcch->dci));
4850 #else
4851             if (hqP->pdcch)
4852             {
4853                rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
4854                      &(hqP->pdcch->dci));
4855             }
4856             else if ((ue) && (ue->dl.spsOccPdcch.rnti == ue->spsRnti))
4857             {
4858                rgSCHUtlFillPdschDciInfo(&(allocInfo->dciInfo),
4859                      &(ue->dl.spsOccPdcch.dci));
4860             }
4861 #endif /* ifndef LTEMAC_SPS */
4862          }
4863 #ifdef LTEMAC_SPS
4864             if (hqP->pdcch)
4865             {
4866                allocInfo->pdcchRnti = hqP->pdcch->rnti;
4867             }
4868             else if (ue)
4869             {
4870                allocInfo->pdcchRnti = ue->spsRnti;
4871             }
4872 #endif
4873          tbInfo = &(allocInfo->tbInfo[tbCnt]);
4874          allocInfo->nmbOfTBs++;
4875          allocInfo->hqProcId = hqP->procId;
4876          allocInfo->tbInfo[tbCnt].schdTbSz = hqP->tbInfo[tbCnt].tbSz;
4877
4878          tbInfo->disTb  = FALSE;
4879          if(!(hqP->tbInfo[tbCnt].txCntr))
4880          {
4881 #ifdef LTE_ADV
4882             if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
4883                         rgSCHLaaSCellEnabled(cell))))
4884 #endif
4885             {
4886                hqP->tbInfo[tbCnt].txCntr++;
4887             }
4888             for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
4889             {
4890                tbInfo->schdDat[idx].lcId =\
4891                   hqP->tbInfo[tbCnt].lchSchdData[idx].lcId;
4892                tbInfo->schdDat[idx].numBytes =\
4893                   hqP->tbInfo[tbCnt].lchSchdData[idx].schdData;
4894                if(hqP->hqE->ue)
4895                {
4896                   lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId; 
4897                   if(lcId != 0)
4898                   {
4899                      dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
4900                      if(dlLcCb != NULLP)
4901                      {
4902                         RG_SCH_CMN_DL_GET_HDR_EST(dlLcCb, rlcHdrEstmt);
4903                         /* Update the totalBo with the scheduled bo */
4904                         (hqP->hqE->ue->totalBo <= tbInfo->schdDat[idx].numBytes - rlcHdrEstmt)?\
4905                                                   (hqP->hqE->ue->totalBo = 0):\
4906                                                   (hqP->hqE->ue->totalBo -= tbInfo->schdDat[idx].numBytes-rlcHdrEstmt);
4907
4908                         /* RRM_RBC_X */
4909 #ifdef LTE_L2_MEAS
4910                         prbUsed = ((hqP->tbInfo[tbCnt].\
4911                                  lchSchdData[idx].schdData  *
4912                                  hqP->tbInfo[tbCnt].dlGrnt.numRb) /
4913                               (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
4914                         dlLcCb->qciCb->dlPrbCount += prbUsed;
4915                         if(dlLcCb->qciCb->qci > 0)
4916                         {
4917                            RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
4918                         }
4919 #endif                        /* RRM_RBC_Y */
4920
4921 #ifdef RG_PFS_STATS
4922                         //if(!(hqP->hqE->ue->pfsStats.lcStats[lcId-1].isLcCntSet))
4923                         if(tbCnt == 0)
4924                         {
4925                            uint8_t idx = 0;
4926                            if (hqP->hqE->ue->cell == hqP->hqE->cell)
4927                            {
4928                               idx = RGSCH_PCELL_INDEX;
4929                            }
4930                            else
4931                            {
4932                               idx = RG_SCH_GET_SCELL_INDEX((hqP->hqE->ue), (hqP->hqE->cell));
4933                            }
4934                            hqP->hqE->ue->pfsStats.lcStats[lcId-1].ueSchdOcc[idx]++;
4935                            hqP->hqE->ue->pfsStats.lcStats[lcId-1].perRefresh[ue->pfsStats.lcStats[lcId-1].lastIdx].lcSchdOcc++;
4936                         }   
4937 #endif
4938                      }
4939                   }
4940                }
4941             }
4942             /* Added Dl TB count for SRB/DRB data transmission*/
4943 #ifdef LTE_L2_MEAS 
4944             cell->dlUlTbCnt.tbTransDlTotalCnt++;  
4945 #endif            
4946             tbInfo->ta.pres = hqP->tbInfo[tbCnt].schdTa.pres;
4947             tbInfo->ta.val =  hqP->tbInfo[tbCnt].schdTa.val;
4948 #ifdef LTE_ADV
4949             tbInfo->sCellActCe = hqP->tbInfo[tbCnt].schdSCellActCe;
4950 #endif
4951             tbInfo->numSchLch = hqP->tbInfo[tbCnt].numLch;
4952             if(!(hqP->tbInfo[tbCnt].numLch))
4953             {
4954                tbInfo->schdDat[tbInfo->numSchLch].numBytes= hqP->tbInfo[tbCnt].tbSz;
4955                /* Fix: If only TA is scheduled, use some dummy LCID */
4956                if (tbInfo->ta.pres)
4957                   tbInfo->schdDat[tbInfo->numSchLch].lcId = RG_TA_LCID;
4958             }
4959
4960             tbInfo->contResCe = hqP->tbInfo[tbCnt].contResCe;
4961             tbInfo->isReTx = FALSE;
4962          }
4963          else
4964          {
4965 #ifdef LTE_ADV
4966             if(!((rgSCHLaaCheckIfLAAProc(hqP)) && (TRUE ==
4967                         rgSCHLaaSCellEnabled(cell))))
4968 #endif
4969             {
4970                hqP->tbInfo[tbCnt].txCntr++;
4971             }
4972             tbInfo->isReTx = TRUE;
4973             /* RRM_RBC_X */
4974             /* As per 36.314, harq retransmission also considered for 
4975              * prb utilization calculation*/
4976             for(idx = 0; idx < hqP->tbInfo[tbCnt].numLch; idx++)
4977             {
4978 #ifdef LTE_L2_MEAS
4979                if(hqP->hqE->ue)
4980                {
4981                   lcId = hqP->tbInfo[tbCnt].lchSchdData[idx].lcId; 
4982                   if(lcId != 0)
4983                   {
4984                      dlLcCb = hqP->hqE->ue->dl.lcCb[lcId-1];
4985                      if(dlLcCb != NULLP)
4986                      {
4987                         prbUsed = ((hqP->tbInfo[tbCnt].\
4988                                lchSchdData[idx].schdData  *
4989                                hqP->tbInfo[tbCnt].dlGrnt.numRb) /
4990                                   (hqP->tbInfo[0].tbSz + hqP->tbInfo[1].tbSz));
4991                         if(dlLcCb->qciCb->qci > 0)
4992                         {
4993                            RG_SCH_CALC_GBR_UTILIZATION(cell, dlLcCb, prbUsed);
4994                         }
4995                      }
4996                   }
4997                }
4998 #endif
4999             }
5000             /* RRM_RBC_Y */
5001          }
5002       }
5003     }
5004 #ifdef LTE_ADV 
5005    rgSCHLaaResetDlHqProcCb(hqP);
5006 #endif
5007
5008    return;
5009 }
5010 /***********************************************************
5011  *
5012  *     Func : rgSCHUtlFillRgInfUeInfo
5013  *
5014  *     Desc : Utility Function to fill the allocation info of Ue
5015  *             : MIMO : Filling 2TB's of each UE
5016  *
5017  *     Ret  : ROK
5018  *            RFAILED
5019  *
5020  *     Notes: This function should be called while sending a msg from
5021  *     scheduler instance to MAC
5022  *
5023  *     File : rg_utl.c
5024  *
5025  **********************************************************/
5026   /* CA dev Start */
5027 Void rgSCHUtlFillRgInfUeInfo(RgSchDlSf *sf,RgSchCellCb *cell,CmLListCp *dlDrxInactvTmrLst,CmLListCp *dlInActvLst,CmLListCp  *ulInActvLst)
5028 {
5029    RgInfSfAlloc    *sfAlloc;
5030    CmLListCp       *lnkLst;   /* lnkLst assignment */
5031    CmLList         *tmp;
5032    CmLList         *hqPNode;
5033    RgSchUeCb       *ue = NULLP;
5034    RgInfUeInfo     *ueInfo = NULLP;
5035    RgInfUeAlloc    *ueAlloc = NULLP;
5036    RgSchDlHqProcCb *hqCb = NULLP;
5037
5038    /* Since Msg4 is sched only on PCELL, use cell arg's sfAllocArr */
5039    sfAlloc = &(cell->sfAllocArr[cell->crntSfIdx]);
5040    ueInfo = &(sfAlloc->ueInfo);
5041    ueAlloc = sfAlloc->ueInfo.allocInfo;
5042
5043    lnkLst = &(sf->msg4HqPLst);
5044    CM_LLIST_FIRST_NODE(lnkLst, tmp);
5045    while(NULLP != tmp)
5046    {
5047       DU_LOG("\nINFO  -->  SCH : 5GTF_ERROR MSG4 Consolidation\n");
5048       hqCb = (RgSchDlHqProcCb *)(tmp->node);
5049       CM_LLIST_NEXT_NODE(lnkLst, tmp);
5050
5051       rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], cell);
5052
5053       ue = hqCb->hqE->ue;
5054
5055       if(ue != NULLP)
5056       {   
5057          if((!(ue->dl.dlInactvMask & RG_HQENT_INACTIVE)) && (ue->isDrxEnabled))
5058          {   
5059             rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes], 
5060                   dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
5061          }
5062       }
5063       ueInfo->numUes++;
5064    }
5065  
5066    lnkLst = &(sf->ueLst);
5067    CM_LLIST_FIRST_NODE(lnkLst, tmp);
5068    while(NULLP != tmp)
5069    {
5070 #if defined (TENB_STATS) && defined (RG_5GTF)
5071       cell->tenbStats->sch.dl5gtfPdschCons++;
5072 #endif
5073       ue = (RgSchUeCb *)(tmp->node);
5074       CM_LLIST_NEXT_NODE(lnkLst, tmp);
5075
5076       hqPNode = ue->dl.dlSfHqInfo[cell->cellId][sf->dlIdx].hqPLst.first;
5077       while (hqPNode)
5078       {
5079          hqCb = (RgSchDlHqProcCb *)hqPNode->node;
5080          hqPNode = hqPNode->next;
5081
5082          sfAlloc = &(hqCb->hqE->cell->sfAllocArr[hqCb->hqE->cell->crntSfIdx]);
5083          ueInfo = &(sfAlloc->ueInfo);
5084          ueAlloc = sfAlloc->ueInfo.allocInfo;
5085
5086          rgSCHUtlFillRgInfTbInfo(hqCb, &ueAlloc[ueInfo->numUes], 
5087                hqCb->hqE->cell);
5088
5089          if(ue->isDrxEnabled)
5090          {   
5091             rgSCHUtlGetDrxSchdUesInDl(cell, ue, hqCb, &ueAlloc[ueInfo->numUes], 
5092                   dlDrxInactvTmrLst, dlInActvLst, ulInActvLst);
5093          }
5094          ueInfo->numUes++;
5095       }
5096 #ifdef LTE_ADV
5097       if (rgSchCb[cell->instIdx].genCfg.isSCellActDeactAlgoEnable == TRUE)
5098       {
5099          /*If remaining BO is left then increment the count*/
5100          if(ue->totalBo > 0)
5101          {
5102             ue->remBoCnt++;
5103             /* Check if trigger for Activation is met or not */
5104             if(rgSCHIsActvReqd(cell, ue))
5105             {
5106                ue->remBoCnt = 0;
5107                /*Passing primary cell*/
5108                rgSCHSCellSelectAndActDeAct(ue->cell, ue, RGR_SCELL_ACT);
5109             }
5110          }
5111          else
5112          {
5113             /*If remaining BO is 0 then reset the count*/
5114             ue->remBoCnt = 0;
5115          }
5116       }
5117 #endif
5118    }
5119   
5120    return;
5121 } /* end of rgSCHUtlFillRgInfUeInfo */
5122   /* CA dev End */
5123
5124
5125 /** @brief This function  shall update the scheduler with the CEs and data rcvd
5126  *
5127  * @details
5128  *
5129  *     Function: rgSCHUtlUpdSch
5130  *
5131  *         Processing steps:
5132  *         - Collate the information of all the SDUs received and inform the
5133  *         scheduler rgSCHDataRcvd
5134  *         - Send Data indication to the higher layer with the dedicated data
5135  *         (rgUIMSndDedDatInd)
5136  *         - Inform scheduler with any MAC CEs if present.
5137  *
5138  * @param  [in] RgCellCb   *cellCb
5139  * @param  [in] RgUeCb     *ueCb
5140  * @param  [in] RgMacPdu   *pdu
5141  * @param  [in] RgSchErrInfo  *err
5142  *  @return  S16
5143  *      -# ROK
5144  *      -# RFAILED
5145  */
5146 S16 rgSCHUtlUpdSch(RgInfSfDatInd *subfrmInfo,RgSchCellCb *cellCb,RgSchUeCb *ueCb,RgInfUeDatInd  *pdu,RgSchErrInfo *err)
5147 {
5148
5149    S16               ret;
5150 #ifdef LTEMAC_SPS
5151    if (RGSCH_UL_SPS_ACT_PRSENT & pdu->ceInfo.bitMask)
5152    {
5153       /* SPS to be activated due to data on SPS LCG ID*/
5154       rgSCHUtlSpsActInd(cellCb, ueCb, pdu->ceInfo.spsSduSize);
5155    }
5156 #endif
5157    /* TODO : Temp Fix for crash due to UL SDU corruption*/
5158    if (RGSCH_PHR_CE_PRSNT & pdu->ceInfo.bitMask)
5159    {
5160       /* PHR present */
5161       RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
5162       if ((ret = rgSCHUtlUpdPhr(cellCb, ueCb, pdu->ceInfo.ces.phr, err)) != ROK)
5163          return (ret);
5164    }
5165    /* Note: Order of indication to Sch now is
5166     *       1st Indicate the DataInd info for each LCG's
5167     *       2nd Update the BSR reports received along with data
5168     *       this is to make sure the effBsr is updated to the latest BSR 
5169     *       received.
5170     */
5171    cellCb->sc.apis->rgSCHUpdUeDataIndLcg(cellCb, ueCb, pdu);
5172
5173 #ifndef MAC_5GTF_UPDATE
5174    if (RGSCH_TRUNC_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
5175    {
5176       RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
5177       /*ccpu00129922 - MOD - Deleted return value
5178        * checking since it returns void*/
5179       rgSCHUtlUpdBsrTrunc (cellCb, ueCb,
5180                   (uint8_t)(pdu->ceInfo.ces.bsr.truncBsr >> 6),
5181                   (uint8_t)(pdu->ceInfo.ces.bsr.truncBsr & 0x3F), err); 
5182    }
5183    else
5184    {
5185       if (RGSCH_SHORT_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
5186       {
5187          RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
5188          /*ccpu00129922 - MOD - Deleted return value
5189           checking since it returns void*/
5190          rgSCHUtlUpdBsrShort (cellCb, ueCb,
5191                      (uint8_t)(pdu->ceInfo.ces.bsr.shortBsr >> 6),
5192                      (uint8_t)(pdu->ceInfo.ces.bsr.shortBsr & 0x3F), err);
5193       }
5194       else
5195       {
5196          if (RGSCH_LONG_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
5197 #else
5198          if (RGSCH_BSR_CE_PRSNT & pdu->ceInfo.bitMask)
5199 #endif
5200          {
5201             RGSCHCPYTIMEINFO(subfrmInfo->timingInfo, ueCb->macCeRptTime);
5202             /*ccpu00129922 - MOD - Deleted return value
5203               checking since it returns void*/
5204             rgSCHUtlUpdBsrLong (cellCb, ueCb,
5205                         pdu->ceInfo.ces.bsr.longBsr.bs1,
5206                         pdu->ceInfo.ces.bsr.longBsr.bs2,
5207                         pdu->ceInfo.ces.bsr.longBsr.bs3,
5208                         pdu->ceInfo.ces.bsr.longBsr.bs4,
5209                         err);
5210          }
5211 #ifndef MAC_5GTF_UPDATE
5212       }
5213  
5214    }
5215 #endif
5216             
5217    return ROK;
5218 } /* end of rgSCHUtlUpdSch */
5219 #ifdef RGR_V1
5220 /**
5221  * @brief Handler for Updating Bo received in StaRsp
5222  *
5223  * @details
5224  *
5225  *     Function : rgSCHUtlAddUeToCcchSduLst
5226  *
5227  *     This function shall be invoked once it receives staRsp on CCCH
5228  *
5229  *  @param[in]     RgSchCellCb       *cell
5230  *  @param[in]     RgSchUeCb       *ueCb
5231  *  @return  S16
5232  *      -# ROK
5233  **/
5234 S16 rgSCHUtlAddUeToCcchSduLst(RgSchCellCb  *cell,RgSchUeCb *ueCb)
5235 {
5236    RgSchCmnDlUe  *ueDl = RG_SCH_CMN_GET_DL_UE(ueCb, cell);
5237    RgSchDlHqProcCb *hqP  = (RgSchDlHqProcCb *)ueDl->proc;
5238
5239    /* Temp Guard: For back to back CCCH SDU BO 
5240     * twice. Hence an extra guard. If already added to scheduling
5241     * queue or if scheduled and waiting for HQ FDBK, ignore */
5242    if ((ueCb->ccchSduLnk.node) ||
5243        ((!(ueCb->dl.dlInactvMask & RG_HQENT_INACTIVE)) &&
5244        ((hqP != NULLP) && (hqP->hqE->ccchSduProc))))
5245    {
5246       DU_LOG("\nINFO  -->  SCH : RNTI:%d Unexpected CCCH SDU BO",
5247          ueCb->ueId);
5248       return ROK;
5249    }
5250
5251    ueCb->ccchSduLnk.node = (PTR)(ueCb);
5252    cmLListAdd2Tail(&(cell->ccchSduUeLst), &(ueCb->ccchSduLnk));
5253
5254    return ROK;
5255 }
5256 /**
5257  *
5258  * @details
5259  *
5260  *     Function : rgSCHUtlUpdtBo
5261  *
5262  *     This function shall be invoked once it receives staRsp on CCCH
5263  *
5264  *  @param[in]     RgSchCellCb       *cell
5265  *  @param[in]     RgRguCmnStaRsp *staRsp
5266  *  @return  S16
5267  *      -# ROK
5268  **/
5269 S16 rgSCHUtlUpdtBo(RgSchCellCb  *cell,RgInfCmnBoRpt *staRsp)
5270 {
5271    RgSchUeCb *ueCb;
5272
5273    if ((ueCb = rgSCHDbmGetUeCb(cell, staRsp->u.rnti)) == NULLP)
5274    {
5275       /* Handle Ue fetch failure */
5276       DU_LOG("\nERROR  -->  SCH : Invalid UEID:%d",staRsp->u.rnti);
5277       return RFAILED;
5278    }
5279    /* Update Bo in ueCb */
5280    ueCb->dlCcchInfo.bo = (uint32_t)(staRsp->bo);
5281 #ifdef EMTC_ENABLE
5282      if(ueCb->isEmtcUe)
5283      {
5284         rgSCHUtlAddUeToEmtcCcchSduLst(cell,ueCb);
5285      }
5286      else
5287 #endif
5288     {
5289       rgSCHUtlAddUeToCcchSduLst(cell, ueCb);
5290     }
5291
5292    return ROK;
5293 } /* rgSCHUtlUpdtBo */
5294
5295 #endif
5296 /**
5297  *
5298  * @details
5299  *     Function : rgSCHUtlHndlCcchBoUpdt
5300  *
5301  *     This function shall fetch the raCb with the given rnti and ask RAM to
5302  *     update BO
5303  *
5304  *
5305  *  @param[in]  RgSchCellCb    *cell
5306  *  @param[in]  RgInfCmnBoRpt *boRpt
5307  *  @return  S16
5308  *      -# ROK
5309  *      -# RFAILED
5310  **/
5311 S16 rgSCHUtlHndlCcchBoUpdt(RgSchCellCb *cell,RgInfCmnBoRpt *boRpt)
5312 {
5313    RgSchRaCb       *raCb;
5314    RgSchUeCb *ueCb;
5315
5316    if ((raCb = rgSCHDbmGetRaCb(cell, boRpt->u.rnti)) == NULLP)
5317    {
5318 #ifdef RGR_V1
5319    /* CR timer implementation changes*/
5320       /*If no raCb, schedule ueCb, ueCb is extracted in rgSCHUtlUpdtBo*/
5321       return (rgSCHUtlUpdtBo(cell, boRpt));
5322 #else
5323       /* Handle RaCb fetch failure */
5324       DU_LOG("\nERROR  -->  SCH : Invalid RNTI:%d to fetch raCb",boRpt->u.rnti);
5325       return RFAILED;
5326 #endif
5327    }
5328
5329 #ifdef RGR_V1
5330
5331       /*Fix: If RaCb exists, then MSG4 is not completed yet*/
5332       /*Check if guard timer has expired, if not CR CE + CCCH SDU will be scheduled*/
5333       if((raCb->contResTmrLnk.node != NULLP) && \
5334             (raCb->schdLnk.node == NULLP) && (raCb->dlHqE->msg4Proc == NULLP))
5335       {
5336 #ifdef EMTC_ENABLE
5337          /*if contention resolution timer left ,Stop the Contention Resolution Guard Timer ,
5338          add in toBeSchduled list and update the Bo */
5339          if(TRUE == raCb->isEmtcRaCb)
5340          {
5341             rgSCHRamEmtcUpdtBo(cell, raCb, boRpt);
5342          }
5343          else
5344 #endif
5345          {
5346             cmLListDelFrm(&cell->contResGrdTmrLst, &(raCb->contResTmrLnk));
5347             raCb->contResTmrLnk.node=NULLP;               
5348             rgSCHRamUpdtBo(cell, raCb, boRpt);
5349          }
5350        }
5351       else
5352       {
5353          /*Fix:Guard timer has expired */
5354          /*Update the BO in UE CB but dont add it to the scheduling list. 
5355           *Should be added to the list after MSG4 completion*/
5356          if ((ueCb = rgSCHDbmGetUeCb(cell, boRpt->u.rnti)) == NULLP)
5357          {
5358             /* Handle Ue fetch failure */
5359             DU_LOG("\nERROR  -->  SCH : Invalid RNTI:%d",boRpt->u.rnti);
5360             return RFAILED;
5361          }
5362          /* Update Bo in ueCb */
5363          ueCb->dlCcchInfo.bo = (uint32_t)(boRpt->bo);     
5364       }
5365
5366 #else
5367       rgSCHRamUpdtBo(cell, raCb, boRpt);
5368 #endif
5369
5370    return ROK;
5371 } /* rgSCHUtlHndlCcchBoUpdt */
5372
5373 /**
5374  * @brief Validates BO received for BCCH or PCCH.
5375  *
5376  * @details
5377  *
5378  *     Function : rgSCHUtlGetAllwdCchTbSz
5379  *
5380  *     This function shall return the tbSz equal to or
5381  *     the nearest greater value for a given bo.
5382  *     If no such value found return -1. The nPrb value is
5383  *     accordingly set.
5384  *
5385  *
5386  *  @param[in]  uint32_t            bo
5387  *  @param[out] uint8_t             *nPrb
5388  *  @return  S32
5389  *      -# ROK
5390  *      -# RFAILED
5391  **/
5392 S32 rgSCHUtlGetAllwdCchTbSz(uint32_t bo,uint8_t  *nPrb,uint8_t  *mcs)
5393 {
5394    S32 lt;
5395    S32 cn;
5396    S32 rt;
5397
5398    for (lt = 0, rt = 43; lt <= rt;)
5399    {
5400       cn = (lt + rt)/2;
5401       if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz == bo)
5402       {
5403          *nPrb = rgSchUtlBcchPcchTbSzTbl[cn].rbIndex;
5404          *mcs  = rgSchUtlBcchPcchTbSzTbl[cn].mcs;
5405          return (rgSchUtlBcchPcchTbSzTbl[cn].tbSz);
5406       }
5407       else if (rgSchUtlBcchPcchTbSzTbl[cn].tbSz < bo)
5408          lt = cn + 1;
5409       else
5410          rt = cn - 1;
5411    }
5412    if (lt == 44)
5413    {
5414       return RFAILED;
5415    }
5416    *nPrb = rgSchUtlBcchPcchTbSzTbl[lt].rbIndex;
5417    *mcs  = rgSchUtlBcchPcchTbSzTbl[lt].mcs;
5418    return (rgSchUtlBcchPcchTbSzTbl[lt].tbSz);
5419 }
5420
5421 /**
5422  * @brief Handler for BO Updt received for BCCH or PCCH.
5423  *
5424  * @details
5425  *
5426  *     Function : rgSCHUtlHndlBcchPcchBoUpdt
5427  *
5428  *     This function shall store the buffer and time to transmit in lcCb
5429  *
5430  *
5431  *  @param[in]  RgSchCellCb    *cell
5432  *  @param[in]  RgInfCmnBoRpt  *boRpt
5433  *  @return  S16
5434  *      -# ROK
5435  *      -# RFAILED
5436  **/
5437 S16 rgSCHUtlHndlBcchPcchBoUpdt(RgSchCellCb *cell,RgInfCmnBoRpt *boUpdt)
5438 {
5439    RgSchClcDlLcCb *dlLc;
5440    RgSchClcBoRpt  *boRpt;
5441    Inst           inst = cell->instIdx;
5442    uint8_t             nPrb=0;
5443    uint8_t             mcs=0;
5444
5445    dlLc = rgSCHDbmGetBcchOnBch(cell);
5446    if (dlLc == NULLP)
5447    {
5448       DU_LOG("\nERROR  -->  SCH : No Logical Channel dlLc is NULLP for RNTI:%d LCID:%d",boUpdt->u.rnti,boUpdt->lcId);
5449       return RFAILED;
5450    }
5451    if (boUpdt->lcId != dlLc->lcId)
5452    {
5453       /* Added for dropping paging Message*/      
5454           /*suman*/
5455       if ((rgSCHChkBoUpdate(cell,boUpdt))== ROK)  /* Checking if received BO falls within the window of 5120 slots*/
5456       {
5457          if (rgSCHUtlGetAllwdCchTbSz(boUpdt->bo*8, &nPrb, &mcs) 
5458                != (boUpdt->bo*8))
5459          {
5460             DU_LOG("\nERROR  -->  SCH : [%d]BO: does not match any "
5461                   "valid TB Size RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
5462             return RFAILED;
5463          }
5464       }/*end of rgSCHChkBoUpdate*/
5465       else
5466       {
5467           return ROK;
5468       } 
5469    }
5470    if ((dlLc = rgSCHDbmGetCmnLcCb(cell, boUpdt->lcId)) == NULLP)
5471    {
5472       /* Handle lcCb fetch failure */
5473       DU_LOG("\nERROR  -->  SCH : LCID:%d Invalid for RNTI:%d",boUpdt->lcId,boUpdt->u.rnti);
5474    }
5475
5476    if (((rgSCHUtlAllocSBuf(inst, (Data **)(&boRpt), sizeof(RgSchClcBoRpt))) ==RFAILED) ||
5477        (!boRpt))
5478    {
5479       DU_LOG("\nERROR  -->  SCH : Allocation of common bo %dreport "
5480          "failed  RNTI:%d LCID:%d", boUpdt->bo,boUpdt->u.rnti,boUpdt->lcId);
5481       return RFAILED;
5482    }
5483
5484    boRpt->bo = boUpdt->bo;
5485    boRpt->mcs = mcs;
5486    boRpt->timeToTx = boUpdt->u.timeToTx;
5487    boRpt->nPrb = nPrb;
5488 #ifdef EMTC_ENABLE
5489    if(cell->emtcEnable)
5490    {
5491       boRpt->emtcDIReason = boUpdt->emtcDIReason;
5492       boRpt->pnb = boUpdt->pnb;
5493    }
5494 #endif
5495    RG_SCH_ADD_TO_CRNT_TIME(boRpt->timeToTx, 
5496          boRpt->maxTimeToTx, cell->siCfg.siWinSize)
5497    if((NULLP != dlLc) && (dlLc->si))
5498    {
5499       boRpt->retxCnt = cell->siCfg.retxCnt;
5500    }
5501    else
5502    {
5503       boRpt->retxCnt = 0;
5504    }
5505    rgSCHDbmInsCmnLcBoRpt(dlLc, boRpt);
5506
5507    return ROK;
5508 } /* rgSCHUtlHndlBcchPcchBoUpdt */
5509
5510 /**
5511  * @brief API for sending bind confirm from Scheduler instance to RRM
5512  *
5513  * @details
5514  *
5515  *     Function: rgSCHUtlRgrBndCfm
5516  *
5517  *     This API is invoked to send bind confirm from Scheduler instance to RRM.
5518  *     This API fills in Pst structure and SAP Ids and invokes
5519  *     bind confirm API towards RRM.
5520  *
5521  *  @param[in]  SuId          suId
5522  *  @param[in]  uint8_t            status
5523  *  @return  S16
5524  *      -# ROK
5525  *      -# RFAILED
5526  **/
5527 S16 rgSCHUtlRgrBndCfm(Inst instId,SuId suId,uint8_t status)
5528 {
5529    S16  ret = ROK;
5530
5531    ret = RgUiRgrBndCfm(&rgSchCb[instId].rgrSap[suId].sapCfg.sapPst, rgSchCb[instId].rgrSap[suId].sapCfg.suId, status);
5532    if (ret != ROK)
5533    {
5534       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrBndCfm: RgUiRgrBndCfm Failed ");
5535       return (ret);
5536    }
5537    return (ret);
5538 }  /* rgSCHUtlRgrBndCfm*/
5539
5540 /**
5541  * @brief API for sending bind confirm from Scheduler instance to RRM via RGM
5542  *        interface
5543  *
5544  * @details
5545  *
5546  *     Function: rgSCHUtlRgmBndCfm
5547  *
5548  *     This API is invoked to send bind confirm from Scheduler instance to RRM.
5549  *     This API fills in Pst structure and SAP Ids and invokes
5550  *
5551  *  @param[in]  SuId          suId
5552  *  @param[in]  uint8_t            status
5553  *  @return  S16
5554  *      -# ROK
5555  *      -# RFAILED
5556  **/
5557 S16 rgSCHUtlRgmBndCfm(Inst instId,SuId suId,uint8_t status)
5558 {
5559    S16  ret = ROK;
5560
5561    ret = RgUiRgmBndCfm(&rgSchCb[instId].rgmSap[suId].sapCfg.sapPst, rgSchCb[instId].rgmSap[suId].sapCfg.suId, status);
5562    if (ret != ROK)
5563    {
5564       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgmBndCfm: RgUiRgrBndCfm Failed ");
5565       return (ret);
5566    }
5567    return (ret);
5568 }  /* rgSCHUtlRgmBndCfm*/
5569
5570
5571
5572 /**
5573  * @brief API for sending configuration confirm from Scheduler to DU APP
5574  *
5575  * @details
5576  *
5577  *     Function: schSendCfgCfm 
5578  *
5579  *     This API is invoked to send configuration confirm from Scheduler to DU
5580  *     APP.
5581  *
5582  *  @param[in]  Pst           pst 
5583  *  @param[in]  RgrCfgTransId transId
5584  *  @param[in]  uint8_t            status
5585  *  @return  S16
5586  *      -# ROK
5587  *      -# RFAILED
5588  **/
5589 S16 schSendCfgCfm(Region reg,Pool pool,RgrCfgTransId transId,uint8_t status)
5590 {
5591    Pst cfmPst;
5592
5593    memset((&cfmPst), 0, sizeof(Pst));
5594
5595    cfmPst.srcEnt    = (Ent)ENTDUAPP;
5596    cfmPst.srcInst   = (Inst) 0;
5597    cfmPst.srcProcId = SFndProcId();
5598    cfmPst.dstEnt    = (Ent)ENTMAC;
5599    cfmPst.dstInst   = (Inst) 0;
5600    cfmPst.dstProcId = SFndProcId();
5601    cfmPst.selector  = ODU_SELECTOR_LC;
5602    cfmPst.region    = reg;
5603    cfmPst.pool      = pool;
5604
5605    if(RgUiRgrCfgCfm(&cfmPst,transId, status) != ROK)
5606    {
5607       DU_LOG("\nERROR  -->  SCH : schSendCfgCfm: RgUiRgrCfgCfm Failed ");
5608       return RFAILED;
5609    }
5610    return ROK;
5611 }  /* schSendCfgCfm*/
5612 #ifdef RGR_RRM_TICK
5613 /**
5614  * @brief API for sending TTI indication from Scheduler to RRM.
5615  *
5616  * @details
5617  *
5618  *     Function: rgSCHUtlRgrTtiInd
5619  *
5620  *     This API is invoked to send TTI indication from Scheduler instance to RRM.
5621  *     This API fills in Pst structure and RgrTtiIndInfo
5622  *
5623  *  @param[in]  cell                   RgSchCellCb
5624  *  @param[in]  CmLteTimingInfo        status
5625  *  @return  S16
5626  *      -# ROK
5627  *      -# RFAILED
5628  **/
5629 S16 rgSCHUtlRgrTtiInd(RgSchCellCb *cell,RgrTtiIndInfo *rgrTti)
5630 {
5631    S16           ret = ROK;
5632    RgSchUpSapCb  *rgrSap;                    /*!< RGR SAP Control Block */
5633 #ifdef L2_L3_SPLIT
5634    Bool g_usettitmr;
5635    Void mtTmrHdlrPublic(void);
5636 #endif
5637
5638    rgrSap = cell->rgrSap;
5639    if (rgrSap->sapSta.sapState != LRG_BND)
5640    {
5641       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrTtiInd() Upper SAP not bound (%d) ",
5642                rgrSap->sapSta.sapState);
5643       return RFAILED;
5644    }
5645    RgUiRgrTtiInd(&(cell->rgrSap->sapCfg.sapPst),
5646          cell->rgrSap->sapCfg.suId, rgrTti);
5647 #ifdef L2_L3_SPLIT
5648    {
5649       g_usettitmr = TRUE;
5650       mtTmrHdlrPublic();
5651    }
5652 #endif
5653    return (ret);
5654 }  /* rgSCHUtlRgrTtiInd*/
5655 #endif
5656 /** @brief This function is called by rgMacSchSfRecpInd. This function invokes the
5657  * scheduler with the information of the received Data and any Control Elements
5658  * if present.
5659  *
5660  * @details
5661  *
5662  *     Function:
5663  *
5664  *         Processing steps:
5665  *         - Retrieves the RaCb with the rnti provided, if it doesnt exist
5666  *         return failure.
5667  *         - If UE exists then update the Schduler with any MAC CEs if present.
5668  *         - Invoke RAM module to do Msg3 related processing rgSCHRamProcMsg3
5669  *
5670  * @param  [in] RgSchCellCb   *cellCb
5671  * @param  [in] RgSchUeCb     *ueCb
5672  * @param  [in] CmLteRnti     rnti
5673  * @param  [in] RgMacPdu   *pdu
5674  * @param  [in] RgSchErrInfo  *err
5675  * @param
5676  *  @return  S16
5677  *      -# ROK
5678  *      -# RFAILED
5679  */
5680 S16 rgSCHUtlProcMsg3
5681 (
5682 RgInfSfDatInd    *subfrmInfo,
5683 RgSchCellCb      *cellCb,
5684 RgSchUeCb        *ueCb,
5685 CmLteRnti        rnti,
5686 RgInfUeDatInd    *pdu,
5687 RgSchErrInfo     *err
5688 )
5689 {
5690    S16               ret;
5691    RgSchRaCb         *raCb;
5692
5693    /* must have an raCb for this case */
5694    raCb = rgSCHDbmGetRaCb (cellCb, rnti);
5695    if (raCb == NULLP)
5696    {
5697       DU_LOG("\nERROR  -->  SCH : RNTI:%d Received MSG3, unable to "
5698          "find raCb",rnti);
5699       return RFAILED;
5700    }
5701
5702    /* ccpu00130982: Processing CRNTI MAC CE before Short BSR, if any, such that 
5703     * effBsr of current case only will be considered in scheduling of ContResLst*/
5704    ret = rgSCHRamProcMsg3 (cellCb, ueCb, raCb, pdu, err);
5705    if (ret != ROK)
5706    {
5707       DU_LOG("\nERROR  -->  SCH : Processing failed in the RAM "
5708          "RNTI:%d ",rnti);
5709       return (ret);
5710    }
5711    /* if ueCb is present */
5712    if (ueCb != NULLP)
5713    {
5714       rgSCHUtlUpdSch (subfrmInfo, cellCb, ueCb, pdu, err);
5715    }
5716
5717    return ROK;
5718 }
5719 #ifdef LTEMAC_SPS
5720 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
5721  * scheduler with the information of the received Data.
5722  *
5723  * @details
5724  *
5725  *     Function: rgSCHUtlSpsRelInd
5726  *
5727  *         Processing steps:
5728  *         TODO
5729  *
5730  * @param  [in] RgSchCellCb        *cellCb
5731  * @param  [in] RgSchUeCb          *ueCb
5732  * @param  [in] Bool               *isExplRel
5733  * @param
5734  *  @return  S16
5735  *      -# ROK
5736  *      -# RFAILED
5737  */
5738 S16 rgSCHUtlSpsRelInd(RgSchCellCb *cellCb,RgSchUeCb *ueCb,Bool isExplRel)
5739 {
5740    cellCb->sc.apis->rgSCHUlSpsRelInd(cellCb, ueCb, isExplRel);
5741    return ROK;
5742 } /* end of rgSCHUtlSpsRelInd */
5743
5744
5745 /** @brief This function is called by RgMacSchSpsRelInd. This function invokes the
5746  * scheduler with the information of the received Data.
5747  *
5748  * @details
5749  *
5750  *     Function: rgSCHUtlSpsActInd
5751  *
5752  *         Processing steps:
5753  *         TODO
5754  *
5755  * @param  [in] RgSchCellCb        *cellCb
5756  * @param  [in] RgSchUeCb          *ueCb
5757  * @param  [in] uint16_t                spsSduSize
5758  * @param
5759  *  @return  S16
5760  *      -# ROK
5761  *      -# RFAILED
5762  */
5763 S16 rgSCHUtlSpsActInd(RgSchCellCb *cellCb,RgSchUeCb *ueCb,uint16_t spsSduSize)
5764 {
5765    cellCb->sc.apis->rgSCHUlSpsActInd(cellCb, ueCb, spsSduSize);
5766    return ROK;
5767 } /* end of rgSCHUtlSpsActInd */
5768
5769
5770 #endif /* LTEMAC_SPS */
5771
5772 #ifdef RG_PHASE_2
5773 /**
5774  * @brief This API is invoked to send uplink group power control request to PHY.
5775  *
5776  * @details
5777  *
5778  *     Function : rgSCHUtlTfuGrpPwrCntrlReq
5779  *
5780  *      This API is invoked to send uplink group power control request to PHY.
5781  *      It fills in the Pst structure, spId value and invokes group power
5782  *      control request primitive at TFU.
5783  *
5784  *  @param[in]  TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq
5785  *  @return  S16
5786  *      -# ROK
5787  *      -# RFAILED
5788  **/
5789 S16 rgSCHUtlTfuGrpPwrCntrlReq(Inst inst,S16 sapId,TfuGrpPwrCntrlReqInfo *grpPwrCntrlReq)
5790 {
5791    S16             ret;
5792    RgSchLowSapCb  *tfuSap;
5793    Pst             pst;
5794
5795    /* Get the lower SAP control block from the layer control block. */
5796    tfuSap = &(rgSchCb[inst].tfuSap[sapId]);
5797    if (tfuSap->sapSta.sapState != LRG_BND)
5798    {
5799       DU_LOG("\nERROR  -->  SCH : rgSCHUtlTfuGrpPwrCntrlReq() Lower SAP not bound (%d) ",tfuSap->sapSta.sapState);
5800       return RFAILED;
5801    }
5802    memcpy (&pst, &(tfuSap->sapCfg.sapPst), sizeof(Pst));
5803    if((ret = RgLiTfuGrpPwrCntrlReq (&pst, tfuSap->sapCfg.spId, grpPwrCntrlReq)) != ROK)
5804    {
5805        DU_LOG("\nERROR  -->  SCH : rgSCHUtlTfuGrpPwrCntrlReq() Call to RgLiTfuGrpPwrCntrlReq() failed");
5806    }
5807    return (ret);
5808 }  /* rgSCHUtlTfuGrpPwrCntrlReq */
5809 #endif
5810
5811 /* FOR ACK NACK REP */
5812
5813 /**
5814  * @brief This API is invoked to tell the DL Scheduler to add the UE back into
5815  * its scheduling queues.
5816  *
5817  * @details
5818  *
5819  *     Function : rgSCHUtlDlActvtUe
5820  *
5821  *      This API is invoked from Measurement gap moduled.
5822  *
5823  *  @param[in]  RgSchCellCb    *cell
5824  *  @param[in]  RgSchUeCb        *ueCb
5825  *
5826  *  @return  S16
5827  *      -# ROK
5828  *      -# RFAILED
5829  **/
5830 S16 rgSCHUtlDlActvtUe(RgSchCellCb *cell,RgSchUeCb   *ue)
5831 {
5832    cell->sc.apis->rgSCHActvtDlUe(cell, ue);
5833    return ROK;
5834 }
5835
5836 /**
5837  * @brief This API is invoked to tell the UL Scheduler to add the UE back into
5838  * its scheduling queues.
5839  *
5840  * @details
5841  *
5842  *     Function : rgSCHUtlUlActvtUe
5843  *
5844  *      This API is invoked from Measurement gap moduled.
5845  *
5846  *  @param[in]  RgSchCellCb    *cell
5847  *  @param[in]  RgSchUeCb        *ueCb
5848  *
5849  *  @return  S16
5850  *      -# ROK
5851  *      -# RFAILED
5852  **/
5853 S16 rgSCHUtlUlActvtUe(RgSchCellCb *cell,RgSchUeCb *ue)
5854 {
5855    cell->sc.apis->rgSCHActvtUlUe(cell, ue);
5856    return ROK;
5857 }
5858
5859  /** @brief This function Validates the SAP information received along with the
5860   * primitive from the lower layer.
5861   *
5862   * Function: rgSCHUtlValidateTfuSap
5863   *
5864   *                      Validates SAP information.
5865   * @param  suId The SAP Id
5866   * @return
5867   *   -# ROK
5868   *   -# RFAILED
5869   */
5870 S16 rgSCHUtlValidateTfuSap(Inst  inst,SuId  suId)
5871 {
5872    RgSchLowSapCb  *tfuSap;
5873
5874    if(suId >= rgSchCb[inst].numSaps)
5875    {
5876       DU_LOG("\nERROR  -->  SCH : Incorrect SuId");
5877       return RFAILED;
5878    }
5879    tfuSap = &(rgSchCb[inst].tfuSap[suId]);
5880
5881    /* First lets check the suId */
5882    if( suId != tfuSap->sapCfg.suId)
5883    {
5884       DU_LOG("\nERROR  -->  SCH : Incorrect SuId. Configured (%d) Recieved (%d)",
5885             tfuSap->sapCfg.suId, suId);
5886       return RFAILED;
5887    }
5888    if (tfuSap->sapSta.sapState != LRG_BND)
5889    {
5890       DU_LOG("\nERROR  -->  SCH : Lower SAP not enabled SuId (%d)",
5891             tfuSap->sapCfg.suId);
5892       return RFAILED;
5893    }
5894    return ROK;
5895 } /* end of rgSCHUtlValidateTfuSap */
5896
5897 /*
5898 *
5899 *       Fun:   rgSCHUtlAllocEventMem
5900 *
5901 *       Desc:  This function allocates event memory
5902 *
5903 *       Ret:   ROK      - on success
5904 *              RFAILED  - on failure
5905 *
5906 *       Notes: None
5907 *
5908 *       File:  rg_utl.c
5909 *
5910 */
5911 S16 rgSCHUtlAllocEventMem(Inst inst,Ptr *memPtr,Size memSize)
5912 {
5913    Mem  sMem;
5914    volatile uint32_t  startTime=0;
5915
5916
5917    sMem.region = rgSchCb[inst].rgSchInit.region;
5918    sMem.pool = rgSchCb[inst].rgSchInit.pool;
5919
5920 #if (ERRCLASS & ERRCLS_DEBUG)
5921    if (memSize<= 0)
5922    {
5923       DU_LOG("\nERROR  -->  SCH : rgAllocEventMem(): memSize invalid\n");
5924       return  (RFAILED);
5925    }
5926 #endif /* ERRCLASS & ERRCLS_DEBUG */
5927    /*starting Task*/
5928    SStartTask(&startTime, PID_SCHUTL_CMALLCEVT);
5929
5930 #ifdef MS_MBUF_CORRUPTION /* Should be enabled when debugging mbuf corruption */
5931    MS_BUF_ADD_ALLOC_CALLER();
5932 #endif /* */
5933 #ifdef TFU_ALLOC_EVENT_NO_INIT
5934    if(ROK != cmAllocEvntNoInit(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
5935 #else
5936    if(ROK != cmAllocEvnt(memSize, TFU_MAX_MEMBLK_SIZE, &sMem, memPtr))
5937 #endif /* */
5938    {
5939       DU_LOG("\nERROR  -->  SCH : cmAllocEvnt Failed.");
5940       return RFAILED;
5941    }
5942    /*stoping Task*/
5943    SStopTask(startTime, PID_SCHUTL_CMALLCEVT);
5944    return ROK;
5945 } /* end of rgSCHUtlAllocEventMem*/
5946
5947 /*
5948 *
5949 *       Fun:   rgGetEventMem
5950 *
5951 *       Desc:  This function allocates event memory
5952 *
5953 *       Ret:   ROK      - on success
5954 *              RFAILED  - on failure
5955 *
5956 *       Notes: None
5957 *
5958 *       File:  rg_utl.c
5959 *
5960 */
5961 S16 rgSCHUtlGetEventMem(Ptr *ptr,Size len,Ptr memCp)
5962 {
5963    S16   ret;
5964
5965 #ifdef TFU_ALLOC_EVENT_NO_INIT
5966    ret = cmGetMemNoInit(memCp, len, (Ptr *)ptr);
5967 #else
5968    ret = cmGetMem(memCp, len, (Ptr *)ptr);
5969 #endif
5970    return (ret);
5971 } /* end of rgSCHUtlGetEventMem*/
5972
5973 #ifdef LTE_TDD
5974
5975
5976 /**
5977  * @brief Handler to allocate memory for ACK/NACk feedback information
5978  *
5979  * @details
5980  *
5981  *     Function : rgSCHUtlAllocUeANFdbkInfo
5982  *
5983  *   It allocates memory for the UE related ACK NACK information.
5984  *
5985  *  @param[in]  RgSchUeCb           *ue
5986  *  @return     S16
5987  **/
5988 S16 rgSCHUtlAllocUeANFdbkInfo(RgSchUeCb *ue,uint8_t servCellIdx)
5989 {
5990    uint8_t idx;
5991
5992    if (rgSCHUtlAllocSBuf(ue->cell->instIdx,
5993                (Data **) &(ue->cellInfo[servCellIdx]->anInfo), sizeof(RgSchTddANInfo) * \
5994    ue->cell->ackNackFdbkArrSize) != ROK)
5995    {
5996       return RFAILED;
5997    }
5998
5999    for(idx=0; idx < ue->cell->ackNackFdbkArrSize; idx++)
6000    {
6001       rgSCHUtlInitUeANFdbkInfo(&ue->cellInfo[servCellIdx]->anInfo[idx]);
6002    }
6003
6004    /* Set it to the first index */
6005    ue->cellInfo[servCellIdx]->nextFreeANIdx = 0;
6006    return ROK;
6007 } /* rgSCHUtlAllocUeANFdbkInfo */
6008
6009 /**
6010  * @brief Handler to release memory for ACK/NACk feedback information
6011  *
6012  * @details
6013  *
6014  *     Function : rgSCHUtlDelUeANFdbkInfo
6015  *
6016  *   It releases memory for the UE related ACK NACK information.
6017  *
6018  *  @param[in]  RgSchUeCb           *ue
6019  *  @return     Void
6020  **/
6021 Void rgSCHUtlDelUeANFdbkInfo(RgSchUeCb *ue,uint8_t servCellIdx)
6022 {
6023
6024    /* ccpu00117052 - MOD - Passing double pointer
6025    for proper NULLP assignment*/
6026    rgSCHUtlFreeSBuf(ue->cell->instIdx,
6027          (Data **)(&( ue->cellInfo[servCellIdx]->anInfo)), sizeof(RgSchTddANInfo) * \
6028                         ue->cell->ackNackFdbkArrSize);
6029
6030    return;
6031 } /* rgSCHUtlDelUeANFdbkInfo */
6032
6033 /**
6034  * @brief Handler to initialise UE ACK/NACk feedback information
6035  *
6036  * @details
6037  *
6038  *     Function : rgSCHUtlInitUeANFdbkInfo
6039  *
6040  *   It initialises UE related ACK NACK information.
6041  *
6042  *  @param[in]  RgSchTddANInfo   *anFdInfo
6043  *  @return     S16
6044  **/
6045 S16 rgSCHUtlInitUeANFdbkInfo(RgSchTddANInfo *anFdInfo)
6046 {
6047
6048    anFdInfo->sfn = RGSCH_MAX_SFN+1; /* defensively setting invalid sfn */
6049    anFdInfo->slot = 0;
6050    anFdInfo->ulDai = RG_SCH_INVALID_DAI_VAL;
6051    anFdInfo->dlDai = RG_SCH_INVALID_DAI_VAL;
6052    anFdInfo->latestMIdx = RG_SCH_INVALID_M_VAL;
6053
6054    return ROK;
6055 } /* rgSCHUtlInitUeANFdbkInfo */
6056
6057 /**
6058  * @brief Handler to get UE related ACK NACK feedback information
6059  *
6060  * @details
6061  *
6062  *     Function : rgSCHUtlGetUeANFdbkInfo
6063  *
6064  *   It gets the UE related ACK NACK information based on
6065  *   SFN and slot number.
6066  *
6067  *  @param[in]  RgSchUeCb        *ueCb
6068  *  @param[in]  CmLteTimingInfo  *time
6069  *  @return     RgSchTddANInfo*
6070  **/
6071 RgSchTddANInfo* rgSCHUtlGetUeANFdbkInfo(RgSchUeCb *ueCb,CmLteTimingInfo *timeInfo,uint8_t servCellIdx)
6072 {
6073    uint8_t idx;
6074
6075    for (idx = 0; idx < ueCb->cell->ackNackFdbkArrSize; ++idx)
6076    {
6077        if( (timeInfo->sfn == ueCb->cellInfo[servCellIdx]->anInfo[idx].sfn) &&
6078                (timeInfo->slot == ueCb->cellInfo[servCellIdx]->anInfo[idx].slot))
6079        {
6080             return (&ueCb->cellInfo[servCellIdx]->anInfo[idx]);
6081        }
6082    }
6083
6084    return (NULLP);
6085 } /* rgSCHUtlGetUeANFdbkInfo */
6086
6087 /**
6088  * @brief To get downlink slot index
6089  *
6090  * @details
6091  *
6092  *     Function: rgSCHUtlGetDlSfIdx
6093  *     Purpose:  Gets downlink slot index based on SFN and slot no
6094  *
6095  *  @param[in]  CmLteTimingInfo  *timeInfo
6096  *  @param[in]  RgSchCellCb         *cell
6097  *  @return uint8_t
6098  *
6099  **/
6100 uint8_t  rgSCHUtlGetDlSfIdx(RgSchCellCb  *cell,CmLteTimingInfo *timeInfo)
6101 {
6102    uint16_t       idx = 0;
6103
6104    idx = RGSCH_NUM_SUB_FRAMES - \
6105          rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
6106    idx = ((idx * timeInfo->sfn) + \
6107          rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][timeInfo->slot]) - 1;
6108    idx = idx % cell->numDlSubfrms;
6109
6110    return ((uint8_t)idx);
6111 }
6112
6113 /**
6114  * @brief To get the next downlink slot
6115  *
6116  * @details
6117  *
6118  *     Function: rgSCHUtlGetNxtDlSfInfo
6119  *     Purpose:  Gets next downlink slot based on current DL slot
6120  *
6121  *  @param[in]  CmLteTimingInfo  curDlTime
6122  *  @param[in]  RgSchCellCb      *cell
6123  *  @param[in]  RgSchDlSf        *dlSf
6124  *  @param[in]  RgSchDlSf        **nxtDlsf
6125  *  @param[in]  CmLteTimingInfo  *nxtDlTime
6126  *  @return uint8_t
6127  *
6128  **/
6129 Void rgSCHUtlGetNxtDlSfInfo(CmLteTimingInfo curDlTime,RgSchCellCb  *cell,RgSchDlSf *dlSf,RgSchDlSf **nxtDlsf,CmLteTimingInfo *nxtDlTime)
6130 {
6131    uint16_t  idx = curDlTime.slot;
6132    uint8_t   count = 0;
6133
6134    while(TRUE)
6135    {
6136       do
6137       {
6138          idx = (idx + 1) % RGSCH_NUM_SUB_FRAMES;
6139          count++;
6140       }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
6141                                        != RG_SCH_TDD_DL_slot);
6142       RG_SCH_ADD_TO_CRNT_TIME(curDlTime, (*nxtDlTime), count);
6143       *nxtDlsf = rgSCHUtlSubFrmGet(cell, *nxtDlTime);
6144       if(dlSf->dlFdbkInfo.slot != (*nxtDlsf)->dlFdbkInfo.slot)
6145       {
6146          break;
6147       }
6148    }
6149    return;
6150 }
6151
6152 /**
6153  * @brief To get the previous downlink slot
6154  *
6155  * @details
6156  *
6157  *     Function: rgSCHUtlGetPrevDlSfInfo
6158  *     Purpose:  Gets previous downlink slot based on current DL slot
6159  *
6160  *  @param[in]  RgSchCellCb      *cell
6161  *  @param[in]  CmLteTimingInfo  curDlTime
6162  *  @param[in]  CmLteTimingInfo  *prevDlTime
6163  *  @param[in]  uint8_t               *numSubfrm
6164  *  @return uint8_t
6165  *
6166  **/
6167 Void rgSCHUtlGetPrevDlSfInfo(RgSchCellCb *cell,CmLteTimingInfo curDlTime,CmLteTimingInfo *prevDlTime,uint8_t *numSubfrm)
6168 {
6169    S16 idx = curDlTime.slot;
6170    uint8_t  count = 0;
6171
6172    do
6173    {
6174       idx--;
6175       if(idx < 0)
6176       {
6177          idx = RGSCH_NUM_SUB_FRAMES-1;
6178       }
6179       count++;
6180    }while(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][idx]
6181          !=  RG_SCH_TDD_DL_slot);
6182    *numSubfrm = count;
6183    RGSCHDECRFRMCRNTTIME(curDlTime, (*prevDlTime), count);
6184    return;
6185 }
6186
6187 #endif
6188 /* Added Holes Management functions for Adaptive Re transmission */
6189 /******* </AllocHolesMemMgmnt>: START *****/
6190 /***********************************************************
6191  *
6192  *     Func : rgSCHUtlUlSfInit
6193  *
6194  *     Desc : UL slot init.
6195  *
6196  *     Ret  : S16
6197  *
6198  *     Notes:
6199  *
6200  *     File :
6201  *
6202  **********************************************************/
6203 S16 rgSCHUtlUlSfInit(RgSchCellCb  *cell,RgSchUlSf *sf,uint8_t idx,uint8_t maxUePerSf)
6204 {
6205    S16             ret=ROK;
6206
6207    sf->idx = idx;
6208 #ifdef RG_5GTF
6209    uint8_t index;
6210 #endif
6211
6212 #ifdef LTE_TDD   
6213    if(cell->ulDlCfgIdx == 0)
6214    {
6215       /* Store the Uplink slot number corresponding to the idx */
6216       sf->ulSfIdx = rgSchTddCfg0UlSfTbl[idx%6]; 
6217    }
6218 #endif   
6219    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->allocDb,
6220                            sizeof(RgSchUlAllocDb));
6221    if (ret != ROK)
6222    {
6223       return (ret);
6224    }
6225    ret = rgSCHUtlUlAllocDbInit(cell, sf->allocDb, maxUePerSf);
6226    if (ret != ROK)
6227    {
6228       /* ccpu00117052 - MOD - Passing double pointer
6229       for proper NULLP assignment*/
6230       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
6231                        sizeof(RgSchUlAllocDb));
6232       return (ret);
6233    }
6234    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&sf->holeDb,
6235          sizeof(RgSchUlHoleDb));
6236    if (ret != ROK)
6237    {
6238       rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
6239       /* ccpu00117052 - MOD - Passing double pointer
6240       for proper NULLP assignment*/
6241       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
6242                        sizeof(RgSchUlAllocDb));
6243       return (ret);
6244    }
6245    /* Initialize the hole with CFI 1 Pusch Bw Info */ 
6246    ret = rgSCHUtlUlHoleDbInit(cell, sf->holeDb, (uint8_t)(maxUePerSf + 2), \
6247                               0, cell->dynCfiCb.bwInfo[1].numSb);
6248
6249    if (ret != ROK)
6250    {
6251       rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
6252       /* ccpu00117052 - MOD - Passing double pointer
6253       for proper NULLP assignment*/
6254       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
6255                        sizeof(RgSchUlAllocDb));
6256       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
6257                        sizeof(RgSchUlHoleDb));
6258       return (ret);
6259    }
6260    cmLListInit(&sf->reTxLst);
6261
6262    /* Fix ccpu00120610*/
6263    sf->allocCountRef = &sf->allocDb->count;
6264
6265    /* initialize UL available subbands for current sub-frame */
6266    sf->availSubbands = cell->dynCfiCb.bwInfo[1].numSb;
6267 #ifdef RG_5GTF
6268    sf->numGrpPerTti = cell->cell5gtfCb.ueGrpPerTti;
6269    sf->numUePerGrp = cell->cell5gtfCb.uePerGrpPerTti;
6270    for(index = 0; index < MAX_5GTF_BEAMS; index++)
6271    {
6272       sf->sfBeamInfo[index].totVrbgAllocated = 0;
6273       sf->sfBeamInfo[index].totVrbgRequired = 0;
6274       sf->sfBeamInfo[index].vrbgStart = 0;
6275    }
6276 #endif
6277
6278    return (ret);
6279 }
6280
6281
6282 /***********************************************************
6283  *
6284  *     Func : rgSCHUtlUlSfDeinit
6285  *
6286  *     Desc : Deinitialises a slot
6287  *
6288  *     Ret  : Void
6289  *
6290  *     Notes:
6291  *
6292  *     File :
6293  *
6294  **********************************************************/
6295 Void rgSCHUtlUlSfDeinit(RgSchCellCb  *cell,RgSchUlSf  *sf)
6296 {
6297    if (sf->allocDb)
6298    {
6299       rgSCHUtlUlAllocDbDeinit(cell, sf->allocDb);
6300       /* ccpu00117052 - MOD - Passing double pointer
6301       for proper NULLP assignment*/
6302       /* ccpu00117052 - MOD - Passing double pointer
6303       for proper NULLP assignment*/
6304       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->allocDb)),
6305                        sizeof(RgSchUlAllocDb));
6306    }
6307    if (sf->holeDb)
6308    {
6309       rgSCHUtlUlHoleDbDeinit(cell, sf->holeDb);
6310       /* ccpu00117052 - MOD - Passing double pointer
6311       for proper NULLP assignment*/
6312       rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(sf->holeDb)),
6313                        sizeof(RgSchUlHoleDb));
6314    }
6315    return;
6316 }
6317
6318 /***********************************************************
6319  *
6320  *     Func : rgSCHUtlUlAllocDbInit
6321  *
6322  *     Desc : Initialise allocation DB
6323  *
6324  *     Ret  : S16 (ROK/RFAILED)
6325  *
6326  *     Notes:
6327  *
6328  *     File :
6329  *
6330  **********************************************************/
6331 static S16 rgSCHUtlUlAllocDbInit(RgSchCellCb *cell,RgSchUlAllocDb *allocDb,uint8_t maxAllocs)
6332 {
6333    S16 ret = rgSCHUtlUlAllocMemInit(cell, &allocDb->mem, maxAllocs);
6334    if (ret != ROK)
6335    {
6336       return (ret);
6337    }
6338    allocDb->count = 0;
6339    allocDb->first = NULLP;
6340    return ROK;
6341 }
6342
6343 /***********************************************************
6344  *
6345  *     Func : rgSCHUtlUlAllocDbDeinit
6346  *
6347  *     Desc : Deinitialises allocation DB
6348  *            sent to UE, for a UE with accumulation disabled
6349  *
6350  *     Ret  : Void
6351  *
6352  *     Notes:
6353  *
6354  *     File :
6355  *
6356  **********************************************************/
6357 static Void rgSCHUtlUlAllocDbDeinit(RgSchCellCb *cell,RgSchUlAllocDb *allocDb)
6358 {
6359    rgSCHUtlUlAllocMemDeinit(cell, &allocDb->mem);
6360    allocDb->count = 0;
6361    allocDb->first = NULLP;
6362    return;
6363 }
6364
6365 /***********************************************************
6366  *
6367  *     Func : rgSCHUtlUlHoleDbInit
6368  *
6369  *     Desc : Initialise hole DB
6370  *
6371  *     Ret  : S16 (ROK/RFAILED)
6372  *
6373  *     Notes:
6374  *
6375  *     File :
6376  *
6377  **********************************************************/
6378 static S16 rgSCHUtlUlHoleDbInit(RgSchCellCb *cell,RgSchUlHoleDb *holeDb,uint8_t maxHoles,uint8_t start,uint8_t num)
6379 {
6380    S16 ret;
6381    RgSchUlHole *hole = NULLP;
6382
6383    ret = rgSCHUtlUlHoleMemInit(cell, &holeDb->mem, maxHoles, &hole);
6384    if (ret != ROK)
6385    {
6386       return (ret);
6387    }
6388    holeDb->count = 1;
6389    holeDb->first = hole;
6390    hole->start = start;
6391    hole->num = num;
6392    hole->prv = hole->nxt = NULLP;
6393    return ROK;
6394 }
6395
6396 /***********************************************************
6397  *
6398  *     Func : rgSCHUtlUlHoleDbDeinit
6399  *
6400  *     Desc : Deinitialises hole DB
6401  *
6402  *     Ret  : Void
6403  *
6404  *     Notes:
6405  *
6406  *     File :
6407  *
6408  **********************************************************/
6409 static Void rgSCHUtlUlHoleDbDeinit(RgSchCellCb   *cell,RgSchUlHoleDb *holeDb)
6410 {
6411    rgSCHUtlUlHoleMemDeinit(cell, &holeDb->mem);
6412    holeDb->count = 0;
6413    holeDb->first = NULLP;
6414    return;
6415 }
6416
6417
6418 /***********************************************************
6419  *
6420  *     Func : rgSCHUtlUlAllocGetHole
6421  *
6422  *     Desc : Get allocation from hole
6423  *
6424  *     Ret  : RgSchUlAlloc *
6425  *
6426  *     Notes:
6427  *
6428  *     File :
6429  *
6430  **********************************************************/
6431 RgSchUlAlloc *rgSCHUtlUlAllocGetHole(RgSchUlSf *sf,uint8_t numSb,RgSchUlHole *hole)
6432 {
6433    if (numSb < hole->num)
6434    {
6435       return (rgSCHUtlUlAllocGetPartHole(sf, numSb, hole));
6436    }
6437    else
6438    {
6439       return (rgSCHUtlUlAllocGetCompHole(sf, hole));
6440    }
6441 }
6442
6443
6444 /***********************************************************
6445  *
6446  *     Func : rgSCHUtlUlAllocGetCompHole
6447  *
6448  *     Desc : Get an allocation corresponding to an entire hole
6449  *
6450  *     Ret  : RgSchUlAlloc *
6451  *
6452  *     Notes:
6453  *
6454  *     File :
6455  *
6456  **********************************************************/
6457 RgSchUlAlloc *rgSCHUtlUlAllocGetCompHole(RgSchUlSf   *sf,RgSchUlHole *hole)
6458 {
6459    RgSchUlAlloc *alloc;
6460       /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
6461    /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
6462     * updated, causing another check for prv */
6463    RgSchUlAlloc *prv = hole->prvAlloc;
6464    RgSchUlAlloc *nxt = hole->nxtAlloc;
6465
6466    if (prv)
6467    {
6468       if (hole->start == prv->nxtHole->start)
6469       {
6470          prv->nxtHole = NULLP;
6471       }
6472       alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
6473    }
6474    else
6475    {
6476       alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
6477    }
6478
6479    RGSCH_NULL_CHECK( 0, alloc);
6480    alloc->prvHole = NULLP;
6481    alloc->nxtHole = NULLP;
6482
6483    alloc->sbStart = hole->start;
6484    alloc->numSb = hole->num;
6485
6486    if (nxt)
6487    {
6488       nxt->prvHole = NULLP;
6489    }
6490
6491    rgSCHUtlUlHoleRls(sf->holeDb, hole);
6492
6493    /* UL_ALLOC_CHANGES*/
6494    alloc->allocDbRef = (void*)sf->allocDb;
6495    alloc->holeDbRef  = (void*)sf->holeDb;
6496    return (alloc);
6497 }
6498
6499 /***********************************************************
6500  *
6501  *     Func : rgSCHUtlUlAllocGetPartHole
6502  *
6503  *     Desc : Get an allocation corresponding to a part of a hole.
6504  *            The initial 'numSb' part of the hole shall be taken
6505  *            away for this alloc.
6506  *
6507  *     Ret  : RgSchUlAlloc *
6508  *
6509  *     Notes:
6510  *
6511  *     File :
6512  *
6513  **********************************************************/
6514 RgSchUlAlloc *rgSCHUtlUlAllocGetPartHole(RgSchUlSf *sf,uint8_t numSb,RgSchUlHole *hole)
6515 {
6516    RgSchUlAlloc *alloc;
6517       /* alloc = rgSCHUtlUlAllocGetAndIns(sf->allocDb, hole->prvAlloc, hole->nxtAlloc); */
6518    /* Calling rgSchCmnUlAllocGetAndIns is ok, but prv alloc needs to have nxtHole
6519     * updated, causing another check for prv */
6520    RgSchUlAlloc *prv = hole->prvAlloc;
6521
6522    if (prv)
6523    {
6524       if (hole->start == prv->nxtHole->start)
6525       {
6526          prv->nxtHole = NULLP;
6527       }
6528       alloc = rgSCHUtlUlAllocGetAdjNxt(sf->allocDb, prv);
6529    }
6530    else
6531    {
6532       alloc = rgSCHUtlUlAllocGetFirst(sf->allocDb);
6533    }
6534
6535    RGSCH_NULL_CHECK( 0, alloc);
6536    alloc->prvHole = NULLP;
6537    alloc->nxtHole = hole;
6538    hole->prvAlloc = alloc;
6539
6540    alloc->sbStart = hole->start;
6541    alloc->numSb = numSb;
6542    hole->start += numSb;
6543    hole->num -= numSb;
6544
6545    rgSCHUtlUlHoleDecr(sf->holeDb, hole);
6546
6547    /* UL_ALLOC_CHANGES*/
6548    alloc->allocDbRef = (void*)sf->allocDb;
6549    alloc->holeDbRef  = (void*)sf->holeDb;
6550
6551    return (alloc);
6552 }
6553
6554 /***********************************************************
6555  *
6556  *     Func : rgSCHUtlUlAllocFirst
6557  *
6558  *     Desc : Get first alloc in slot
6559  *
6560  *     Ret  : RgSchUlAlloc *
6561  *
6562  *     Notes:
6563  *
6564  *     File :
6565  *
6566  **********************************************************/
6567 RgSchUlAlloc *rgSCHUtlUlAllocFirst(RgSchUlSf *sf)
6568 {
6569    return (sf->allocDb->first);
6570 }
6571
6572 /***********************************************************
6573  *
6574  *     Func : rgSCHUtlUlAllocNxt
6575  *
6576  *     Desc : Get next alloc
6577  *
6578  *     Ret  : RgSchUlAlloc *
6579  *
6580  *     Notes:
6581  *
6582  *     File :
6583  *
6584  **********************************************************/
6585 RgSchUlAlloc *rgSCHUtlUlAllocNxt(RgSchUlSf    *sf,RgSchUlAlloc *alloc)
6586 {
6587    UNUSED(sf);
6588    return (alloc->nxt);
6589 }
6590
6591 /***********************************************************
6592  *
6593  *     Func : rgSCHUtlUlAllocGetAdjNxt
6594  *
6595  *     Desc : Get alloc which is immediately after the passed one.
6596  *            1. Gets alloc from mem.
6597  *            2. Inserts alloc into list (between prv and
6598  *                prv->nxt, prv is not NULLP).
6599  *            3. Increments alloc count.
6600  *            Note 1: Holes are not dealt with here.
6601  *            Note 2: Assumes prv to be NULL.
6602  *
6603  *     Ret  : RgSchUlAlloc *
6604  *
6605  *     Notes:
6606  *
6607  *     File :
6608  *
6609  **********************************************************/
6610 RgSchUlAlloc *rgSCHUtlUlAllocGetAdjNxt(RgSchUlAllocDb *db,RgSchUlAlloc   *prv)
6611 {
6612    RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
6613    RgSchUlAlloc *nxt = prv->nxt;
6614
6615 #if (ERRCLASS & ERRCLS_DEBUG)
6616    if ( alloc == NULLP )
6617    {
6618        return  ( NULLP );
6619    }
6620 #endif
6621    alloc->prv = prv;
6622    alloc->nxt = nxt;
6623    prv->nxt = alloc;
6624    if (nxt)
6625    {
6626       nxt->prv = alloc;
6627    }
6628
6629    ++db->count;
6630
6631    return (alloc);
6632 }
6633
6634 /***********************************************************
6635  *
6636  *     Func : rgSCHUtlUlAllocGetFirst
6637  *
6638  *     Desc : Get alloc which is to be the first one in the alloc list
6639  *            1. Gets alloc from mem.
6640  *            2. Inserts alloc as first element into list.
6641  *            3. Increments alloc count.
6642  *            Note 1: Holes are not dealt with here.
6643  *            Note 2: prv to necessarily NULLP.
6644  *
6645  *     Ret  : RgSchUlAlloc *
6646  *
6647  *     Notes:
6648  *
6649  *     File :
6650  *
6651  **********************************************************/
6652 RgSchUlAlloc *rgSCHUtlUlAllocGetFirst(RgSchUlAllocDb *db)
6653 {
6654    RgSchUlAlloc *alloc = rgSCHUtlUlAllocMemGet(&db->mem);
6655    RgSchUlAlloc *nxt = db->first;
6656
6657 #if (ERRCLASS & ERRCLS_DEBUG)
6658     if ( alloc == NULLP )
6659     {
6660        return  ( NULLP );
6661     }
6662 #endif
6663
6664    alloc->prv = NULLP;
6665    alloc->nxt = nxt;
6666    if (nxt)
6667    {
6668       nxt->prv = alloc;
6669    }
6670    db->first = alloc;
6671
6672    ++db->count;
6673
6674    return (alloc);
6675 }
6676
6677 /* UL_ALLOC_ENHANCEMENT */
6678 /***********************************************************
6679  *
6680  *     Func : rgSCHUtlUlHoleAddAllocation
6681  *
6682  *     Desc : On freeing an alloc, add to hole
6683  *
6684  *     Ret  : Void
6685  *
6686  *     Notes:
6687  *
6688  *     File :
6689  *
6690  **********************************************************/
6691 Void rgSCHUtlUlHoleAddAllocation(RgSchUlAlloc *alloc)
6692 {
6693    /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
6694     * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
6695     * The excessive branching is meant to utilise the knowledge of whether prv
6696     * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
6697     * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
6698     * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
6699    RgSchUlHoleDb *db = alloc->holeDbRef;
6700    RgSchUlHole *prv = alloc->prvHole;
6701    RgSchUlHole *nxt = alloc->nxtHole;
6702
6703    if (prv)
6704    {
6705       if (nxt)
6706       {
6707          rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
6708       }
6709       else
6710          rgSCHUtlUlHoleExtndRight(db, prv, alloc);
6711    }
6712    else
6713    {
6714       if (nxt)
6715       {
6716          rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
6717       }
6718       else
6719          rgSCHUtlUlHoleNew(db, alloc);
6720    }
6721    return;
6722 }
6723
6724
6725 /***********************************************************
6726  *
6727  *     Func : rgSCHUtlUlAllocRelease
6728  *
6729  *     Desc : Releases an uplink allocation, only take alloc ptr
6730  *
6731  *     Ret  : Void
6732  *
6733  *     Notes:
6734  *
6735  *     File :
6736  *
6737  **********************************************************/
6738 Void rgSCHUtlUlAllocRelease(RgSchUlAlloc *alloc)
6739 {
6740    RgSchUlAllocDb *allocDb = alloc->allocDbRef;
6741    RgSchUlAlloc   *prv = alloc->prv;
6742    RgSchUlAlloc   *nxt = alloc->nxt;
6743
6744    alloc->ue = NULLP;
6745    alloc->raCb = NULLP;
6746    alloc->isAdaptive = FALSE;
6747
6748    if (prv)
6749    {
6750       prv->nxt = nxt;
6751       if (nxt)           /* general case: this allocation lies btw two */
6752       {
6753          nxt->prv = prv;
6754       }
6755    }
6756    else
6757    {
6758       allocDb->first = nxt;
6759       if (nxt)
6760       {
6761          nxt->prv = NULLP;
6762       }
6763    }
6764    --allocDb->count;
6765    rgSCHUtlUlHoleAddAllocation(alloc);
6766    rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
6767
6768    return;
6769 }
6770
6771
6772 /***********************************************************
6773  *
6774  *     Func : rgSCHUtlUlAllocRls
6775  *
6776  *     Desc : Releases an uplink allocation
6777  *
6778  *     Ret  : Void
6779  *
6780  *     Notes:
6781  *
6782  *     File :
6783  *
6784  **********************************************************/
6785 Void rgSCHUtlUlAllocRls(RgSchUlSf *sf,RgSchUlAlloc *alloc)
6786 {
6787    RgSchUlAllocDb *allocDb = sf->allocDb;
6788    RgSchUlAlloc   *prv = alloc->prv;
6789    RgSchUlAlloc   *nxt = alloc->nxt;
6790
6791    alloc->ue = NULLP;
6792    alloc->raCb = NULLP;
6793    alloc->isAdaptive = FALSE;
6794
6795    if(allocDb->count)
6796    {
6797       if (prv)
6798       {
6799          prv->nxt = nxt;
6800          if (nxt)           /* general case: this allocation lies btw two */
6801          {
6802             nxt->prv = prv;
6803          }
6804       }
6805       else
6806       {
6807          allocDb->first = nxt;
6808          if (nxt)
6809          {
6810             nxt->prv = NULLP;
6811          }
6812       }
6813       --allocDb->count;
6814       rgSCHUtlUlHoleAddAlloc(sf, alloc);
6815       rgSCHUtlUlAllocMemRls(&allocDb->mem, alloc);
6816    }
6817    else
6818    {
6819
6820       DU_LOG("\nERROR  -->  SCH :  allocDb->count is ZERO ");
6821    }
6822
6823    //DU_LOG("\nallocDb->count:%u\n",allocDb->count);
6824
6825    return;
6826 }
6827
6828 /***********************************************************
6829  *
6830  *     Func : rgSCHUtlUlHoleFirst
6831  *
6832  *     Desc : Get first (largest) hole
6833  *
6834  *     Ret  : RgSchUlHole *
6835  *
6836  *     Notes:
6837  *
6838  *     File :
6839  *
6840  **********************************************************/
6841 RgSchUlHole *rgSCHUtlUlHoleFirst(RgSchUlSf *sf)
6842 {
6843    return (sf->holeDb->first);
6844 }
6845
6846 /***********************************************************
6847  *
6848  *     Func : rgSCHUtlUlHoleNxt
6849  *
6850  *     Desc : Get next largest hole
6851  *
6852  *     Ret  : RgSchUlHole *
6853  *
6854  *     Notes:
6855  *
6856  *     File :
6857  *
6858  **********************************************************/
6859 RgSchUlHole *rgSCHUtlUlHoleNxt(RgSchUlSf   *sf,RgSchUlHole *hole)
6860 {
6861    UNUSED(sf);
6862    return (hole->nxt);
6863 }
6864
6865 /***********************************************************
6866  *
6867  *     Func : rgSCHUtlUlHoleAddAlloc
6868  *
6869  *     Desc : On freeing an alloc, add to hole
6870  *
6871  *     Ret  : Void
6872  *
6873  *     Notes:
6874  *
6875  *     File :
6876  *
6877  **********************************************************/
6878 Void rgSCHUtlUlHoleAddAlloc(RgSchUlSf *sf,RgSchUlAlloc *alloc)
6879 {
6880    /* Note: rgSchCmnUlHoleUpdAllocLnks function that is used should not exist as
6881     * one, if such excessive branching is done (AllocNone, AllocNoPrv etc).
6882     * The excessive branching is meant to utilise the knowledge of whether prv
6883     * and nxt allocs exist or not. Hence for each kind (none, noprv, nonxt,
6884     * both), there should be a rgSchCmnUlHoleUpdAllocLnks... function (such as
6885     * rgSchCmnUlHoleUpdAllocLnksNone/NoPrv etc. */
6886    RgSchUlHoleDb *db = sf->holeDb;
6887    RgSchUlHole *prv = alloc->prvHole;
6888    RgSchUlHole *nxt = alloc->nxtHole;
6889
6890    if (prv)
6891    {
6892       if (nxt)
6893       {
6894          rgSCHUtlUlHoleJoin(db, prv, nxt, alloc);
6895       }
6896       else
6897          rgSCHUtlUlHoleExtndRight(db, prv, alloc);
6898    }
6899    else
6900    {
6901       if (nxt)
6902       {
6903          rgSCHUtlUlHoleExtndLeft(db, nxt, alloc);
6904       }
6905       else
6906          rgSCHUtlUlHoleNew(db, alloc);
6907    }
6908
6909    /* increment the number of subbands getting freed to total available list */
6910    sf->availSubbands += alloc->numSb;
6911
6912    return;
6913 }
6914
6915 /***********************************************************
6916  *
6917  *     Func : rgSCHUtlUlHoleJoin
6918  *
6919  *     Desc : Join two holes (due to alloc being deleted)
6920  *
6921  *     Ret  : Void
6922  *
6923  *     Notes:
6924  *
6925  *     File :
6926  *
6927  **********************************************************/
6928 Void rgSCHUtlUlHoleJoin(RgSchUlHoleDb *db,RgSchUlHole *prv,RgSchUlHole *nxt,RgSchUlAlloc *alloc)
6929 {
6930    prv->num += alloc->numSb + nxt->num;
6931    rgSCHUtlUlHoleRls(db, nxt);
6932    rgSCHUtlUlHoleIncr(db, prv);
6933    rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
6934
6935    return;
6936 }
6937
6938 /***********************************************************
6939  *
6940  *     Func : rgSCHUtlUlHoleExtndRight
6941  *
6942  *     Desc : Extend hole due to alloc coming 'after' the hole
6943  *            being deleted
6944  *
6945  *     Ret  : Void
6946  *
6947  *     Notes:
6948  *
6949  *     File :
6950  *
6951  **********************************************************/
6952 Void rgSCHUtlUlHoleExtndRight(RgSchUlHoleDb *db,RgSchUlHole *prv,RgSchUlAlloc *alloc)
6953 {
6954    prv->num += alloc->numSb;
6955    rgSCHUtlUlHoleIncr(db, prv);
6956    rgSCHUtlUlHoleUpdAllocLnks(prv, alloc->prv, alloc->nxt);
6957    return;
6958 }
6959
6960 /***********************************************************
6961  *
6962  *     Func : rgSCHUtlUlHoleExtndLeft
6963  *
6964  *     Desc : Extend hole due to alloc coming 'before' the hole
6965  *            being deleted
6966  *
6967  *     Ret  : Void
6968  *
6969  *     Notes:
6970  *
6971  *     File :
6972  *
6973  **********************************************************/
6974 Void rgSCHUtlUlHoleExtndLeft(RgSchUlHoleDb *db,RgSchUlHole   *nxt,RgSchUlAlloc  *alloc)
6975 {
6976    nxt->num += alloc->numSb;
6977    nxt->start = alloc->sbStart;
6978    rgSCHUtlUlHoleIncr(db, nxt);
6979    rgSCHUtlUlHoleUpdAllocLnks(nxt, alloc->prv, alloc->nxt);
6980    return;
6981 }
6982
6983 /***********************************************************
6984  *
6985  *     Func : rgSCHUtlUlHoleNew
6986  *
6987  *     Desc : Create new hole due to alloc being deleted
6988  *
6989  *     Ret  : Void
6990  *
6991  *     Notes:
6992  *
6993  *     File :
6994  *
6995  **********************************************************/
6996 Void rgSCHUtlUlHoleNew(RgSchUlHoleDb *db,RgSchUlAlloc  *alloc)
6997 {
6998    RgSchUlHole *hole = rgSCHUtlUlHoleMemGet(&db->mem);
6999 #if (ERRCLASS & ERRCLS_DEBUG)
7000    if ( hole == NULLP )
7001    {
7002       return;
7003    }
7004 #endif
7005    hole->start = alloc->sbStart;
7006    hole->num = alloc->numSb;
7007    ++db->count;
7008    rgSCHUtlUlHoleIns(db, hole);
7009    rgSCHUtlUlHoleUpdAllocLnks(hole, alloc->prv, alloc->nxt);
7010    return;
7011 }
7012
7013 /***********************************************************
7014  *
7015  *     Func : rgSCHUtlUlHoleUpdAllocLnks
7016  *
7017  *     Desc : Update alloc links in hole
7018  *
7019  *     Ret  : Void
7020  *
7021  *     Notes:
7022  *
7023  *     File :
7024  *
7025  **********************************************************/
7026 Void rgSCHUtlUlHoleUpdAllocLnks(RgSchUlHole  *hole,RgSchUlAlloc *prvAlloc,RgSchUlAlloc *nxtAlloc)
7027 {
7028    if (prvAlloc)
7029    {
7030       prvAlloc->nxtHole = hole;
7031    }
7032    if (nxtAlloc)
7033    {
7034       nxtAlloc->prvHole = hole;
7035    }
7036    hole->prvAlloc = prvAlloc;
7037    hole->nxtAlloc = nxtAlloc;
7038    return;
7039 }
7040
7041
7042 /***********************************************************
7043  *
7044  *     Func : rgSCHUtlUlHoleIns
7045  *
7046  *     Desc : Insert (newly created) hole in sorted list of holes.
7047  *            Searches linearly, beginning with the largest hole.
7048  *
7049  *     Ret  : Void
7050  *
7051  *     Notes:
7052  *
7053  *     File :
7054  *
7055  **********************************************************/
7056 Void rgSCHUtlUlHoleIns(RgSchUlHoleDb *db,RgSchUlHole   *hole)
7057 {
7058    RgSchUlHole *cur;
7059
7060    if ((cur = db->first) != NULLP)
7061    {
7062       RgSchUlHole *nxt;
7063       if (cur->num < hole->num)
7064       {
7065          /* Add at front */
7066          hole->nxt = cur;
7067          cur->prv = hole;
7068          db->first = hole;
7069          hole->prv = NULLP;
7070          return;
7071       }
7072
7073       for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
7074       {
7075          if (nxt->num < hole->num)
7076          {
7077             /* Insert hole:  cur <-> hole <-> nxt */
7078             cur->nxt = hole;
7079             hole->prv = cur;
7080             hole->nxt = nxt;
7081             nxt->prv = hole;
7082             return;
7083          }
7084       }
7085
7086       /* Add at end */
7087       cur->nxt = hole;
7088       hole->prv = cur;
7089       hole->nxt = NULLP;
7090       return;
7091    }
7092
7093    /* This is the first hole */
7094    db->first = hole;
7095    hole->prv = NULLP; /* may not be needed */
7096    hole->nxt = NULLP;
7097    return;
7098 }
7099
7100
7101 /***********************************************************
7102  *
7103  *     Func : rgSCHUtlUlHoleIncr
7104  *
7105  *     Desc : hole->num has increeased, reposition in sorted
7106  *            list if needed
7107  *
7108  *     Ret  : Void
7109  *
7110  *     Notes:
7111  *
7112  *     File :
7113  *
7114  **********************************************************/
7115 Void rgSCHUtlUlHoleIncr(RgSchUlHoleDb *db,RgSchUlHole   *hole)
7116 {
7117    RgSchUlHole *cur;
7118
7119    if ((cur = hole->prv) != NULLP)
7120    {
7121       RgSchUlHole *prv;
7122
7123       if (cur->num > hole->num)
7124       {
7125          return;
7126       }
7127
7128       /* Remove hole from current position */
7129       cur->nxt = hole->nxt;
7130       if (hole->nxt)
7131       {
7132          hole->nxt->prv = cur;
7133       }
7134
7135       for (prv = cur->prv; prv; cur = prv, prv = prv->prv)
7136       {
7137          if (prv->num > hole->num)
7138          {
7139             /* Insert hole:  prv <-> hole <-> cur */
7140             prv->nxt = hole;
7141             hole->prv = prv;
7142             hole->nxt = cur;
7143             cur->prv = hole;
7144             return;
7145          }
7146       }
7147
7148       /* Add at front */
7149       hole->nxt = cur;
7150       cur->prv = hole;
7151       db->first = hole;
7152       hole->prv = NULLP;
7153       return;
7154    }
7155    return;
7156 }
7157
7158 /***********************************************************
7159  *
7160  *     Func : rgSCHUtlUlHoleDecr
7161  *
7162  *     Desc : hole->num has decreeased, reposition in sorted
7163  *            list if needed
7164  *
7165  *     Ret  : Void
7166  *
7167  *     Notes:
7168  *
7169  *     File :
7170  *
7171  **********************************************************/
7172 Void rgSCHUtlUlHoleDecr(RgSchUlHoleDb *db,RgSchUlHole   *hole)
7173 {
7174    RgSchUlHole *cur;
7175
7176    if ((cur = hole->nxt) != NULLP)
7177    {
7178       RgSchUlHole *nxt;
7179
7180       if (cur->num < hole->num)
7181       {
7182          return;
7183       }
7184
7185       /* Remove hole from current position */
7186       cur->prv = hole->prv;
7187       if (hole->prv)
7188       {
7189          hole->prv->nxt = cur;
7190       }
7191       else /* no prv, so cur to replace hole as first in list */
7192       {
7193          db->first = cur;
7194       }
7195
7196       for (nxt = cur->nxt; nxt; cur = nxt, nxt = nxt->nxt)
7197       {
7198          if (nxt->num < hole->num)
7199          {
7200             /* Insert hole:  cur <-> hole <-> nxt */
7201             cur->nxt = hole;
7202             hole->prv = cur;
7203             hole->nxt = nxt;
7204             nxt->prv = hole;
7205             return;
7206          }
7207       }
7208
7209       /* Add at end */
7210       cur->nxt = hole;
7211       hole->prv = cur;
7212       hole->nxt = NULLP;
7213       return;
7214    }
7215    return;
7216 }
7217
7218 /***********************************************************
7219  *
7220  *     Func : rgSCHUtlUlHoleRls
7221  *
7222  *     Desc : Releases hole.
7223  *            1. Decrements hole count.
7224  *            2. Deletes hole from list.
7225  *            3. Frees hole (hole memory release).
7226  *
7227  *     Ret  : Void
7228  *
7229  *     Notes:
7230  *
7231  *     File :
7232  *
7233  **********************************************************/
7234 Void rgSCHUtlUlHoleRls(RgSchUlHoleDb *db,RgSchUlHole   *hole)
7235 {
7236    RgSchUlHole *prv = hole->prv;
7237    RgSchUlHole *nxt = hole->nxt;
7238
7239    --db->count;
7240    if (prv)
7241    {
7242       prv->nxt = nxt;
7243       if (nxt)
7244       {
7245          nxt->prv = prv;
7246       }
7247    }
7248    else
7249    {
7250       db->first = nxt;
7251       if (nxt)
7252       {
7253          nxt->prv = NULLP;
7254       }
7255    }
7256
7257    rgSCHUtlUlHoleMemRls(&db->mem, hole);
7258    return;
7259 }
7260
7261
7262 /***********************************************************
7263  *
7264  *     Func : rgSCHUtlUlAllocMemInit
7265  *
7266  *     Desc : Initialises alloc free pool
7267  *
7268  *     Ret  : S16 (ROK/RFAILED)
7269  *
7270  *     Notes:
7271  *
7272  *     File :
7273  *
7274  **********************************************************/
7275 S16 rgSCHUtlUlAllocMemInit(RgSchCellCb *cell,RgSchUlAllocMem *mem,uint8_t maxAllocs)
7276 {
7277    S16 ret;
7278    RgSchUlAlloc *allocs;
7279
7280    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&allocs,
7281                            maxAllocs * sizeof(*allocs));
7282    if (ret != ROK)
7283    {
7284       return (ret);
7285    }
7286    mem->allocs = allocs;
7287    mem->maxAllocs = maxAllocs;
7288    if (mem->maxAllocs == 1)
7289    {
7290       allocs[0].prv = NULLP;
7291       allocs[0].nxt = NULLP;
7292    }
7293    else
7294    {
7295       uint8_t i;
7296       allocs[0].prv = NULLP;
7297       allocs[0].nxt = &allocs[1];
7298       for (i = 1; i < mem->maxAllocs - 1; ++i)
7299       {
7300          allocs[i].prv = &allocs[i-1];
7301          allocs[i].nxt = &allocs[i+1];
7302       }
7303       allocs[i].prv = &allocs[i-1];
7304       allocs[i].nxt = NULLP;
7305    }
7306    mem->firstFree = &allocs[0];
7307    return ROK;
7308 }
7309
7310 /***********************************************************
7311  *
7312  *     Func : rgSCHUtlUlAllocMemDeinit
7313  *
7314  *     Desc : Deinitialises alloc free pool
7315  *
7316  *     Ret  : Void
7317  *
7318  *     Notes:
7319  *
7320  *     File :
7321  *
7322  **********************************************************/
7323 Void rgSCHUtlUlAllocMemDeinit(RgSchCellCb     *cell,RgSchUlAllocMem *mem)
7324 {
7325    /* ccpu00117052 - MOD - Passing double pointer
7326    for proper NULLP assignment*/
7327    rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->allocs)),
7328                     mem->maxAllocs * sizeof(*mem->allocs));
7329    mem->maxAllocs = 0;
7330    mem->firstFree = NULLP;
7331    return;
7332 }
7333
7334 /***********************************************************
7335  *
7336  *     Func : rgSCHUtlUlHoleMemInit
7337  *
7338  *     Desc : Initialises hole free pool. Assumes maxHoles
7339  *            to be at least 2.
7340  *
7341  *     Ret  : S16 (ROK/RFAILED)
7342  *
7343  *     Notes:
7344  *
7345  *     File :
7346  *
7347  **********************************************************/
7348 S16 rgSCHUtlUlHoleMemInit(RgSchCellCb  *cell,RgSchUlHoleMem *mem,uint8_t  maxHoles,RgSchUlHole **holeRef)
7349 {
7350    S16 ret;
7351    RgSchUlHole *holes;
7352
7353    ret = rgSCHUtlAllocSBuf(cell->instIdx, (Data **)&holes,
7354                            maxHoles * sizeof(*holes));
7355    if (ret != ROK)
7356    {
7357       return (ret);
7358    }
7359
7360    mem->holes = holes;
7361    mem->maxHoles = maxHoles;
7362
7363    /* first hole is taken up */
7364    holes[0].prv = NULLP; /* not needed */
7365    holes[0].nxt = NULLP; /* not needed */
7366    *holeRef = &holes[0];
7367
7368    if (mem->maxHoles == 2)
7369    {
7370       holes[1].prv = NULLP; /* may not be needed */
7371       holes[1].nxt = NULLP; /* may not be needed */
7372    }
7373    else
7374    {
7375       uint8_t i;
7376       holes[1].prv = NULLP;
7377       holes[0].nxt = &holes[1];
7378       for (i = 1; i < mem->maxHoles - 1; ++i)
7379       {
7380          holes[i].prv = &holes[i-1];
7381          holes[i].nxt = &holes[i+1];
7382       }
7383       holes[i].prv = &holes[i-1];
7384       holes[i].nxt = NULLP;
7385    }
7386    mem->firstFree = &holes[1];
7387
7388    return ROK;
7389 }
7390
7391 /***********************************************************
7392  *
7393  *     Func : rgSCHUtlUlHoleMemDeinit
7394  *
7395  *     Desc : Deinitialises hole free pool
7396  *
7397  *     Ret  : Void
7398  *
7399  *     Notes:
7400  *
7401  *     File :
7402  *
7403  **********************************************************/
7404 Void rgSCHUtlUlHoleMemDeinit(RgSchCellCb  *cell,RgSchUlHoleMem *mem)
7405 {
7406    /* ccpu00117052 - MOD - Passing double pointer
7407    for proper NULLP assignment*/
7408    rgSCHUtlFreeSBuf(cell->instIdx, (Data **)(&(mem->holes)),
7409                     mem->maxHoles * sizeof(*mem->holes));
7410    mem->maxHoles = 0;
7411    mem->firstFree = NULLP;
7412    return;
7413 }
7414
7415 /***********************************************************
7416  *
7417  *     Func : rgSCHUtlUlAllocMemGet
7418  *
7419  *     Desc : Gets an 'alloc' from the free pool
7420  *
7421  *     Ret  : RgSchUlAlloc *
7422  *
7423  *     Notes:
7424  *
7425  *     File :
7426  *
7427  **********************************************************/
7428 RgSchUlAlloc *rgSCHUtlUlAllocMemGet(RgSchUlAllocMem *mem)
7429 {
7430    RgSchUlAlloc *alloc;
7431
7432 #if (ERRCLASS & ERRCLS_DEBUG)
7433    if (mem->firstFree == NULLP)
7434    {
7435       return (NULLP);
7436    }
7437 #endif
7438
7439    alloc = mem->firstFree;
7440    mem->firstFree = alloc->nxt;
7441    alloc->nxt = NULLP; /* probably not needed */
7442    /* alloc->prv might already be NULLP, in case was needed to set it to NULLP */
7443
7444    return (alloc);
7445 }
7446
7447 /***********************************************************
7448  *
7449  *     Func : rgSCHUtlUlAllocMemRls
7450  *
7451  *     Desc : Returns an 'alloc' to the free pool
7452  *
7453  *     Ret  :
7454  *
7455  *     Notes:
7456  *
7457  *     File :
7458  *
7459  **********************************************************/
7460 Void rgSCHUtlUlAllocMemRls(RgSchUlAllocMem *mem,RgSchUlAlloc  *alloc)
7461 {
7462    alloc->prv = NULLP;
7463
7464    alloc->nxt = mem->firstFree;
7465    if (mem->firstFree != NULLP)
7466    {
7467       mem->firstFree->prv = alloc;
7468    }
7469    mem->firstFree = alloc;
7470    return;
7471 }
7472
7473 /***********************************************************
7474  *
7475  *     Func : rgSCHUtlUlHoleMemGet
7476  *
7477  *     Desc : Gets a 'hole' from the free pool
7478  *
7479  *     Ret  : RgSchUlHole *
7480  *
7481  *     Notes:
7482  *
7483  *     File :
7484  *
7485  **********************************************************/
7486 RgSchUlHole *rgSCHUtlUlHoleMemGet(RgSchUlHoleMem *mem)
7487 {
7488    RgSchUlHole *hole;
7489
7490 #if (ERRCLASS & ERRCLS_DEBUG)
7491    if (mem->firstFree == NULLP)
7492    {
7493       return (NULLP);
7494    }
7495 #endif
7496
7497    hole = mem->firstFree;
7498    mem->firstFree = hole->nxt;
7499    mem->firstFree->prv = NULLP; /* may not be needed, under error class */
7500    hole->nxt = NULLP; /* probably not needed */
7501    /* hole->prv is might already be NULLP, in case was needed to set it to NULLP */
7502
7503    return (hole);
7504 }
7505
7506 /***********************************************************
7507  *
7508  *     Func : rgSCHUtlUlHoleMemRls
7509  *
7510  *     Desc : Returns a 'hole' to the free pool
7511  *
7512  *     Ret  : Void
7513  *
7514  *     Notes:
7515  *
7516  *     File :
7517  *
7518  **********************************************************/
7519 Void rgSCHUtlUlHoleMemRls(RgSchUlHoleMem *mem,RgSchUlHole    *hole)
7520 {
7521    hole->prv = NULLP;
7522
7523    hole->nxt = mem->firstFree;
7524    if (mem->firstFree != NULLP)
7525    {
7526       mem->firstFree->prv = hole;
7527    }
7528    mem->firstFree = hole;
7529    return;
7530 }
7531
7532 /**
7533  * @brief Get an alloc from the specified position in the BW.
7534  *
7535  * @details
7536  *
7537  *     Function : rgSCHUtlUlGetSpfcAlloc
7538  *
7539  *      - Return an alloc from the specified position in the BW.
7540  *        Note: This function assumes there is always a hole
7541  *              Existing which completely has the specified
7542  *              allocation. The reason for such an assumption is
7543  *              the function's usage as of now guarantees that there
7544  *              will always be such hole. And also for efficiency.
7545  *
7546  *  @param[in]  RgSchUlSf     *sf
7547  *  @param[in]  uint8_t            startSb
7548  *  @param[in]  uint8_t            numSb
7549  *  @return  RgSchUlAlloc*
7550  **/
7551 RgSchUlAlloc *rgSCHUtlUlGetSpfcAlloc(RgSchUlSf *sf,uint8_t startSb,uint8_t  numSb)
7552 {
7553    RgSchUlHole     *hole, *nxtHole;
7554    RgSchUlAlloc    *alloc = NULLP;
7555
7556    if ((hole = rgSCHUtlUlHoleFirst(sf)) == NULLP)
7557    {
7558       return (NULLP);
7559    }
7560    do
7561    {
7562       nxtHole = rgSCHUtlUlHoleNxt(sf, hole);
7563       if ((startSb >= hole->start) &&
7564           (startSb+numSb <= hole->start+hole->num))
7565       {
7566          if (startSb != hole->start)
7567          {
7568             /* Create a new hole to accomodate Subbands between
7569              * hole start and req alloc start */
7570             RgSchUlHole *newHole = rgSCHUtlUlHoleMemGet(&(sf->holeDb->mem));
7571
7572 #if (ERRCLASS & ERRCLS_DEBUG)
7573             if ( newHole == NULLP )
7574             {
7575                 return ( NULLP );
7576             }
7577 #endif
7578             newHole->start = hole->start;
7579             newHole->num = startSb - hole->start;
7580             hole->start = startSb;
7581             /* [ccpu00122847]-MOD- Correctly updating the hole->num */
7582             hole->num -= newHole->num;
7583             ++(sf->holeDb->count);
7584             rgSCHUtlUlHoleIns(sf->holeDb, newHole);
7585             newHole->prvAlloc = hole->prvAlloc;
7586             if (newHole->prvAlloc)
7587             {
7588                newHole->prvAlloc->nxtHole = newHole;
7589             }
7590             if (numSb == hole->num)
7591             {
7592                alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
7593             }
7594             else
7595             {
7596                alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
7597             }
7598             alloc->prvHole = newHole;
7599             newHole->nxtAlloc = alloc;
7600          }
7601          else /* Hole start and req alloc start are same */
7602          {
7603             if (numSb == hole->num)
7604             {
7605                alloc = rgSCHUtlUlAllocGetCompHole(sf, hole);
7606             }
7607             else
7608             {
7609                alloc = rgSCHUtlUlAllocGetPartHole(sf, numSb, hole);
7610             }
7611          }
7612          break;
7613       }
7614    } while ((hole = nxtHole) != NULLP);
7615    return (alloc);
7616 }
7617 #ifdef LTE_L2_MEAS
7618 /**
7619  * @brief  Validates the qci values
7620  *
7621  * @details
7622  *
7623  *     Function :rgSCHUtlValidateQci
7624  *
7625  *  @param[in]  RgSchCellCb     *cellCb
7626  *  @param[in]  uint8_t              numQci
7627  *  @param[out] uint8_t              *qci
7628  *  @return  S16
7629  *           ROK
7630  *           RFAILED
7631  **/
7632 static S16 rgSCHUtlValidateQci(RgSchCellCb  *cellCb,uint8_t numQci,uint8_t *qci)
7633 {
7634    uint8_t        qciIdx;
7635    uint8_t        qciVal;
7636
7637    for(qciIdx = 0; qciIdx < numQci; qciIdx++)
7638    {
7639       qciVal = qci[qciIdx];
7640       if(qciVal == 0 || qciVal > 9)
7641       {
7642          return RFAILED;
7643       }
7644       if(qciVal != cellCb->qciArray[qciVal].qci)
7645       {
7646          return RFAILED;
7647       }
7648    }
7649
7650    return ROK;
7651 }/* rgSCHUtlValidateQci */
7652 /**
7653  * @brief  Validates the measurement request parameters.
7654  *
7655  * @details
7656  *
7657  *     Function :rgSCHUtlValidateMeasReq
7658  *
7659  *  @param[in]  RgSchCellCb        *cellCb
7660  *  @param[in]  LrgSchMeasReqInfo  *schL2MeasInfo
7661  *  @param[out] RgSchErrInfo       *err
7662  *  @return  RgSchUlAlloc*
7663  **/
7664 S16 rgSCHUtlValidateMeasReq(RgSchCellCb *cellCb, LrgSchMeasReqInfo *schL2MeasInfo,RgSchErrInfo *err)
7665 {
7666    uint16_t    measType;
7667    S16   ret;
7668
7669    measType = schL2MeasInfo->measType;
7670    if((measType == 0) ||
7671        measType > 2047)
7672    {
7673       err->errType = RGSCHERR_SCH_INVALID_MEAS_TYPE;
7674       err->errCause = RGSCHERR_SCH_L2MEAS;
7675       return RFAILED;
7676    }
7677    if((schL2MeasInfo->timePrd !=0) &&
7678       (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
7679       ((schL2MeasInfo->avgPrbQciDl.numQci > LRG_MAX_QCI_PER_REQ)||
7680        (schL2MeasInfo->avgPrbQciDl.numQci == 0)))
7681    {
7682       err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
7683       err->errCause = RGSCHERR_SCH_L2MEAS;
7684       return RFAILED;
7685    }
7686    if((schL2MeasInfo->timePrd !=0) &&
7687      (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) &&
7688       (schL2MeasInfo->avgPrbQciUl.numQci > LRG_MAX_QCI_PER_REQ)) 
7689    {
7690       err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
7691       err->errCause = RGSCHERR_SCH_L2MEAS;
7692       return RFAILED;
7693    }
7694    if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL) &&
7695          ((schL2MeasInfo->nmbActvUeQciDl.numQci > LRG_MAX_QCI_PER_REQ) ||
7696           (schL2MeasInfo->nmbActvUeQciDl.sampPrd == 0)||
7697           ((schL2MeasInfo->timePrd !=0)&&
7698            (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciDl.sampPrd)) ||
7699          (schL2MeasInfo->nmbActvUeQciDl.sampPrd > LRG_MAX_SAMP_PRD)))
7700    {
7701       err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
7702       err->errCause = RGSCHERR_SCH_L2MEAS;
7703       return RFAILED;
7704    }
7705    if((measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL) &&
7706       ((schL2MeasInfo->nmbActvUeQciUl.numQci > LRG_MAX_QCI_PER_REQ) ||
7707        (schL2MeasInfo->nmbActvUeQciUl.sampPrd == 0)||
7708        ((schL2MeasInfo->timePrd !=0) &&
7709         (schL2MeasInfo->timePrd < schL2MeasInfo->nmbActvUeQciUl.sampPrd)) ||
7710         (schL2MeasInfo->nmbActvUeQciUl.sampPrd > LRG_MAX_SAMP_PRD)))
7711    {
7712       err->errType = RGSCHERR_SCH_INVALID_PARAM_RANGE;
7713       err->errCause = RGSCHERR_SCH_L2MEAS;
7714       return RFAILED;
7715    }
7716    if((schL2MeasInfo->timePrd !=0) &&
7717        (measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL))
7718    {
7719       RGSCH_ARRAY_BOUND_CHECK(cellCb->instIdx, schL2MeasInfo->avgPrbQciDl.qci,  \
7720       (schL2MeasInfo->avgPrbQciDl.numQci));
7721       ret  = rgSCHUtlValidateQci(cellCb, schL2MeasInfo->avgPrbQciDl.numQci,
7722                                  schL2MeasInfo->avgPrbQciDl.qci);
7723       if(ret != ROK)
7724       {
7725           err->errType = RGSCHERR_SCH_INVALID_QCI_VAL;
7726           err->errCause = RGSCHERR_SCH_L2MEAS;
7727           return RFAILED;
7728       }
7729    }
7730    return ROK;
7731 }/* rgSCHUtlValidateMeasReq */
7732 #endif /* LTE_L2_MEAS */
7733 /******* </AllocHolesMemMgmnt>: END *****/
7734 #ifdef RGR_SI_SCH
7735 /**
7736  * @brief API for sending SI configuration confirm from Scheduler to RRM
7737  *
7738  * @details
7739  *
7740  *     Function: rgSCHUtlRgrSiCfgCfm
7741  *
7742  *     This API is invoked to send SI configuration confirm from Scheduler
7743  *     to RRM.
7744  *     This API fills in Pst structure and SAP Ids and invokes
7745  *     config confirm API towards RRM.
7746  *
7747  *  @param[in]  RgrCfgTransId transId
7748  *  @param[in]  uint8_t            status
7749  *  @return  S16
7750  *      -# ROK
7751  *      -# RFAILED
7752  **/
7753 S16 rgSCHUtlRgrSiCfgCfm(Inst instId,SpId  spId,RgrCfgTransId transId,uint8_t status)
7754 {
7755    uint8_t        prntTrans[RGR_CFG_TRANSID_SIZE+1];
7756
7757    memcpy(prntTrans, transId.trans, RGR_CFG_TRANSID_SIZE);
7758    prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
7759    if(RgUiRgrSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
7760                     rgSchCb[instId].rgrSap[spId].sapCfg.suId,
7761                     transId, status) != ROK)
7762    {
7763       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrSiCfgCfm: "
7764                 "RgUiRgrSiCfgCfm Failed ");
7765       return RFAILED;
7766    }
7767
7768    return ROK;
7769 }  /* rgSCHUtlRgrSiCfgCfm */
7770
7771 \f
7772 /**
7773  * @brief API for sending Warning SI configuration confirm from 
7774  * Scheduler to RRM
7775  *
7776  * @details
7777  *
7778  *
7779  *     This API is invoked to send Warning SI configuration confirm 
7780  *     from Scheduler to RRM.
7781  *     This API fills in Pst structure and SAP Ids and invokes
7782  *     config confirm API towards RRM.
7783  *
7784  *  @param[in]  RgrCfgTransId transId
7785  *  @param[in]  uint8_t            status
7786  *  @return  S16
7787  *      -# ROK
7788  *      -# RFAILED
7789  **/
7790 S16 rgSCHUtlRgrWarningSiCfgCfm(Inst instId,SpId spId,uint8_t siId,RgrCfgTransId transId,uint8_t  status)
7791 {
7792    uint8_t        prntTrans[RGR_CFG_TRANSID_SIZE+1];
7793
7794    memcpy(prntTrans, transId.trans, RGR_CFG_TRANSID_SIZE);
7795    prntTrans[RGR_CFG_TRANSID_SIZE] = '\0';
7796    
7797    if(RgUiRgrWarningSiCfgCfm(&rgSchCb[instId].rgrSap[spId].sapCfg.sapPst,
7798                     rgSchCb[instId].rgrSap[spId].sapCfg.suId, 
7799                     transId, siId, status) != ROK)
7800    {
7801       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrSiCfgCfm: "
7802                 "RgUiRgrSiCfgCfm Failed ");
7803       return RFAILED;
7804    }
7805
7806    return ROK;
7807 }  /* rgSCHUtlRgrWarningSiCfgCfm */
7808
7809 /***********************************************************
7810  *
7811  *     Func : rgSCHUtlPutSiInfo
7812  *
7813  *     Desc : Utility Function to deallocate SI information
7814  *
7815  *
7816  *            RFAILED
7817  *
7818  *
7819  *     File : rg_utl.c
7820  *
7821  **********************************************************/
7822 Void rgSCHUtlPutSiInfo(RgSchCellCb *cell)
7823 {
7824    uint8_t    idx = 0;
7825    uint32_t   sizeOfSiInfo = 0;
7826    /*Free the buffers in crntSiInfo*/
7827    RGSCH_FREE_MSG(cell->siCb.crntSiInfo.mib)
7828    RGSCH_FREE_MSG(cell->siCb.crntSiInfo.sib1Info.sib1)
7829    
7830    sizeOfSiInfo = sizeof(cell->siCb.crntSiInfo.siInfo)/sizeof(cell->siCb.crntSiInfo.siInfo[0]);
7831    
7832    for(idx=0; idx < sizeOfSiInfo; idx++)
7833    {
7834       RGSCH_FREE_MSG(cell->siCb.crntSiInfo.siInfo[idx].si)
7835    }
7836
7837    /*Free the buffers in newSiInfo */
7838    RGSCH_FREE_MSG(cell->siCb.newSiInfo.mib)
7839    RGSCH_FREE_MSG(cell->siCb.newSiInfo.sib1Info.sib1)
7840
7841    sizeOfSiInfo = sizeof(cell->siCb.newSiInfo.siInfo)/sizeof(cell->siCb.newSiInfo.siInfo[0]);
7842
7843    for(idx=0; idx < sizeOfSiInfo; idx++)
7844    {
7845       RGSCH_FREE_MSG(cell->siCb.newSiInfo.siInfo[idx].si)
7846    }
7847
7848    return;
7849 }
7850 #endif /*RGR_SI_SCH */
7851
7852
7853
7854 /***********************************************************
7855  *
7856  *     Func : rgSCHUtlGetDrxSchdUesInDl
7857  *
7858  *     Desc : Utility Function to fill the get the list of
7859  *            scheduled UEs. On these UE's, drx-inactivity
7860  *            timer will be started/restarted.
7861  *
7862  *     Ret  : ROK
7863  *            RFAILED
7864  *
7865  *     Notes:
7866  *
7867  *     File : rg_utl.c
7868  *
7869  **********************************************************/
7870 S16 rgSCHUtlGetDrxSchdUesInDl
7871 (
7872 RgSchCellCb     *cellCb,
7873 RgSchUeCb       *ueCb,
7874 RgSchDlHqProcCb *dlHq,
7875 RgInfUeAlloc    *allocInfo,
7876 CmLListCp       *dlDrxInactvTmrLst,
7877 CmLListCp       *dlInActvLst,
7878 CmLListCp       *ulInActvLst
7879 )
7880 {
7881    Bool                  isNewTx = FALSE;
7882    uint8_t                    idx;
7883    RgSchDrxDlHqProcCb    *drxHq;
7884    RgSchDRXCellCb        *drxCell = cellCb->drxCb;
7885    RgSchDrxUeCb          *drxUe;
7886    uint8_t                    cellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(dlHq->hqE->cell)];
7887    uint32_t                   dlInactvMask;
7888    uint32_t                   ulInactvMask;
7889
7890    for(idx = 0; idx < allocInfo->nmbOfTBs; idx++)
7891    {
7892       if(allocInfo->tbInfo[idx].isReTx == FALSE)
7893       {
7894          isNewTx = TRUE;
7895          /* Removing break here, since in 2 TB case if 2nd TB is proceeding with 
7896             retx then drxretx timer should be stopped.*/
7897       }
7898       else
7899       {
7900          /*Stop the DRX retransmission timer as UE scheduled for retx. Here
7901           * we stop the timer and inactivate the UE for both UL and DL.
7902           * This may result in loss of one slot for UL but this trade
7903           * off is taken to avoid the overhead of maintaining a list of UEs
7904           * to be inactivated in the next slot.*/
7905          drxHq = RG_SCH_DRX_GET_DL_HQ(dlHq);
7906          drxUe = RG_SCH_DRX_GET_UE(ueCb);
7907          if(drxHq->reTxIndx != DRX_INVALID)
7908          {  
7909             /* This condition should never occur */      
7910             if(drxHq->reTxIndx >= RG_SCH_MAX_DRXQ_SIZE)
7911             {
7912                 DU_LOG("\nERROR  -->  SCH : [%d]UE:DRXUE RETX IDX[%d]"
7913                         "is out of bound,dlInactvMask %d,procId %d\n", ueCb->ueId,
7914                         drxHq->reTxIndx,ueCb->dl.dlInactvMask, dlHq->procId);
7915             }
7916
7917             drxUe->drxDlInactvMaskPerCell[cellIdx]  |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
7918             drxUe->drxUlInactvMaskPerCell[cellIdx]  |= (RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId);
7919
7920             dlInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
7921             ulInactvMask = RG_SCH_DRX_DLHQ_BITMASK << dlHq->procId;
7922
7923             for(cellIdx = 0; cellIdx < CM_LTE_MAX_CELLS; cellIdx++)
7924             {
7925                dlInactvMask &= drxUe->drxDlInactvMaskPerCell[cellIdx];
7926                ulInactvMask &= drxUe->drxUlInactvMaskPerCell[cellIdx];
7927             }
7928
7929             drxUe->drxDlInactvMask |= dlInactvMask;
7930             drxUe->drxUlInactvMask |= ulInactvMask;
7931
7932             /* if no other condition is keeping ue active,
7933              * inactivate the Ue
7934              */
7935             if(!RG_SCH_DRX_DL_IS_UE_ACTIVE(drxUe))
7936             {
7937                /* BUG 2 : HARQ_RTT, changed for consistency */
7938                ueCb->dl.dlInactvMask |= (RG_DRX_INACTIVE);
7939
7940                /* Add to DL inactive list */
7941                cmLListAdd2Tail(dlInActvLst,&(ueCb->dlDrxInactvLnk));
7942                ueCb->dlDrxInactvLnk.node = (PTR)ueCb;
7943             }
7944
7945             if(!RG_SCH_DRX_UL_IS_UE_ACTIVE(drxUe))
7946             {
7947                /*BUG 2: HARQ_RTT changed for consistency */
7948                ueCb->ul.ulInactvMask |= (RG_DRX_INACTIVE);
7949
7950                cmLListAdd2Tail(ulInActvLst,&(ueCb->ulDrxInactvLnk));
7951                ueCb->ulDrxInactvLnk.node  = (PTR)ueCb;
7952             }
7953
7954             /* Deleting entry from HARQ RTT queue for the same HARQ proc, 
7955              * if exist. This is the special case which can happen iF UL 
7956              * scheduling is done later. */
7957             if(drxHq->rttIndx != DRX_INVALID)
7958             {
7959                cmLListDelFrm (&(cellCb->drxCb->drxQ[drxHq->rttIndx].harqRTTQ),
7960                      &(drxHq->harqRTTEnt));
7961
7962                drxHq->rttIndx = DRX_INVALID;
7963             }   
7964
7965             cmLListDelFrm (&(drxCell->drxQ[drxHq->reTxIndx].harqRetxQ),
7966                   &(drxHq->harqRetxEnt));
7967             drxHq->reTxIndx = DRX_INVALID;
7968          }
7969       }
7970    }
7971
7972    if(isNewTx == TRUE)
7973    {
7974       if(ueCb->drxCb->raRcvd == TRUE)
7975       {
7976          ueCb->drxCb->raRcvd = FALSE;
7977
7978          /* mark the ra bit */
7979          ueCb->drxCb->drxUlInactvMask |= RG_SCH_DRX_RA_BITMASK;
7980          ueCb->drxCb->drxDlInactvMask |= RG_SCH_DRX_RA_BITMASK;
7981
7982       }/*if(ra->rcvd) == TRUE */
7983
7984       if(ueCb->dlDrxInactvTmrLnk.node == NULLP)
7985       {   
7986          cmLListAdd2Tail(dlDrxInactvTmrLst,&(ueCb->dlDrxInactvTmrLnk));
7987          ueCb->dlDrxInactvTmrLnk.node = (PTR)ueCb;
7988       }
7989    }/*if(isNewTx == TRUE) */
7990
7991    return ROK;
7992 }/* rgSCHUtlGetSchdUes*/
7993 \f
7994 /* ccpu00117452 - MOD - Changed macro name from
7995    RGR_RRM_DLPWR_CNTRL to RGR_CQI_REPT */
7996 #ifdef RGR_CQI_REPT
7997 /**
7998  * @brief This function fills StaInd struct
7999  *
8000  * @details
8001  *
8002  *     Function: rgSCHUtlFillSndStaInd
8003  *     Purpose:  Fills StaInd struct and sends the
8004  *               StaInd to RRM
8005  *
8006  *  @param[in]  RgSchCellCb        *cell  pointer to Cell Control block
8007  *  @param[in]  RgSchUeCb          *ue  pointer to Ue Control block
8008  *  @param[in]  RgrStaIndInfo      *staInfo Sta Ind struct to be filled
8009  *  @param[in]  uint8_t                 numCqiRept NUmber of reports to be filled
8010  *  @return  Void
8011  *
8012  **/
8013 S16 rgSCHUtlFillSndStaInd(RgSchCellCb *cell,RgSchUeCb *ue,RgrStaIndInfo *staInfo,uint8_t numCqiRept)
8014 {
8015    uint8_t idxStart;
8016
8017    /* Fill StaInd for sending collated Latest N CQI rpeorts */
8018    /* Find index in the array from where Latest N
8019       reports needs to be fetched. Use this value to index in the array
8020       and copy the reports into staInfo */
8021
8022    /* Fill the Cell Id of PCC of the UE */
8023    staInfo->cellId = ue->cell->cellId;
8024    staInfo->crnti = ue->ueId;
8025
8026    idxStart = ue->schCqiInfo.cqiCount - numCqiRept;
8027
8028    memcpy (&(staInfo->ueCqiInfo.cqiRept),
8029             &(ue->schCqiInfo.cqiRept[idxStart]),
8030             numCqiRept * sizeof(RgrUeCqiRept));
8031
8032    staInfo->ueCqiInfo.numCqiRept = numCqiRept;
8033
8034    ue->schCqiInfo.cqiCount = 0;
8035
8036    /* Call utility function (rgSCHUtlRgrStaInd) to send rpts to RRM */
8037    if(rgSCHUtlRgrStaInd(cell, staInfo) != ROK)
8038    {
8039       DU_LOG("\nERROR  -->  SCH : Could not send "
8040          "CQI reports for RNTI:%d",ue->ueId);
8041       return RFAILED;
8042    }
8043
8044    return ROK;
8045
8046 }/* End of rgSCHUtlFillSndStaInd */
8047
8048
8049 \f
8050 /**
8051  * @brief API for sending STA indication from Scheduler to RRM.
8052  *
8053  * @details
8054  *
8055  *     Function: rgSCHUtlRgrStaInd
8056  *
8057  *     This API is invoked to send STA indication from Scheduler instance to RRM.
8058  *     This API fills in Pst structure and RgrStaIndInfo
8059  *     and calls the Sta primitive API towards RRM.
8060  *
8061  *  @param[in]  cell                   RgSchCellCb
8062  *  @param[in]  RgrStsIndInfo          *rgrSta
8063  *  @return  S16
8064  *      -# ROK
8065  *      -# RFAILED
8066  **/
8067 S16 rgSCHUtlRgrStaInd(RgSchCellCb *cell,RgrStaIndInfo *rgrSta)
8068 {
8069    S16           ret = ROK;
8070    RgSchUpSapCb  *rgrSap;                    /*!< RGR SAP Control Block */
8071    
8072    rgrSap = cell->rgrSap;
8073    if (rgrSap->sapSta.sapState != LRG_BND)
8074    {
8075       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrStaInd() Upper SAP not bound (%d) ",
8076                rgrSap->sapSta.sapState);
8077       return RFAILED;
8078    }
8079    RgUiRgrStaInd(&(cell->rgrSap->sapCfg.sapPst),
8080          cell->rgrSap->sapCfg.suId, rgrSta);
8081    return (ret);
8082 }  /* rgSCHUtlRgrStaInd*/
8083 #endif /* End of RGR_CQI_REPT */
8084
8085 /* Fix : syed HO UE does not have a valid ue->rntiLnk */
8086 /**
8087  * @brief Indicates MAC to release any rnti context it has.
8088  *
8089  * @details
8090  *     Function : rgSCHUtlIndRntiRls2Mac 
8091  *       This function indicates MAC for this rnti release.
8092  *       In case of ueId change it will indicate MAC
8093  *       about the new rnti to be updated.
8094  *       It will post a release RNTI indication to MAC.
8095  *     
8096  *    
8097  *           
8098  *  @param[in]     RgSchCellCb    *cell
8099  *  @param[in]     CmLteRnti      rnti 
8100  *  @param[in]     Bool           ueIdChng
8101  *  @param[in]     CmLteRnti      newRnti
8102  *  @return  Void
8103  *      -# ROK 
8104  **/
8105 Void rgSCHUtlIndRntiRls2Mac(RgSchCellCb *cell,CmLteRnti  rnti,Bool ueIdChng,CmLteRnti newRnti)
8106 {
8107    Pst          pst;
8108    Inst         inst = cell->instIdx;
8109    RgInfRlsRnti rntiInfo;
8110
8111
8112    /* Copy the info to rntiInfo */
8113    rntiInfo.cellId = cell->cellId;
8114    rntiInfo.rnti   = rnti;
8115    /* Fix : syed ueId change as part of reestablishment.
8116     * Now SCH to trigger this. CRG ueRecfg for ueId change 
8117     * is dummy */          
8118    rntiInfo.ueIdChng = ueIdChng;
8119    rntiInfo.newRnti  = newRnti;
8120 #ifdef LTE_ADV
8121    rntiInfo.isUeSCellDel = FALSE;
8122 #endif
8123    /* Invoke MAC to release the rnti */
8124    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
8125    RgSchMacRlsRnti(&pst, &rntiInfo);
8126    return;
8127 }
8128
8129 /* LTE_ADV_FLAG_REMOVED_START */
8130 /**
8131  * @brief API for sending LOAD INF indication from Scheduler to RRM.
8132  * @details
8133  *
8134  *     Function: rgSCHUtlRgrLoadInfInd
8135  *
8136  *     This API is invoked to send LOAD INF indication from Scheduler instance to RRM.
8137  *     This API fills in Pst structure and RgrLoadInfIndInfo
8138  *     and calls the Sta primitive API towards RRM.
8139  *
8140  *  @param[in]  cell                    RgSchCellCb
8141  *  @param[in]  RgrLoadInfIndInfo       *rgrLoadInf
8142  *  @return  S16
8143  *      -# ROK
8144  *      -# RFAILED
8145  **/
8146 S16 rgSCHUtlRgrLoadInfInd(RgSchCellCb *cell,RgrLoadInfIndInfo *rgrLoadInf)
8147 {
8148    S16           ret = ROK;
8149    RgSchUpSapCb  *rgrSap;                    /*!< RGR SAP Control Block */
8150
8151    rgrSap = cell->rgrSap;
8152    if (rgrSap->sapSta.sapState != LRG_BND)
8153    {
8154       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrLoadInfInd() Upper SAP not bound (%d) ",
8155                rgrSap->sapSta.sapState);
8156       return RFAILED;
8157    }
8158    RgUiRgrLoadInfInd(&(cell->rgrSap->sapCfg.sapPst),
8159          cell->rgrSap->sapCfg.suId, rgrLoadInf);
8160    return (ret);
8161 }  /* rgSCHUtlRgrLoadInfInd*/
8162 /* LTE_ADV_FLAG_REMOVED_END */
8163
8164 /* MS_FIX : syed SCH to act as MASTER in maintaining
8165  * rnti related context. Trigger to rnti del/Chng at SCH
8166  * will result in a Indication to MAC to release its
8167  * RNTI context. MAC inturn indicates the context cleared
8168  * indication to SCH, upon which SCH would set this
8169 /**
8170  * @brief API for sending STA indication from Scheduler to RRM.
8171  *
8172  * @details
8173  *
8174  *     Function: rgSCHUtlRlsRnti
8175  *
8176  *     This API is invoked to indicate MAC to release rnti
8177  *
8178  *  @param[in]  RgSchCellCb    *cellCb                   
8179  *  @param[in]  RgSchRntiLnk   *rntiLnk,
8180  *  @param[in]  Bool           ueIdChngd,
8181  *  @param[in]  CmLteRnti      newRnti
8182  *  @return  Void
8183  **/
8184
8185 Void rgSCHUtlRlsRnti(RgSchCellCb *cell,RgSchRntiLnk  *rntiLnk,Bool ueIdChngd,CmLteRnti newRnti)
8186 {
8187
8188    uint8_t isLegacy = 0;
8189 #ifdef EMTC_ENABLE
8190    if(cell->emtcEnable)
8191    {
8192       rgSCHEmtcUtlRlsRnti(cell, rntiLnk, &isLegacy);
8193    }
8194 #endif
8195    if(!isLegacy)
8196    {
8197       /*Add to Guard Pool*/
8198       cmLListAdd2Tail(&cell->rntiDb.rntiGuardPool, &rntiLnk->rntiGrdPoolLnk);
8199       rntiLnk->rntiGrdPoolLnk.node = (PTR)rntiLnk;
8200    }
8201    /* Fix: syed Explicitly Inidcate MAC to release RNTI */
8202    rgSCHUtlIndRntiRls2Mac(cell, rntiLnk->rnti, ueIdChngd, newRnti);
8203
8204    return;
8205 }
8206
8207
8208 /**
8209  * @brief This function fills StaInd struct
8210  *
8211  * @details
8212  *
8213  *     Function: rgSCHUtlFillSndUeStaInd
8214  *     Purpose:  Fills StaInd struct and sends the
8215  *               StaInd to RRM
8216  *
8217  *  @param[in]  RgSchCellCb        *cell  pointer to Cell Control block
8218  *  @param[in]  RgSchUeCb          *ue  pointer to Ue Control block
8219  *  @param[in]  uint8_t                 numCqiRept NUmber of reports to be filled
8220  *  @return  Void
8221  *
8222  **/
8223 S16 rgSCHUtlFillSndUeStaInd(RgSchCellCb *cell,RgSchUeCb  *ue,RgrUeStaIndInfo  *ueStaInfo)
8224 {
8225
8226    ueStaInfo->cellId = cell->cellId;
8227    ueStaInfo->crnti = ue->ueId;
8228
8229    /* Call utility function (rgSCHUtlRgrUeStaInd) to send rpts to RRM */
8230    if(rgSCHUtlRgrUeStaInd(cell, ueStaInfo) != ROK)
8231    {
8232       DU_LOG("\nERROR  -->  SCH : Could not send "
8233          "UE Sta reports CRNTI:%d",ue->ueId);
8234       return RFAILED;
8235    }
8236
8237    return ROK;
8238
8239 }/* End of rgSCHUtlFillSndStaInd */
8240
8241
8242 \f
8243 /**
8244  * @brief API for sending STA indication from Scheduler to RRM.
8245  *
8246  * @details
8247  *
8248  *     Function: rgSCHUtlRgrStaInd
8249  *
8250  *     This API is invoked to send STA indication from Scheduler instance to RRM.
8251  *     This API fills in Pst structure and RgrStaIndInfo
8252  *     and calls the Sta primitive API towards RRM.
8253  *
8254  *  @param[in]  cell                   RgSchCellCb
8255  *  @param[in]  RgrStsIndInfo          *rgrSta
8256  *  @return  S16
8257  *      -# ROK
8258  *      -# RFAILED
8259  **/
8260 S16 rgSCHUtlRgrUeStaInd(RgSchCellCb *cell,RgrUeStaIndInfo *rgrUeSta)
8261 {
8262    S16           ret = ROK;
8263    RgSchUpSapCb  *rgrSap;                    /*!< RGR SAP Control Block */
8264
8265    rgrSap = cell->rgrSap;
8266    if (rgrSap->sapSta.sapState != LRG_BND)
8267    {
8268       DU_LOG("\nERROR  -->  SCH : rgSCHUtlRgrUeStaInd() Upper SAP not bound (%d) ",
8269                rgrSap->sapSta.sapState);
8270       return RFAILED;
8271    }
8272    RgUiRgrUeStaInd(&(cell->rgrSap->sapCfg.sapPst),
8273          cell->rgrSap->sapCfg.suId, rgrUeSta);
8274    return (ret);
8275 }  /* rgSCHUtlRgrStaInd*/
8276
8277 /* RRM_RBC_X */
8278 /**
8279  * @brief function to report DL and UL PRB usage to RRM.
8280  *
8281  *
8282  *     Function: rgSCHUtlUpdAvgPrbUsage
8283  *               This function sends the PRB usage report to 
8284  *               RRM with the interval configured by RRM.
8285  *
8286  *  @param[in]  cell       *RgSchCellCb
8287  *  @return  S16
8288  *      -# ROK
8289  *      -# RFAILED
8290  **/
8291 S16 rgSCHUtlUpdAvgPrbUsage(RgSchCellCb  *cell)
8292 {
8293    CmLteTimingInfo  frm;
8294    RgmPrbRprtInd    *prbRprtInd;
8295    S16              ret = ROK;
8296    uint32_t              idx;
8297 #ifdef DBG_MAC_RRM_PRB_PRINT
8298    static uint32_t       count = 0;
8299    const uint32_t reprotForEvery20Sec = 20000/cell->prbUsage.rprtPeriod;
8300
8301    count++;
8302 #endif
8303
8304    frm   = cell->crntTime;
8305    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
8306
8307    uint16_t numDlSf;
8308    uint16_t numUlSf;
8309 #ifdef LTE_TDD
8310   
8311    if(cell->prbUsage.rprtPeriod >= RGSCH_NUM_SUB_FRAMES)
8312    {
8313       /* Get the total number of DL and UL slots within the reporting period*/
8314       numDlSf = (cell->prbUsage.rprtPeriod * 
8315             rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
8316          / RGSCH_NUM_SUB_FRAMES;
8317       numUlSf = (cell->prbUsage.rprtPeriod * 
8318             rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1])
8319          / RGSCH_NUM_SUB_FRAMES;
8320    }
8321    else
8322    {
8323       /* Get the total number of DL and UL slots < 10 ms interval */
8324       numDlSf = rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
8325       numUlSf = rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][frm.slot];
8326    }
8327 #else
8328      numDlSf = cell->prbUsage.rprtPeriod;
8329      numUlSf = cell->prbUsage.rprtPeriod;
8330 #endif
8331
8332     SCH_ALLOC(prbRprtInd, sizeof(RgmPrbRprtInd));
8333     if(prbRprtInd == NULLP)
8334    {
8335       DU_LOG("\nERROR  --> SCH : Failed to allocate memory for prbRprtInd");
8336       return RFAILED;
8337    }
8338
8339    memset(&prbRprtInd->stQciPrbRpts[0],
8340             0,
8341             (RGM_MAX_QCI_REPORTS * sizeof(RgmPrbRptPerQci)));
8342
8343    prbRprtInd->bCellId            = cell->cellId;
8344
8345    if(numDlSf > 0)
8346    {
8347       prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_DL; 
8348       for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
8349       {
8350          prbRprtInd->stQciPrbRpts[idx].bAvgPrbDlUsage  = 
8351            RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed*100),
8352                            (numDlSf * cell->bwCfg.dlTotalBw));
8353          prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
8354          cell->prbUsage.qciPrbRpts[idx].dlTotPrbUsed = 0;
8355       }
8356    }
8357
8358    if(numUlSf > 0)
8359    {
8360       prbRprtInd->bPrbUsageMask |= RGM_PRB_USAGE_UL; 
8361       for (idx = 0; idx < RGM_MAX_QCI_REPORTS; idx++ )
8362       {
8363          prbRprtInd->stQciPrbRpts[idx].bAvgPrbUlUsage  = 
8364            RGSCH_DIV_ROUND((cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed*100),
8365                            (numUlSf * cell->ulAvailBw));
8366          prbRprtInd->stQciPrbRpts[idx].bQci = cell->prbUsage.qciPrbRpts[idx].qci;
8367          cell->prbUsage.qciPrbRpts[idx].ulTotPrbUsed = 0;
8368       }
8369    }
8370
8371 #ifdef DBG_MAC_RRM_PRB_PRINT
8372    if((count % reprotForEvery20Sec) == 0 )
8373    {
8374       DU_LOG("\n====================================================================");
8375       DU_LOG("\nINFO  -->  SCH : QCI-1[DL:UL]  | QCI-2[DL:UL]  | QCI-3[DL:UL]  | QCI-4[DL:UL] \n");
8376       DU_LOG("======================================================================\n");
8377       DU_LOG(" [%d: %d]\t | [%d: %d]\t | [%d: %d]\t| [%d: %d]\t\n", 
8378                  prbRprtInd->stQciPrbRpts[0].bAvgPrbDlUsage,
8379                  prbRprtInd->stQciPrbRpts[0].bAvgPrbUlUsage,
8380                  prbRprtInd->stQciPrbRpts[1].bAvgPrbDlUsage,
8381                  prbRprtInd->stQciPrbRpts[1].bAvgPrbUlUsage,
8382                  prbRprtInd->stQciPrbRpts[2].bAvgPrbDlUsage,
8383                  prbRprtInd->stQciPrbRpts[2].bAvgPrbUlUsage,
8384                  prbRprtInd->stQciPrbRpts[3].bAvgPrbDlUsage,
8385                  prbRprtInd->stQciPrbRpts[3].bAvgPrbUlUsage);
8386    }
8387 #endif
8388    RgUiRgmSendPrbRprtInd(&(cell->rgmSap->sapCfg.sapPst), 
8389                     cell->rgmSap->sapCfg.suId, prbRprtInd);
8390
8391
8392    return (ret);
8393 }
8394 /* RRM_RBC_Y */
8395
8396 /**
8397  * @brief This function resends the Ta in case of 
8398  *        max retx failure or DTX for the Ta transmitted 
8399  *
8400  * @details
8401  *
8402  *     Function: rgSCHUtlReTxTa
8403  *     Purpose:  
8404  *                
8405  *  @param[in]  RgSchCellCb           *cell
8406  *  @param[in]  RgSchUeCb             *ue
8407  *  @return  Void 
8408  *
8409  **/
8410 Void rgSCHUtlReTxTa(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
8411 {
8412
8413    /* If TA Timer is running. Stop it */
8414    if (ueCb->taTmr.tmrEvnt != TMR_NONE)
8415    {
8416       rgSCHTmrStopTmr(cellCb, ueCb->taTmr.tmrEvnt, ueCb);
8417    }
8418    /*[ccpu00121813]-ADD-If maxretx is reached then 
8419     * use outstanding TA val for scheduling again */
8420    if(ueCb->dl.taCb.outStndngTa == TRUE)
8421    {
8422       ueCb->dl.taCb.ta = ueCb->dl.taCb.outStndngTaval;
8423       ueCb->dl.taCb.outStndngTaval = RGSCH_NO_TA_RQD;
8424       ueCb->dl.taCb.outStndngTa = FALSE;
8425
8426    }
8427    /* Fix : syed TA state updation missing */
8428    ueCb->dl.taCb.state = RGSCH_TA_TOBE_SCHEDULED;
8429    rgSCHUtlDlTARpt(cellCb, ueCb); 
8430
8431    return;
8432 }
8433
8434 /* Added function for dropping Paging Message*/
8435 /**
8436  * @brief Handler for BO Updt received for BCCH or PCCH.
8437  *
8438  * @details
8439  *
8440  *     Function : rgSCHChkBoUpdate
8441  *
8442  *     This function shall check for BO received falls within the scheduling window or not
8443  *
8444  *
8445  *  @param[in]  RgSchCellCb    *cell
8446  *  @return  S16
8447  *      -# ROK 
8448  *      -# RFAILED
8449  **/
8450 static S16 rgSCHChkBoUpdate(RgSchCellCb *cell,RgInfCmnBoRpt  *boUpdt)
8451 {
8452
8453    uint32_t crntTimeInSubFrms = 0;
8454    uint32_t boUpdTimeInSubFrms = 0;
8455    uint32_t distance = 0;
8456
8457    crntTimeInSubFrms = (cell->crntTime.sfn * RGSCH_NUM_SUB_FRAMES_5G) +  cell->crntTime.slot +
8458            RG_SCH_CMN_DL_DELTA + 2;  /* As bo received will scheduled in next TTI
8459                                         so incrementing with +1 more */
8460    boUpdTimeInSubFrms = (boUpdt->u.timeToTx.sfn * RGSCH_NUM_SUB_FRAMES_5G)+ boUpdt->u.timeToTx.slot;
8461
8462
8463    distance = boUpdTimeInSubFrms > crntTimeInSubFrms ? \
8464               boUpdTimeInSubFrms - crntTimeInSubFrms : \
8465               (RGSCH_MAX_SUBFRM_5G - crntTimeInSubFrms + boUpdTimeInSubFrms);
8466
8467    if (distance > RGSCH_PCCHBCCH_WIN)
8468    {
8469            return RFAILED;
8470    }
8471    return ROK;
8472
8473 }/*rgSCHChkBoUpdate*/
8474
8475
8476 #ifdef LTE_TDD
8477 /**
8478  * @brief  Utility function to calculate the UL reTxIdx in TDD cfg0
8479  *
8480  * @details
8481  *
8482  *     Function : rgSchUtlCfg0ReTxIdx
8483  *
8484  *     Update the reTxIdx according to the rules mentioned
8485  *     in 3GPP TS 36.213 section 8 for TDD Cfg0
8486  *
8487  *  @param[in]  RgSchCellCb     *cell
8488  *  @param[in]  CmLteTimingInfo  phichTime 
8489  *  @param[in]  uint8_t               hqFdbkIdx
8490  *  @return     uint8_t
8491  **/
8492 uint8_t rgSchUtlCfg0ReTxIdx(RgSchCellCb    *cell,CmLteTimingInfo phichTime,uint8_t hqFdbkIdx)
8493 {
8494    uint8_t reTxIdx = RGSCH_INVALID_INFO;
8495    uint8_t iPhich = 0; 
8496    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
8497    RgSchUlSf       *ulSf;   
8498    uint8_t               ulSF; /* UL SF in the TDD frame */
8499          
8500    ulSf = &cellUl->ulSfArr[hqFdbkIdx];
8501    ulSF = ulSf->ulSfIdx;
8502     
8503    /* Check for the UL SF 4 or 9 */
8504    if(ulSF == 9 || ulSF == 4)
8505    {
8506      iPhich = 1;  
8507    }
8508    if(phichTime.slot == 0 || phichTime.slot == 5)
8509    {    
8510       if(iPhich == 0)
8511       {
8512          /* Retx will happen according to the Pusch k table */
8513          reTxIdx = cellUl->schdIdx;
8514       }
8515       if(iPhich == 1)
8516       {
8517          /* Retx will happen at n+7 */
8518          RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
8519          /* Fetch the corresponding  UL slot Idx in UL sf array */ 
8520          reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
8521       }   
8522    }
8523    else if(phichTime.slot == 1 || phichTime.slot == 6) 
8524    { 
8525       /* Retx will happen at n+7 */
8526       RGSCHCMNADDTOCRNTTIME(phichTime, phichTime, 7);
8527       /* Fetch the corresponding  UL slot Idx in UL sf array */ 
8528       reTxIdx = rgSCHCmnGetUlSfIdx(&phichTime, cell);
8529    }
8530    return (reTxIdx);
8531 }
8532 #endif
8533
8534 /**
8535  * @brief  Utility function to calculate total num of PRBs required to
8536  *         satisfy DL BO for TM1/TM2/TM6/TM7
8537  *
8538  * @details
8539  *
8540  *     Function : rgSchUtlDlCalc1CwPrb
8541  *
8542  *    Calculate PRBs required for UE to satisfy BO in DL
8543  *   
8544  *    Note : Total calculated PRBs will be assigned to *prbReqrd
8545  *    
8546  *
8547  *  @param[in]  RgSchCellCb     *cell
8548  *  @param[in]  RgSchUeCb       *ue 
8549  *  @param[in]  uint32_t              bo 
8550  *  @param[out] uint32_t             *prbReqrd 
8551  *  @return Void
8552  **/
8553 Void rgSchUtlDlCalc1CwPrb(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t bo,uint32_t  *prbReqrd)
8554 {
8555    RgSchCmnDlCell *dlCell  = RG_SCH_CMN_GET_DL_CELL(cell); 
8556    RgSchCmnDlUe   *dlUe  = RG_SCH_CMN_GET_DL_UE(ue, cell); 
8557    uint32_t       eff;
8558    uint32_t       noRes;
8559    uint8_t        iTbs;
8560    uint8_t        cfi = dlCell->currCfi;               
8561
8562    iTbs  = dlUe->mimoInfo.cwInfo[0].iTbs[0];
8563    eff   = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs];
8564
8565    /* Optimization to convert totalBo (which is in-terms of bytes) to bits 
8566     * i.e, << 3 and multiply with 1024 i.e, << 10 */
8567    noRes = ((uint64_t)((bo << 3) << 10)) / (eff);
8568    /* Get the number of RBs needed for this transmission */
8569    /* Number of RBs = No of REs / No of REs per RB       */
8570    *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
8571
8572    return;
8573 } /* rgSchUtlDlCalc1CwPrb*/
8574
8575 /**
8576  * @brief  Utility function to calculate total num of PRBs required to
8577  *         satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
8578  *         for TM3/TM4
8579  *
8580  * @details
8581  *
8582  *     Function : rgSchUtlDlCalc2CwPrb
8583  *
8584  *    Calculate PRBs required for UE to satisfy BO in DL
8585  *   
8586  *    Note : Total calculated PRBs will be assigned to *prbReqrd
8587  *    
8588  *
8589  *  @param[in]  RgSchCellCb     *cell
8590  *  @param[in]  RgSchUeCb       *ue 
8591  *  @param[in]  uint32_t              bo 
8592  *  @param[out] uint32_t             *prbReqrd 
8593  *  @return Void
8594  **/
8595 Void rgSchUtlDlCalc2CwPrb(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t bo,uint32_t *prbReqrd)
8596 {
8597    RgSchCmnDlCell *dlCell  = RG_SCH_CMN_GET_DL_CELL(cell); 
8598    RgSchCmnDlUe   *dlUe  = RG_SCH_CMN_GET_DL_UE(ue, cell); 
8599    uint32_t            eff1, eff2;
8600    uint32_t            noRes;
8601    uint8_t             noLyr1, noLyr2;
8602    uint8_t             iTbs1, iTbs2;
8603    uint8_t             cfi = dlCell->currCfi;               
8604
8605    if ((dlUe->mimoInfo.forceTD) ||/* Transmit Diversity (TD) */
8606        (dlUe->mimoInfo.ri < 2))/* 1 layer precoding */
8607    {
8608       iTbs1  = dlUe->mimoInfo.cwInfo[0].iTbs[0];
8609       eff1   = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[0][cfi]))[iTbs1];
8610
8611       /* Optimization to convert totalBo (which is in-terms of bytes) to bits 
8612        * i.e, << 3 and multiply with 1024 i.e, << 10 */
8613       noRes = ((uint64_t)((bo << 3) << 10)) / (eff1);
8614       /* Get the number of RBs needed for this transmission */
8615       /* Number of RBs = No of REs / No of REs per RB       */
8616       *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
8617    }
8618    else
8619    {
8620       noLyr1 = dlUe->mimoInfo.cwInfo[0].noLyr;
8621       noLyr2 = dlUe->mimoInfo.cwInfo[1].noLyr;
8622       iTbs1  = dlUe->mimoInfo.cwInfo[0].iTbs[noLyr1 - 1];
8623       iTbs2  = dlUe->mimoInfo.cwInfo[1].iTbs[noLyr2 - 1];
8624       eff1 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr1 - 1][cfi]))[iTbs1];
8625       eff2 = (*(RgSchCmnTbSzEff *)(dlCell->cqiToEffTbl[noLyr2 - 1][cfi]))[iTbs2];
8626
8627       /* Optimization to convert totalBo (which is in-terms of bytes) to bits 
8628        * i.e, << 3 and multiply with 1024 i.e, << 10 */
8629       noRes = ((uint64_t)((bo << 3) << 10)) / (eff1 + eff2);
8630       /* Get the number of RBs needed for this transmission */
8631       /* Number of RBs = No of REs / No of REs per RB       */
8632       *prbReqrd = RGSCH_CEIL(noRes, dlCell->noResPerRb[cfi]);
8633    }
8634    return;
8635 } /* rgSchUtlDlCalc2CwPrb */
8636
8637 /**
8638  * @brief  Utility function to calculate total num of PRBs required to
8639  *         satisfy DL BO(BO sum of all logical channels for that UE or an LC BO)
8640  *
8641  * @details
8642  *
8643  *     Function : rgSchUtlCalcTotalPrbReq
8644  *
8645  *    This function calls TM specific routine to calculate PRB
8646  *   
8647  *
8648  *  @param[in]  RgSchCellCb     *cell
8649  *  @param[in]  RgSchUeCb       *ue 
8650  *  @param[in]  uint32_t              bo 
8651  *  @param[out] uint32_t             *prbReqrd 
8652  *  @return Void
8653  **/
8654 Void rgSchUtlCalcTotalPrbReq(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t bo,uint32_t *prbReqrd)
8655 {
8656    /* Call TM specific Prb calculation routine */
8657    (dlCalcPrbFunc[ue->mimoInfo.txMode - 1])(cell, ue, bo, prbReqrd);
8658
8659    return;
8660 } /* rgSchUtlCalcTotalPrbReq */
8661 #ifdef UNUSE_FUN
8662 #ifdef TFU_UPGRADE
8663 /***********************************************************
8664  *
8665  *     Func : rgSCHUtlFetchPcqiBitSz
8666  *
8667  *
8668  *     Desc : Fetch the CQI/PMI bits for a UE based on the mode, periodicity.
8669  *
8670  *     Ret  : uint8_t
8671  *            ROK - Success
8672  *
8673  *     Notes:
8674  *
8675  *     File :
8676  *
8677  **********************************************************/
8678 static uint8_t rgSCHUtlFetchPcqiBitSz(RgSchCellCb *cell, RgSchUeCb *ueCb,uint8_t numTxAnt)
8679 {
8680    uint8_t   confRepMode;
8681    uint8_t   pcqiSz;
8682    uint8_t   ri;
8683    RgSchUePCqiCb *cqiCb = RG_SCH_GET_UE_CELL_CQI_CB(ueCb,cell);
8684
8685    confRepMode = cqiCb->cqiCfg.cqiSetup.prdModeEnum;
8686    if((ueCb->mimoInfo.txMode != RGR_UE_TM_3) && 
8687          (ueCb->mimoInfo.txMode != RGR_UE_TM_4))
8688    {
8689       ri =1;
8690    }
8691    else
8692    {
8693       ri = cqiCb->perRiVal;
8694    }
8695    switch(confRepMode)
8696    {
8697       case RGR_PRD_CQI_MOD10:
8698       {
8699          pcqiSz = 4;
8700       }
8701       break;
8702
8703       case RGR_PRD_CQI_MOD11:
8704       {
8705          if(numTxAnt == 2)
8706          {
8707             if (ri ==1)
8708             {
8709                pcqiSz = 6;
8710             }
8711             else
8712             {
8713                pcqiSz = 8;
8714             }
8715          }
8716          else if(numTxAnt == 4)
8717          {
8718             if (ri ==1)
8719             {
8720                pcqiSz = 8;
8721             }
8722             else
8723             {
8724                pcqiSz = 11;
8725             }
8726          }
8727          else
8728          {
8729             /* This is number of antenna case 1.
8730              * This is not applicable for Mode 1-1. 
8731              * So setting it to invalid value */
8732             pcqiSz = 0;
8733          }
8734       }
8735       break;
8736
8737       case RGR_PRD_CQI_MOD20:
8738       {
8739          if(cqiCb->isWb)
8740          {
8741             pcqiSz = 4;
8742          }
8743          else
8744          {
8745             pcqiSz = 4 + cqiCb->label;
8746          }
8747       }
8748       break;
8749
8750       case RGR_PRD_CQI_MOD21:
8751       {
8752          if(cqiCb->isWb)
8753          {
8754              if(numTxAnt == 2)
8755              {
8756                 if (ri ==1)
8757                 {
8758                     pcqiSz = 6;
8759                 }
8760                 else
8761                 {
8762                     pcqiSz = 8;
8763                 }
8764              }
8765              else if(numTxAnt == 4)
8766              {
8767                 if (ri ==1)
8768                 {
8769                     pcqiSz = 8;
8770                 }
8771                 else
8772                 {
8773                     pcqiSz = 11;
8774                 }
8775              }
8776              else
8777              {
8778                 /* This might be number of antenna case 1.
8779                  * For mode 2-1 wideband case only antenna port 2 or 4 is supported.
8780                  * So setting invalid value.*/
8781                 pcqiSz = 0;
8782              }
8783           }
8784           else
8785           {
8786              if (ri ==1)
8787              {
8788                  pcqiSz = 4 + cqiCb->label;
8789              }
8790              else
8791              {
8792                  pcqiSz = 7 + cqiCb->label;
8793              }
8794           }
8795       }
8796       break;
8797
8798       default:
8799          pcqiSz = 0;
8800       break;
8801    }
8802    
8803    return (pcqiSz);
8804 }
8805 #endif
8806 #endif
8807 /**
8808  * @brief  Utility function to returns the number of subbands based on the 
8809  *         requested bytes.
8810  *
8811  * @details
8812  *
8813  *     Function : rgSchUtlGetNumSbs
8814  *
8815  *     Calculate the number of PRBs
8816  *     Update the subbandRequired based on the nPrbs and subband size
8817  *
8818  *  @param[in]  RgSchCellCb  *cell
8819  *  @param[in]  RgSchUeCb    *ue
8820  *  @param[in]  uint32_t          *numSbs
8821  *  @return     uint8_t
8822  **/
8823 uint8_t rgSchUtlGetNumSbs(RgSchCellCb *cell,RgSchUeCb *ue,uint32_t *numSbs)
8824 {
8825    uint32_t  nPrb;
8826    //Currently hardcoding MAX prb for each UE
8827    nPrb = ue->ue5gtfCb.maxPrb;
8828    (*numSbs) = RGSCH_CEIL(nPrb, MAX_5GTF_VRBG_SIZE);
8829    return ROK;
8830 }
8831
8832 /**
8833  * @brief  Utility function to insert the UE node into UE Lst based on the
8834  *         number of subbands allocated for the UE for the current TTI.
8835  *
8836  * @details
8837  *
8838  *     Function : rgSchUtlSortInsUeLst
8839  *
8840  *     If subbandRequired < Min, then insert at head
8841  *     Else If subbandRequired > Max, then insert at tail
8842  *     Else, traverse the list and place the node at the appropriate place
8843  *
8844  *  @param[in]  RgSchCellCb  *cell
8845  *  @param[in]  RgSchUeCb    *ue
8846  *  @return     uint8_t
8847  **/
8848 uint8_t rgSchUtlSortInsUeLst(RgSchCellCb *cell,CmLListCp *ueLst,CmLList *node,uint8_t vrbgRequired)
8849 {
8850    CmLList      *ueInLst;
8851    CmLList      *firstUeInLst;
8852    CmLList      *lastUeInLst;
8853    RgSchUeCb    *tempUe;
8854    RgSchCmnUlUe *ueUl;
8855
8856    //firstUeInLst = cmLListFirst(ueLst);
8857    CM_LLIST_FIRST_NODE(ueLst,firstUeInLst);
8858    if(NULLP == firstUeInLst)
8859    {
8860       /* first node to be added to the list */
8861       cmLListAdd2Tail(ueLst, node);
8862    }
8863    else
8864    {
8865       /* Sb Required for the UE is less than the first node in the list */
8866       tempUe      = (RgSchUeCb *)(firstUeInLst->node);
8867       ueUl = RG_SCH_CMN_GET_UL_UE(tempUe, cell);
8868
8869       if(vrbgRequired <= ueUl->vrbgRequired)
8870       {
8871          cmLListInsCrnt(ueLst, (node));
8872       }
8873       else
8874       {
8875          /* Sb Required for this UE is higher than the UEs in the list */
8876          lastUeInLst = cmLListLast(ueLst);
8877          tempUe      = (RgSchUeCb *)(lastUeInLst->node);
8878          if(vrbgRequired >= ueUl->vrbgRequired)
8879          {
8880             cmLListAdd2Tail(ueLst, (node));
8881          }
8882          else
8883          {
8884             /* This UE needs to be in the middle. Search and insert the UE */
8885             ueInLst = cmLListFirst(ueLst);
8886             do
8887             {
8888                tempUe = (RgSchUeCb *)(ueInLst->node);
8889
8890                if(vrbgRequired <= ueUl->vrbgRequired)
8891                {
8892                   cmLListInsCrnt(ueLst, (node));
8893                   break;
8894                }
8895
8896                ueInLst = cmLListNext(ueLst);
8897
8898             } while(NULLP != ueInLst && ueInLst != firstUeInLst);
8899          }
8900       }
8901    }
8902
8903    return ROK;
8904 }
8905
8906 /**
8907  * @brief Function to Send LCG GBR register to MAC
8908  *
8909  * @details
8910  *
8911  *     Function: rgSCHUtlBuildNSendLcgReg
8912  *
8913  *     Handler for sending LCG GBR registration 
8914  *
8915  *     Invoked by: 
8916  *         SCHD
8917  *
8918  *     Processing Steps:
8919  *           
8920  *  @param[in] RgSchCellCb       *cell
8921  *  @param[in] CmLteRnti         crnti
8922  *  @param[in] uint8_t                lcgId
8923  *  @param[in] Bool              isGbr
8924  *  @return  S16
8925  *      -# ROK 
8926  **/
8927 S16 rgSCHUtlBuildNSendLcgReg(RgSchCellCb  *cell,CmLteRnti  crnti,uint8_t lcgId,Bool isGbr)
8928 {
8929    Pst            pst;
8930    RgInfLcgRegReq lcgRegReq;
8931
8932    memset(&pst, 0, sizeof(Pst));
8933    lcgRegReq.isGbr  = isGbr;
8934    lcgRegReq.cellId = cell->cellId;
8935    lcgRegReq.crnti  = crnti;
8936    lcgRegReq.lcgId  = lcgId;
8937    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
8938    /* code Coverage portion of the test case */ 
8939    RgSchMacLcgReg(&pst, &lcgRegReq);
8940
8941    return ROK;
8942 }
8943
8944 #ifdef TFU_UPGRADE
8945 #ifdef LTE_ADV
8946 #ifndef TFU_TDD
8947 /**
8948  * @brief Function to map RGR pucch type to TFU type
8949  *
8950  * @details
8951  *
8952  *     Function: rgSchUtlGetFdbkMode
8953  *
8954  *
8955  *     Invoked by: 
8956  *         SCHD
8957  *
8958  *     Processing Steps:
8959  *           
8960  *  @param[in] RgrSchFrmt1b3TypEnum
8961  *  @return  TfuAckNackMode
8962  *      -# ROK 
8963  **/
8964 TfuAckNackMode rgSchUtlGetFdbkMode(RgrSchFrmt1b3TypEnum fdbkType)
8965 {
8966
8967    TfuAckNackMode mode = TFU_UCI_FORMAT_1A_1B;
8968
8969    switch(fdbkType)
8970    {
8971      case RG_SCH_UCI_FORMAT_NON_CA:
8972      case RG_SCH_UCI_FORMAT1A_1B:
8973      {
8974         mode = TFU_UCI_FORMAT_1A_1B;
8975      }
8976      break;
8977      case RG_SCH_UCI_FORMAT1B_CS:
8978      {
8979         mode = TFU_UCI_FORMAT_1B_CS;
8980      }
8981      break;
8982      case RG_SCH_UCI_FORMAT3:
8983      {
8984         mode = TFU_UCI_FORMAT_3;
8985      }
8986      break;
8987    }
8988    return (mode);
8989 }
8990 #endif /* TFU_TDD */
8991 #endif /* LTE_ADV */
8992 #endif /*TFU_UPGRADE */
8993
8994 #ifdef LTE_ADV
8995 /**
8996  * @brief Send Ue SCell delete to SMAC.
8997  *
8998  * @details
8999  *
9000  *     Function : rgSCHUtlSndUeSCellDel2Mac 
9001  *       This function populates the struct RgInfRlsRnti and
9002  *       get the pst for SMac and mark field isUeSCellDel to TRUE which 
9003  *       indicates that it is a Ue SCell delete.
9004  *     
9005  *    
9006  *           
9007  *  @param[in]     RgSchCellCb    *cell
9008  *  @param[in]     CmLteRnti      rnti 
9009  *  @return  Void
9010  *      -# ROK 
9011  **/
9012 Void rgSCHUtlSndUeSCellDel2Mac(RgSchCellCb *cell,CmLteRnti rnti)
9013 {
9014    Pst          pst;
9015    Inst         inst = cell->instIdx;
9016    RgInfRlsRnti rntiInfo;
9017
9018    DU_LOG("\nINFO  -->  SCH : RNTI Release IND for UE(%d)\n", rnti);
9019    /* Copy the info to rntiInfo */
9020    rntiInfo.cellId = cell->cellId;
9021    rntiInfo.rnti   = rnti;
9022    /* Fix : syed ueId change as part of reestablishment.
9023     * Now SCH to trigger this. CRG ueRecfg for ueId change 
9024     * is dummy */          
9025    rntiInfo.ueIdChng = FALSE;
9026    rntiInfo.newRnti  = rnti;
9027    rntiInfo.isUeSCellDel = TRUE;
9028    /* Invoke MAC to release the rnti */
9029    rgSCHUtlGetPstToLyr(&pst, &rgSchCb[inst], cell->macInst);
9030    RgSchMacRlsRnti(&pst, &rntiInfo);
9031    return;
9032 }
9033
9034 /**
9035  * @brief Returns max TB supported by a given txMode
9036  *
9037  * @details
9038  *
9039  *     Function : rgSCHUtlGetMaxTbSupp
9040  *     Max TB supported for TM Modes (1,2,5,6 and 7) is 1
9041  *     and 2 for others
9042  *    
9043  *           
9044  *  @param[in]     RgrTxMode  txMode
9045  *  @return        uint8_t maxTbCount; 
9046  *      -# ROK 
9047  **/
9048 uint8_t rgSCHUtlGetMaxTbSupp(RgrTxMode txMode)
9049 {
9050    uint8_t maxTbCount;
9051
9052    /* Primary Cell */
9053
9054    switch(txMode)
9055    {
9056       case RGR_UE_TM_1:
9057       case RGR_UE_TM_2:
9058       case RGR_UE_TM_5:
9059       case RGR_UE_TM_6:
9060       case RGR_UE_TM_7:
9061          maxTbCount = 1;
9062          break;
9063       case RGR_UE_TM_3:
9064       case RGR_UE_TM_4:
9065       case RGR_UE_TM_8:
9066       case RGR_UE_TM_9:
9067          maxTbCount = 2;
9068          break;
9069       default:
9070          maxTbCount = 0;
9071          break;
9072    }
9073
9074    return (maxTbCount);
9075 }
9076
9077 /**
9078  * @brief Send Ue SCell delete to SMAC.
9079  *
9080  * @details
9081  *
9082  *     Function : rgSCHTomUtlGetTrigSet 
9083  *      This function gets the triggerset based on cqiReq 
9084  *     
9085  *  @param[in]     RgSchCellCb    *cell
9086  *  @param[in]     RgSchUeCb      ueCb 
9087  *  @param[in]     uint8_t             cqiReq,
9088  *  @param[out]    uint8_t             *triggerSet
9089  *
9090  *  @return  Void
9091  *      -# ROK 
9092  **/
9093 Void rgSCHTomUtlGetTrigSet(RgSchCellCb *cell,RgSchUeCb  *ueCb,uint8_t cqiReq,uint8_t *triggerSet)
9094 {
9095    RgSchUeCellInfo *pCellInfo = RG_SCH_CMN_GET_PCELL_INFO(ueCb);
9096    switch(cqiReq)
9097    {
9098       case RG_SCH_APCQI_SERVING_CC:
9099          {
9100             /* APeriodic CQI request for Current Carrier.*/
9101             uint8_t sCellIdx = ueCb->cellIdToCellIdxMap[RG_SCH_CELLINDEX(cell)];
9102             *triggerSet = 1 << (7 - sCellIdx);
9103             break;
9104          }
9105       case RG_SCH_APCQI_1ST_SERVING_CCS_SET:
9106          {
9107             *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet1;
9108             break;
9109          }
9110       case RG_SCH_APCQI_2ND_SERVING_CCS_SET:
9111          {
9112             *triggerSet = pCellInfo->acqiCb.aCqiCfg.triggerSet2;
9113             break;
9114          }
9115       default:
9116          {
9117             /* BUG */
9118             break;
9119          }
9120    }
9121    return;
9122 }
9123 #endif
9124 /**
9125  * @brief This function updates the value of UE specific DCI sizes
9126  *
9127  * @details
9128  *
9129  *     Function: rgSCHUtlUpdUeDciSize
9130  *     Purpose:  This function calculates and updates DCI Sizes in bits.
9131  *
9132  *     Invoked by: Scheduler
9133  *
9134  *  @param[in]  RgSchCellCb       *cell
9135  *  @param[in]  RgSchUeCb         *ueCb
9136  *  @param[in]  isCsi2Bit         *isCsi2Bit: is 1 bit or 2 bit CSI
9137  *  @return     Void
9138  *
9139  **/
9140 Void rgSCHUtlUpdUeDciSize(RgSchCellCb *cell,RgSchUeCb *ueCb,Bool isCsi2Bit)
9141 {
9142    uint8_t dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
9143    uint8_t dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0];
9144    if ((ueCb->accessStratumRls >= RGR_REL_10) && (cell->bwCfg.dlTotalBw >= cell->bwCfg.ulTotalBw))
9145    {
9146       dci01aCmnSize += 1; /* Resource Allocation Type DCI 0 */
9147       dci01aDedSize += 1; /* Resource Allocation Type DCI 0 */
9148    }
9149    if (isCsi2Bit == TRUE)
9150    {
9151       dci01aDedSize += 2; /* 2 bit CSI DCI 0 */
9152    }
9153    else
9154    {
9155       dci01aDedSize += 1; /* 1 bit CSI DCI 0 */
9156    }
9157    
9158    /* Common CSI is always 1 bit DCI 0 */
9159    dci01aCmnSize += 1; /* 1 bit CSI DCI 0 */
9160
9161    /* Compare the sizes of DCI 0 with DCI 1A and consider the greater */
9162    if (dci01aCmnSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
9163    {
9164       dci01aCmnSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
9165    }
9166    if (dci01aDedSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
9167    {
9168       dci01aDedSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
9169    }
9170
9171    /* 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 */
9172    dci01aCmnSize += rgSchDciAmbigSizeTbl[dci01aCmnSize];
9173    dci01aDedSize += rgSchDciAmbigSizeTbl[dci01aDedSize];
9174
9175    ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_0]  = dci01aCmnSize;
9176    ueCb->dciSize.cmnSize[TFU_DCI_FORMAT_1A] = dci01aCmnSize;
9177    
9178    ueCb->dciSize.dedSize[TFU_DCI_FORMAT_0]  = dci01aDedSize;
9179    ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A] = dci01aDedSize;
9180
9181    ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
9182    do {
9183       /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled 
9184        * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A 
9185        * for scheduling the same serving cell and mapped onto the UE specific search space given by the 
9186        * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
9187       if (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A])
9188       {
9189          ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += 1;
9190       }
9191
9192       /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs 
9193        * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended 
9194        * to format 1 until the payload size of format 1 does not belong to one of the sizes in 
9195        * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
9196       ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1]];
9197    } while (ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.dedSize[TFU_DCI_FORMAT_1A]);
9198
9199    /* Just copying the value of 2/2A to avoid multiple checks at PDCCH allocations. This values never change.*/
9200    ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2]  = cell->dciSize.size[TFU_DCI_FORMAT_2];
9201    ueCb->dciSize.dedSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
9202    ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2]  = cell->dciSize.size[TFU_DCI_FORMAT_2];
9203    ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_2A] = cell->dciSize.size[TFU_DCI_FORMAT_2A];
9204
9205    /* Spec 36.212-a80 Sec 5.3.3.1.3: except when format 1A assigns downlink resource 
9206     * on a secondary cell without an uplink configuration associated with the secondary cell */
9207    ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
9208    ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]];
9209    ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] = cell->dciSize.baseSize[TFU_DCI_FORMAT_1];
9210    do {
9211       /* Spec 36.212-a80 Sec 5.3.3.1.2: If the UE is configured to decode PDCCH with CRC scrambled 
9212        * by the C-RNTI and the number of information bits in format 1 is equal to that for format 0/1A 
9213        * for scheduling the same serving cell and mapped onto the UE specific search space given by the 
9214        * C-RNTI as defined in [3], one bit of value zero shall be appended to format 1. */
9215       if (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A])
9216       {
9217          ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += 1;
9218       }
9219
9220       /* Spec 36.212-a80 Sec 5.3.3.1.2: If the number of information bits in format 1 belongs 
9221        * to one of the sizes in Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended 
9222        * to format 1 until the payload size of format 1 does not belong to one of the sizes in 
9223        * Table 5.3.3.1.2-1 and is not equal to that of format 0/1A mapped onto the same search space. */
9224       ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1]];
9225    } while (ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1] == ueCb->dciSize.noUlCcSize[TFU_DCI_FORMAT_1A]);
9226 #ifdef EMTC_ENABLE
9227    rgSCHEmtcUtlUpdUeDciSize(cell, ueCb); 
9228 #endif      
9229 }
9230
9231 /**
9232  * @brief This function initialises the DCI Size table
9233  *
9234  * @details
9235  *
9236  *     Function: rgSCHUtlCalcDciSizes
9237  *     Purpose:  This function calculates and initialises DCI Sizes in bits.
9238  *
9239  *     Invoked by: Scheduler
9240  *
9241  *  @param[in]  RgSchCellCb       *cell
9242  *  @return     Void
9243  *
9244  **/
9245 Void rgSCHUtlCalcDciSizes(RgSchCellCb *cell)
9246 {
9247    uint8_t dciSize = 0;
9248    uint8_t dci01aSize = 0;
9249    uint32_t bits = 0, idx = 0;
9250
9251    switch(TFU_DCI_FORMAT_0) /* Switch case for the purpose of readability */
9252    {
9253       case TFU_DCI_FORMAT_0:
9254          {
9255             /* DCI 0: Spec 36.212 Section 5.3.3.1.1 */
9256             dciSize = 0;
9257             /*-- Calculate resource block assignment bits need to be set
9258               Which is ln(N(N+1)/2) 36.212 5.3.3.1 --*/
9259             bits = (cell->bwCfg.ulTotalBw * (cell->bwCfg.ulTotalBw + 1) / 2);
9260             while ((bits & 0x8000) == 0)
9261             {
9262                bits <<= 1;
9263                idx++;
9264             }
9265             bits = 16 - idx;
9266
9267             dciSize = 1 /* DCI 0 bit indicator */ + \
9268                       1 /* Frequency hoping enable bit field */ + \
9269                       (uint8_t)bits /* For frequency Hopping */ + \
9270                       5 /* MCS */ + \
9271                       1 /* NDI */ + \
9272                       2 /* TPC */ + \
9273                       3 /* DMRS */
9274 #ifdef TFU_TDD
9275                       + \
9276                       2 /* UL Index Config 0 or DAI Config 1-6 */
9277 #endif
9278                       ;
9279
9280             cell->dciSize.baseSize[TFU_DCI_FORMAT_0] = dciSize;
9281
9282             /* If hoping flag is enabled */
9283             if (cell->bwCfg.ulTotalBw <= 49) /* Spec 36.213 Table 8.4-1, N UL_hop, if hopping is enabled */
9284             {
9285                cell->dciSize.dci0HopSize = 1;
9286             }
9287             else
9288             {
9289                cell->dciSize.dci0HopSize = 2;
9290             }
9291
9292             /* Update common non-CRNTI scrambled DCI 0/1A flag */
9293             dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_0] + 1; /* 1 bit CSI */
9294          }
9295       case TFU_DCI_FORMAT_1A:
9296          {
9297             /* DCI 1A: Spec 36.212 Section 5.3.3.1.3 */
9298             dciSize = 0;
9299             idx = 0;
9300             /* Calculate resource block assignment bits need to be set
9301               Which is ln(N(N+1)/2) */
9302             bits = (cell->bwCfg.dlTotalBw * (cell->bwCfg.dlTotalBw + 1) / 2);
9303             while ((bits & 0x8000) == 0)
9304             {
9305                bits <<= 1;
9306                idx++;
9307             }
9308             bits = 16 - idx;
9309
9310             dciSize += 1 /* Format 1A */ + \
9311                        1 /* Local or Distributed */ + \
9312                        (uint8_t)bits /* Resource block Assignment */ + \
9313                        5 /* MCS */ + 
9314 #ifdef TFU_TDD
9315                        4 /* HARQ Proc Id */ + 
9316 #else
9317                        3 /* HARQ Proc Id */ + 
9318 #endif
9319                        1 /* NDI */ + \
9320                        2 /* RV */ + \
9321                        2 /* TPC CMD */
9322 #ifdef TFU_TDD
9323                        + \
9324                        2 /* DAI */
9325 #endif
9326                        ;
9327             cell->dciSize.baseSize[TFU_DCI_FORMAT_1A] = dciSize;
9328
9329             /* If the UE is not configured to decode PDCCH with CRC scrambled by the C-RNTI, 
9330              * and the number of information bits in format 1A is less than that of format 0, 
9331              * zeros shall be appended to format 1A until the payload size equals that of format 0. */
9332             /* Compare the size with DCI 1A  and DCI 0 and consider the greater one */
9333             if (dci01aSize < cell->dciSize.baseSize[TFU_DCI_FORMAT_1A])
9334             {
9335                dci01aSize = cell->dciSize.baseSize[TFU_DCI_FORMAT_1A];
9336             }
9337             /* If the number of information bits in format 1A belongs to one of the sizes in 
9338              * Table 5.3.3.1.2-1, one zero bit shall be appended to format 1A. */
9339             dci01aSize += rgSchDciAmbigSizeTbl[dci01aSize];
9340             cell->dciSize.size[TFU_DCI_FORMAT_1A] = cell->dciSize.size[TFU_DCI_FORMAT_0] = dci01aSize;
9341          }
9342       case TFU_DCI_FORMAT_1:
9343          {
9344             /* DCI 1: Spec 36.212 Section 5.3.3.1.2 */
9345             dciSize = 0;
9346             if (cell->bwCfg.dlTotalBw > 10)
9347             {
9348                dciSize = 1; /* Resource Allocation header bit */
9349             }
9350             
9351             /* Resouce allocation bits Type 0 and Type 1 */
9352             bits = (cell->bwCfg.dlTotalBw/cell->rbgSize);
9353             if ((cell->bwCfg.dlTotalBw % cell->rbgSize) != 0)
9354             {
9355                bits++;
9356             }
9357
9358             dciSize += (uint8_t)bits /* Resource Allocation bits */ + \
9359                        5 /* MCS */ + 
9360 #ifdef TFU_TDD
9361                        4 /* HARQ TDD */ + 
9362 #else
9363                        3 /* HARQ FDD */ + 
9364 #endif
9365                        1 /* NDI */ + \
9366                        2 /* Redunancy Version */ + \
9367                        2 /* TPC Cmd */
9368 #ifdef TFU_TDD
9369                        + \
9370                        2 /* DAI */
9371 #endif
9372                        ;
9373
9374             
9375             cell->dciSize.baseSize[TFU_DCI_FORMAT_1] = dciSize;
9376
9377             cell->dciSize.size[TFU_DCI_FORMAT_1] = dciSize;
9378             
9379             do {
9380                /* If the UE is not configured to decode PDCCH with CRC 
9381                 * scrambled by the C-RNTI and the number of information bits in format 1 
9382                 * is equal to that for format 0/1A, one bit of value zero shall be appended 
9383                 * to format 1. */
9384                if (dci01aSize == cell->dciSize.size[TFU_DCI_FORMAT_1])
9385                {
9386                   cell->dciSize.size[TFU_DCI_FORMAT_1] += 1;
9387                }
9388
9389                /* If the number of information bits in format 1 belongs to one of the sizes in 
9390                 * Table 5.3.3.1.2-1, one or more zero bit(s) shall be appended to format 1 until 
9391                 * the payload size of format 1 does not belong to one of the sizes in Table 5.3.3.1.2-1 
9392                 * and is not equal to that of format 0/1A mapped onto the same search space. */
9393                cell->dciSize.size[TFU_DCI_FORMAT_1] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_1]];
9394             } while (cell->dciSize.size[TFU_DCI_FORMAT_1] == dci01aSize);
9395          }
9396       case TFU_DCI_FORMAT_2:
9397          {
9398             /* DCI 2: Spec 36.212 Section 5.3.3.1.5 */
9399             dciSize = 0;
9400             if (cell->bwCfg.dlTotalBw > 10)
9401             {
9402                dciSize = 1; /* Resource Allocation bit */
9403             }
9404
9405             dciSize += (uint8_t)bits /* Resource Allocation bits */ + \
9406                        2 /* TPC */ + 
9407 #ifdef TFU_TDD
9408                        2 /* DAI */ + \
9409                        4 /* HARQ */ + 
9410 #else
9411                        3 /* HARQ */ +
9412 #endif
9413                        1 /* CW Swap Flag */ + \
9414                        5 /* MCS for TB1 */+ \
9415                        1 /* NDI for TB1 */+ \
9416                        2 /* RV for TB1 */ + \
9417                        5 /* MCS for TB2 */+ \
9418                        1 /* NDI for TB2 */+ \
9419                        2 /* RV for TB2 */;
9420             if (cell->numTxAntPorts == 2)
9421             {
9422                dciSize += 3;
9423             }
9424             else if (cell->numTxAntPorts == 4)
9425             {
9426                dciSize += 6;
9427             }
9428             cell->dciSize.size[TFU_DCI_FORMAT_2] = dciSize;
9429             cell->dciSize.size[TFU_DCI_FORMAT_2] += rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2]];
9430          }
9431       case TFU_DCI_FORMAT_2A:
9432          {
9433             /* DCI 2A: Spec 36.212 Section 5.3.3.1.5A */
9434             dciSize = 0;
9435             if (cell->bwCfg.dlTotalBw > 10)
9436             {
9437                dciSize = 1; /* Resource Allocation bit */
9438             }
9439
9440             dciSize += (uint8_t)bits /* Resource Allocation bits */ + \
9441                          2 /* TPC */ + 
9442 #ifdef TFU_TDD
9443                          2 /* DAI */ + \
9444                          4 /* HARQ */ + 
9445 #else
9446                          3 /* HARQ */ +
9447 #endif
9448                          1 /* CW Swap Flag */ + \
9449                          5 /* MCS for TB1 */+ \
9450                          1 /* NDI for TB1 */+ \
9451                          2 /* RV for TB1 */ + \
9452                          5 /* MCS for TB2 */+ \
9453                          1 /* NDI for TB2 */+ \
9454                          2 /* RV for TB2 */;
9455             if (cell->numTxAntPorts == 4)
9456             {
9457                dciSize += 2;
9458             }
9459             cell->dciSize.size[TFU_DCI_FORMAT_2A] = dciSize;
9460             cell->dciSize.size[TFU_DCI_FORMAT_2A] += \
9461                           rgSchDciAmbigSizeTbl[cell->dciSize.size[TFU_DCI_FORMAT_2A]]; /* Spec 39.212 Table 5.3.3.1.2-1 */
9462          }
9463       case TFU_DCI_FORMAT_3:
9464          {
9465             /* DCI 3: Spec 36.212 Section 5.3.3.1.6 */
9466             cell->dciSize.size[TFU_DCI_FORMAT_3] = cell->dciSize.size[TFU_DCI_FORMAT_1A] / 2;
9467             if (cell->dciSize.size[TFU_DCI_FORMAT_3] % 2)
9468             {
9469                cell->dciSize.size[TFU_DCI_FORMAT_3]++;
9470             }
9471          }
9472       case TFU_DCI_FORMAT_3A:
9473          {
9474             /* DCI 3A: Spec 36.212 Section 5.3.3.1.7 */
9475             cell->dciSize.size[TFU_DCI_FORMAT_3A] = cell->dciSize.size[TFU_DCI_FORMAT_1A];
9476          }
9477 #ifdef EMTC_ENABLE
9478       case TFU_DCI_FORMAT_6_0A:
9479          {
9480             rgSCHEmtcGetDciFrmt60ASize(cell);
9481          }
9482          case TFU_DCI_FORMAT_6_1A:
9483          {
9484             rgSCHEmtcGetDciFrmt61ASize(cell);
9485          }
9486 #endif                  
9487       default:
9488          {
9489             /* DCI format not supported */
9490             break;
9491          }
9492    }
9493 }
9494
9495 /**
9496  * @brief Handler for the CPU OvrLd related state adjustment.
9497  *
9498  * @details
9499  *
9500  *     Function : rgSCHUtlCpuOvrLdAdjItbsCap
9501  *
9502  *     Processing Steps:
9503  *      - Record dl/ulTpts 
9504  *      - Adjust maxItbs to acheive target throughputs
9505  *
9506  *  @param[in]  RgSchCellCb *cell
9507  *  @return  Void 
9508  **/
9509 Void rgSCHUtlCpuOvrLdAdjItbsCap( RgSchCellCb *cell)
9510 {
9511    uint32_t tptDelta;
9512
9513    if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_DL_TPT_UP | 
9514             RGR_CPU_OVRLD_DL_TPT_DOWN))
9515    {
9516       /* Regulate DL Tpt for CPU overload */
9517       if (cell->measurements.dlTpt > cell->cpuOvrLdCntrl.tgtDlTpt)
9518       {
9519          tptDelta = cell->measurements.dlTpt - cell->cpuOvrLdCntrl.tgtDlTpt;
9520          /* Upto 0.5% drift in measured vs target tpt is ignored */
9521          if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
9522          {
9523             cell->thresholds.maxDlItbs = RGSCH_MAX((cell->thresholds.maxDlItbs-1), 1);
9524          }
9525       }
9526       else
9527       {
9528          tptDelta = cell->cpuOvrLdCntrl.tgtDlTpt - cell->measurements.dlTpt;
9529          /* Upto 0.5% drift in measured vs target tpt is ignored */
9530          if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtDlTpt) > 5)
9531          {
9532             cell->thresholds.maxDlItbs = RGSCH_MIN((cell->thresholds.maxDlItbs+1), RG_SCH_DL_MAX_ITBS);
9533          }
9534       }
9535 #ifdef CPU_OL_DBG_PRINTS
9536       DU_LOG("\nINFO  -->  SCH :  DL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.dlTpt, cell->cpuOvrLdCntrl.tgtDlTpt, 
9537             cell->thresholds.maxDlItbs);
9538 #endif
9539    }
9540
9541    if ((cell->cpuOvrLdCntrl.cpuOvrLdIns) & (RGR_CPU_OVRLD_UL_TPT_UP | 
9542             RGR_CPU_OVRLD_UL_TPT_DOWN))
9543    {
9544       /* Regualte DL Tpt for CPU overload */
9545       if (cell->measurements.ulTpt > cell->cpuOvrLdCntrl.tgtUlTpt)
9546       {
9547          tptDelta = cell->measurements.ulTpt - cell->cpuOvrLdCntrl.tgtUlTpt;
9548          /* Upto 1% drift in measured vs target tpt is ignored */
9549          if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
9550          {
9551             cell->thresholds.maxUlItbs = RGSCH_MAX((cell->thresholds.maxUlItbs-1), 1);
9552          }
9553       }
9554       else
9555       {
9556          tptDelta = cell->cpuOvrLdCntrl.tgtUlTpt - cell->measurements.ulTpt;
9557          /* Upto 1% drift in measured vs target tpt is ignored */
9558          if (((tptDelta*1000)/cell->cpuOvrLdCntrl.tgtUlTpt) > 10)
9559          {
9560             cell->thresholds.maxUlItbs = RGSCH_MIN((cell->thresholds.maxUlItbs+1), RG_SCH_UL_MAX_ITBS);
9561          }
9562       }
9563 #ifdef CPU_OL_DBG_PRINTS
9564       DU_LOG("\nDEBUG  -->  SCH :  UL CPU OL ADJ = %lu, %lu, %d\n", cell->measurements.ulTpt, cell->cpuOvrLdCntrl.tgtUlTpt, 
9565             cell->thresholds.maxUlItbs);
9566 #endif
9567    }
9568
9569    return;
9570 }
9571 /**
9572  * @brief Handler for the num UE per TTI based CPU OvrLd instr updating
9573  *
9574  * @details
9575  *
9576  *     Function : rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr
9577  *
9578  *     Processing Steps:
9579  *      - Validate the config params.
9580  *      - Update numUEperTTi CPU OL related information.
9581  *      - If successful, return ROK else RFAILED.
9582  *
9583  *  @param[in]  RgSchCellCb *cell
9584  *  @param[in]  uint8_t          cnrtCpuOvrLdIns 
9585  *  @return     Void
9586  **/
9587 static Void rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(RgSchCellCb *cell,uint8_t crntCpuOvrLdIns)
9588 {
9589    RgSchCpuOvrLdCntrlCb    *cpuInstr = &(cell->cpuOvrLdCntrl);
9590    RgSchCmnCell            *cellSch;
9591    uint8_t                 maxUeNewDlTxPerTti;
9592    uint8_t                 maxUeNewUlTxPerTti;
9593    uint8_t                 tmpslot        = 0;
9594 #ifdef CPU_OL_DBG_PRINTS 
9595    uint8_t                 idx = 0;
9596 #endif
9597    uint8_t                 maxDlDecCnt;
9598    uint8_t                 maxUlDecCnt;
9599
9600    cellSch = RG_SCH_CMN_GET_CELL(cell);
9601
9602    maxUeNewDlTxPerTti = cellSch->dl.maxUeNewTxPerTti; 
9603    maxUeNewUlTxPerTti = cellSch->ul.maxUeNewTxPerTti;
9604   
9605    /* Calculate Maximum Decremen */
9606    maxDlDecCnt =  (10*(maxUeNewDlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
9607    maxUlDecCnt =  (10*(maxUeNewUlTxPerTti - 1))-(10-RGR_MAX_PERC_NUM_UE_PER_TTI_RED);
9608
9609    /* Check for DL CPU Commands */
9610    if ( crntCpuOvrLdIns &  RGR_CPU_OVRLD_DL_DEC_NUM_UE_PER_TTI ) 
9611    {
9612       /* Decrement till 90% of maxUeNewDlTxPerTti */
9613       if ( cpuInstr->dlNxtIndxDecNumUeTti < maxDlDecCnt )
9614       {
9615          tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
9616          cpuInstr->dlNxtIndxDecNumUeTti++;
9617          if ( cpuInstr->maxUeNewTxPerTti[tmpslot] > 1 )
9618          {
9619             cpuInstr->maxUeNewTxPerTti[tmpslot]--;
9620          }
9621          else
9622          {
9623 #ifdef CPU_OL_DBG_PRINTS
9624             DU_LOG("\nERROR  -->  SCH : CPU_OL_TTI__ERROR\n");
9625 #endif
9626             DU_LOG("\nERROR  -->  SCH : Invalid CPU OL");
9627          }
9628       }
9629 #ifdef CPU_OL_DBG_PRINTS
9630      DU_LOG("\nDEBUG  -->  SCH : dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
9631 #endif
9632       DU_LOG("\nDEBUG  -->  SCH : dlNxtIndxDecNumUeTti = %d",
9633          cpuInstr->dlNxtIndxDecNumUeTti);
9634    }
9635    else if ( crntCpuOvrLdIns &  RGR_CPU_OVRLD_DL_INC_NUM_UE_PER_TTI )
9636    {
9637       if ( cpuInstr->dlNxtIndxDecNumUeTti >  0) 
9638       {
9639          cpuInstr->dlNxtIndxDecNumUeTti--;
9640          tmpslot = (cpuInstr->dlNxtIndxDecNumUeTti) % 10;
9641          if ( cpuInstr->maxUeNewTxPerTti[tmpslot] < maxUeNewDlTxPerTti )
9642          {
9643             cpuInstr->maxUeNewTxPerTti[tmpslot]++;
9644          }
9645          else
9646          {
9647 #ifdef CPU_OL_DBG_PRINTS
9648              DU_LOG("\nERROR  -->  SCH : CPU_OL_TTI__ERROR\n");
9649 #endif
9650              DU_LOG("\nERROR  -->  SCH : Invalid CPU OL");
9651          }
9652       }
9653 #ifdef CPU_OL_DBG_PRINTS
9654       DU_LOG("\nDEBUG  -->  SCH : dlNxtIndxDecNumUeTti = %d\n", cpuInstr->dlNxtIndxDecNumUeTti);
9655 #endif
9656       DU_LOG("\nERROR  -->  SCH : dlNxtIndxDecNumUeTti = %d",
9657          cpuInstr->dlNxtIndxDecNumUeTti);
9658    }
9659    /* Check for UL CPU commands */
9660    if ( crntCpuOvrLdIns &  RGR_CPU_OVRLD_UL_DEC_NUM_UE_PER_TTI )
9661    {
9662       /* Decrement till 90% of maxUeNewDlTxPerTti */
9663       if ( cpuInstr->ulNxtIndxDecNumUeTti < maxUlDecCnt )
9664       {
9665          tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
9666          cpuInstr->ulNxtIndxDecNumUeTti++;
9667          if ( cpuInstr->maxUeNewRxPerTti[tmpslot] > 1 )
9668          {
9669             cpuInstr->maxUeNewRxPerTti[tmpslot]--;
9670          }
9671          else
9672          {
9673 #ifdef CPU_OL_DBG_PRINTS
9674             DU_LOG("\nERROR  -->  SCH : CPU_OL_TTI__ERROR\n");
9675 #endif
9676             DU_LOG("\nERROR  -->  SCH : Invalid CPU OL");
9677          }
9678       }
9679 #ifdef CPU_OL_DBG_PRINTS
9680       DU_LOG("\nDEBUG  -->  SCH : ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
9681 #endif
9682       DU_LOG("\nDEBUG  -->  SCH : dlNxtIndxDecNumUeTti = %d",
9683          cpuInstr->dlNxtIndxDecNumUeTti);
9684    }
9685    else if ( crntCpuOvrLdIns &  RGR_CPU_OVRLD_UL_INC_NUM_UE_PER_TTI )
9686    {
9687       if ( cpuInstr->ulNxtIndxDecNumUeTti >  0) 
9688       {
9689          cpuInstr->ulNxtIndxDecNumUeTti--;
9690          tmpslot = (cpuInstr->ulNxtIndxDecNumUeTti) % 10;
9691          if ( cpuInstr->maxUeNewRxPerTti[tmpslot] < maxUeNewUlTxPerTti )
9692          {
9693             cpuInstr->maxUeNewRxPerTti[tmpslot]++;
9694          }
9695          else
9696          {
9697 #ifdef CPU_OL_DBG_PRINTS
9698             DU_LOG("\nERROR  -->  SCH : CPU_OL_TTI__ERROR\n");
9699 #endif
9700             DU_LOG("\nERROR  -->  SCH : Invalid CPU OL");
9701          }
9702       }
9703 #ifdef CPU_OL_DBG_PRINTS
9704       DU_LOG("\nDEBUG  -->  SCH : ulNxtIndxDecNumUeTti = %d\n", cpuInstr->ulNxtIndxDecNumUeTti);
9705 #endif
9706       DU_LOG("\nDEBUG  -->  SCH : dlNxtIndxDecNumUeTti = %d",
9707          cpuInstr->dlNxtIndxDecNumUeTti);
9708    }
9709 #ifdef CPU_OL_DBG_PRINTS 
9710  /* TODO: Debug Information - Shall be moved under CPU_OL_DBG_PRINTS */
9711    DU_LOG("\nDEBUG  -->  SCH : maxUeNewDlTxPerTti = %d, maxUeNewUlTxPerTti = %d\n", maxUeNewDlTxPerTti, maxUeNewUlTxPerTti);
9712    DU_LOG("\nINFO  -->  SCH : DL Sf numUePerTti:");
9713    for ( idx = 0; idx < 10 ; idx ++ )
9714    {
9715       DU_LOG("  %d", cpuInstr->maxUeNewTxPerTti[idx]);  
9716    }
9717    DU_LOG("\nINFO  -->  SCH : UL Sf numUePerTti:");
9718    for ( idx = 0; idx < 10 ; idx ++ )
9719    {
9720       DU_LOG("  %d", cpuInstr->maxUeNewRxPerTti[idx]);  
9721    }
9722    DU_LOG("\n");
9723 #endif
9724
9725    return;
9726 } /* rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr */
9727
9728 /**
9729  * @brief Handler for the CPU OvrLd related cell Recfg.
9730  *
9731  * @details
9732  *
9733  *     Function : rgSCHUtlResetCpuOvrLdState
9734  *
9735  *     Processing Steps:
9736  *      - Validate the config params.
9737  *      - Update CPU OL related state information.
9738  *      - If successful, return ROK else RFAILED.
9739  *
9740  *  @param[in]  RgSchCellCb *cell
9741  *  @param[in]  uint8_t          cnrtCpuOvrLdIns 
9742  *  @return  S16
9743  *      -# ROK
9744  *      -# RFAILED
9745  **/
9746 S16 rgSCHUtlResetCpuOvrLdState(RgSchCellCb *cell,uint8_t crntCpuOvrLdIns)
9747 {
9748    uint8_t      crntDlCpuOL=0;
9749    uint8_t      crntUlCpuOL=0;
9750    RgSchCmnCell *schCmnCell = (RgSchCmnCell *)(cell->sc.sch);
9751    uint8_t idx;
9752
9753 #ifdef CPU_OL_DBG_PRINTS
9754    DU_LOG("\nDEBUG  -->  SCH : CPU OVR LD Ins Rcvd = %d\n", (int)crntCpuOvrLdIns);
9755 #endif
9756    DU_LOG("\nINFO  -->  SCH : CPU OVR LD Ins Rcvd");
9757
9758    if ( RGR_CPU_OVRLD_RESET == crntCpuOvrLdIns )
9759    {
9760       /* The CPU OL instruction received with RESET (0), hence reset it */
9761 #ifdef CPU_OL_DBG_PRINTS
9762       DU_LOG("\nDEBUG  -->  SCH : rgSCHUtlResetCpuOvrLdState: RESET CPU OL instr\n");
9763 #endif
9764       DU_LOG("\nINFO  -->  SCH : RESET CPU OVR LD");
9765       cell->cpuOvrLdCntrl.cpuOvrLdIns = 0;
9766       /* Reset the max UL and DL itbs to 26 */
9767       cell->thresholds.maxUlItbs = RG_SCH_UL_MAX_ITBS;
9768       cell->thresholds.maxDlItbs = RG_SCH_DL_MAX_ITBS;
9769       /* Reset the num UE per TTI intructions */
9770       cell->cpuOvrLdCntrl.dlNxtIndxDecNumUeTti = 0;
9771       cell->cpuOvrLdCntrl.ulNxtIndxDecNumUeTti = 0;
9772       for ( idx = 0; idx < 10; idx++ )
9773       {
9774          cell->cpuOvrLdCntrl.maxUeNewTxPerTti[idx] = 
9775             schCmnCell->dl.maxUeNewTxPerTti;
9776          cell->cpuOvrLdCntrl.maxUeNewRxPerTti[idx] = 
9777             schCmnCell->ul.maxUeNewTxPerTti;
9778       }
9779
9780       return ROK;
9781    }
9782    /* Check and Update numUEPer TTI based CPU overload instruction before
9783     * going for TP based CPU OL  
9784     * TTI based intrcuctions shall be > 0xF */
9785    if ( crntCpuOvrLdIns >  0xF )  
9786    {
9787       rgSCHUtlChkAndUpdNumUePerTtiCpuOvInstr(cell, crntCpuOvrLdIns);
9788       /* If need to have both TP and numUePerTti instrcution together in
9789        * one command then dont return from here */
9790       return ROK;
9791    }
9792
9793    crntDlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_UP) +\
9794                  (crntCpuOvrLdIns & RGR_CPU_OVRLD_DL_TPT_DOWN);
9795    if ((crntDlCpuOL) && (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_UP) && 
9796        (crntDlCpuOL != RGR_CPU_OVRLD_DL_TPT_DOWN))
9797    {
9798       /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
9799       return RFAILED;
9800    }
9801    crntUlCpuOL = (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_UP) +\
9802                  (crntCpuOvrLdIns & RGR_CPU_OVRLD_UL_TPT_DOWN);
9803    if ((crntUlCpuOL) && (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_UP) && 
9804        (crntUlCpuOL != RGR_CPU_OVRLD_UL_TPT_DOWN))
9805    {
9806       /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
9807       return RFAILED;
9808    }
9809    if ((crntDlCpuOL == 0) && (crntUlCpuOL == 0))
9810    {
9811       /* Cfg validation failed. Invalid Command. Either UP/DOWN is allowed */
9812       return RFAILED;
9813    }
9814
9815    cell->cpuOvrLdCntrl.cpuOvrLdIns = crntCpuOvrLdIns;
9816
9817    if (crntUlCpuOL)
9818    {
9819       if (crntUlCpuOL == RGR_CPU_OVRLD_UL_TPT_DOWN)
9820       {
9821          cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt - \
9822             (cell->measurements.ulTpt * 3 )/100;
9823       }
9824       else
9825       {
9826          cell->cpuOvrLdCntrl.tgtUlTpt = cell->measurements.ulTpt + \
9827             (cell->measurements.ulTpt * 2 )/100;
9828       }
9829       DU_LOG("\nDEBUG  -->  SCH : CPU OVR LD UL Reset to "
9830             "%d, %u, %u", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,cell->measurements.ulTpt);
9831 #ifdef CPU_OL_DBG_PRINTS
9832       DU_LOG("\nDEBUG  -->  SCH : CPU OVR LD UL Reset to= %d, %u, %u\n", (int)crntUlCpuOL, cell->cpuOvrLdCntrl.tgtUlTpt,
9833                               cell->measurements.ulTpt);
9834 #endif
9835    }
9836
9837    if (crntDlCpuOL)
9838    {
9839       if (crntDlCpuOL == RGR_CPU_OVRLD_DL_TPT_DOWN)
9840       {
9841          cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt - \
9842                                         (cell->measurements.dlTpt * 1 )/100;
9843       }
9844       else
9845       {
9846          cell->cpuOvrLdCntrl.tgtDlTpt = cell->measurements.dlTpt + \
9847             (cell->measurements.dlTpt * 1 )/100;
9848       }
9849       DU_LOG("\nDEBUG  -->  SCH : CPU OVR LD DL Reset to "
9850             "%d, %u, %u", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,cell->measurements.dlTpt);
9851
9852 #ifdef CPU_OL_DBG_PRINTS
9853       DU_LOG("\nDEBUG  -->  SCH :  CPU OVR LD DL Reset to= %d, %lu, %lu\n", (int)crntDlCpuOL, cell->cpuOvrLdCntrl.tgtDlTpt,
9854                               cell->measurements.dlTpt);
9855 #endif
9856    }
9857    rgSCHUtlCpuOvrLdAdjItbsCap(cell);
9858    return ROK;
9859 }
9860 #ifdef EMTC_ENABLE
9861 S16 rgSCHUtlAddToResLst
9862 (
9863  CmLListCp   *cp,  
9864  RgSchIotRes *iotRes
9865  )
9866 {
9867    cmLListAdd2Tail(cp, &iotRes->resLnk);
9868    iotRes->resLnk.node = (PTR)iotRes;
9869    return ROK;
9870 }
9871 S16 rgSCHUtlDelFrmResLst
9872 (
9873 RgSchUeCb *ue,
9874 RgSchIotRes *iotRes
9875 )
9876 {
9877    CmLListCp  *cp = NULLP;
9878    RgSchEmtcUeInfo *emtcUe = NULLP;
9879    emtcUe = RG_GET_EMTC_UE_CB(ue);
9880    if(iotRes->resType == RG_SCH_EMTC_PUCCH_RES)
9881    {
9882       cp = &emtcUe->ulResLst;
9883    }else if(iotRes->resType == RG_SCH_EMTC_PDSCH_RES)
9884    {
9885       cp = &emtcUe->dlResLst;
9886    }else
9887    {
9888       DU_LOG("\nINFO  -->  SCH : *****restype mismatch");
9889    }
9890    if(cp != NULLP )
9891    { 
9892       if(cp->count == 0)
9893       {
9894          DU_LOG("\nINFO  -->  SCH : ****error count*****\n");
9895          return ROK;
9896       }
9897    }
9898    cmLListDelFrm(cp, &iotRes->resLnk);
9899    iotRes->resLnk.node = NULLP;
9900    return ROK;
9901 }
9902 #endif
9903 /**********************************************************************
9904
9905          End of file
9906 **********************************************************************/