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