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