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